SOLR-10912: Add scripts for automatic patch validation

This commit is contained in:
Steve Rowe 2018-03-15 12:31:45 -04:00
parent b896fe68a7
commit 12372530a8
6 changed files with 594 additions and 9 deletions

View File

@ -113,7 +113,7 @@
</subant> </subant>
</target> </target>
<target name="validate" description="Validate dependencies, licenses, etc." depends="-validate-source-patterns,resolve-groovy,rat-sources-typedef,-install-forbidden-apis"> <target name="validate" description="Validate dependencies, licenses, etc." depends="validate-source-patterns,resolve-groovy,rat-sources-typedef,-install-forbidden-apis">
<subant target="validate" inheritall="false" failonerror="true"> <subant target="validate" inheritall="false" failonerror="true">
<fileset dir="lucene" includes="build.xml" /> <fileset dir="lucene" includes="build.xml" />
<fileset dir="solr" includes="build.xml" /> <fileset dir="solr" includes="build.xml" />
@ -124,7 +124,7 @@
</subant> </subant>
</target> </target>
<target name="-validate-source-patterns" unless="disable.source-patterns" depends="resolve-groovy,rat-sources-typedef"> <target name="validate-source-patterns" unless="disable.source-patterns" depends="resolve-groovy,rat-sources-typedef">
<groovy taskname="source-patterns" classpathref="rat.classpath" src="${common.dir}/tools/src/groovy/check-source-patterns.groovy"/> <groovy taskname="source-patterns" classpathref="rat.classpath" src="${common.dir}/tools/src/groovy/check-source-patterns.groovy"/>
</target> </target>

View File

@ -13,3 +13,4 @@ Description of dev-tools/ contents:
./maven/ -- Mavenizes the Lucene/Solr packages ./maven/ -- Mavenizes the Lucene/Solr packages
./netbeans/ -- Used to generate project descriptors for the Netbeans IDE. ./netbeans/ -- Used to generate project descriptors for the Netbeans IDE.
./scripts/ -- Odds and ends for building releases, etc. ./scripts/ -- Odds and ends for building releases, etc.
./test-patch/ -- Scripts for automatically validating patches

View File

@ -0,0 +1,90 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ----------------------------------------------------------------------------------
#
# This script is a copy of the one used by ASF Jenkins's PreCommit-LUCENE-Build job.
#
# See the script "test-patch.sh" in this directory for the script to use for
# local manual patch validation.
#
# For other examples of scripts used to invoke Yetus, see the configuration on the
# PreCommit jobs on ASF Jenkins: https://builds.apache.org/view/PreCommit+Builds/
#
# ------------>8-------------------------->8-------------------------->8------------
#!/usr/bin/env bash
# This is a modified copy of the script from Jenkins project "PreCommit-HADOOP-Build"
YETUSDIR=${WORKSPACE}/yetus
TESTPATCHBIN=${YETUSDIR}/precommit/test-patch.sh
ARTIFACTS=${WORKSPACE}/out
BASEDIR=${WORKSPACE}/sourcedir
rm -rf "${ARTIFACTS}"
mkdir -p "${ARTIFACTS}"
if [[ -d /sys/fs/cgroup/pids/user.slice ]]; then
pids=$(cat /sys/fs/cgroup/pids/user.slice/user-910.slice/pids.max)
if [[ ${pids} -gt 13000 ]]; then
echo "passed: ${pids}"
PIDMAX=10000
else
echo "failed: ${pids}"
PIDMAX=5500
fi
else
systemctl status $$ 2>/dev/null
echo "passed? no limit on trusty?"
PIDMAX=10000
fi
# One-time operation: download and expand Yetus source release
# TODO: when upgrading the Yetus release, remove the old tarball
YETUS_RELEASE=0.7.0
YETUS_TARBALL="yetus-${YETUS_RELEASE}.tar.gz"
if [[ ! -f "${YETUS_TARBALL}" || ! -d "$YETUSDIR}}" ]]; then
echo "Downloading Yetus ${YETUS_RELEASE}"
curl -L "https://api.github.com/repos/apache/yetus/tarball/rel/${YETUS_RELEASE}" -o "${YETUS_TARBALL}"
if [[ -d "${YETUSDIR}" ]]; then
rm -rf "${YETUSDIR}"
mkdir -p "${YETUSDIR}"
fi
gunzip -c "${YETUS_TARBALL}" | tar xpf - -C "${YETUSDIR}" --strip-components 1
fi
YETUS_ARGS+=("--project=LUCENE")
YETUS_ARGS+=("--basedir=${BASEDIR}")
YETUS_ARGS+=("--patch-dir=${ARTIFACTS}")
YETUS_ARGS+=("--personality=${BASEDIR}/dev-tools/test-patch/lucene-solr-yetus-personality.sh")
YETUS_ARGS+=("--jira-user=lucenesolrqa")
YETUS_ARGS+=("--jira-password=$JIRA_PASSWORD")
YETUS_ARGS+=("--brief-report-file=${ARTIFACTS}/email-report.txt")
YETUS_ARGS+=("--console-report-file=${ARTIFACTS}/console-report.txt")
YETUS_ARGS+=("--html-report-file=${ARTIFACTS}/console-report.html")
YETUS_ARGS+=("--proclimit=${PIDMAX}")
YETUS_ARGS+=("--console-urls")
YETUS_ARGS+=("--debug")
YETUS_ARGS+=("--skip-dirs=dev-tools")
YETUS_ARGS+=("--bugcomments=jira")
YETUS_ARGS+=("--resetrepo")
YETUS_ARGS+=("--run-tests")
YETUS_ARGS+=("--contrib-guide=https://wiki.apache.org/lucene-java/HowToContribute#Contributing_your_work")
YETUS_ARGS+=("--jenkins")
YETUS_ARGS+=("LUCENE-${ISSUE_NUM}")
/bin/bash ${TESTPATCHBIN} "${YETUS_ARGS[@]}"

View File

@ -0,0 +1,399 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This is a Yetus precommit "personality" (aka customized configuration) for Lucene/Solr.
#
# See the Yetus precommit documentation at https://yetus.apache.org/documentation/0.7.0/
# and especially https://yetus.apache.org/documentation/0.7.0/precommit-advanced/.
# See also the Yetus source code for other projects' personality examples at
# https://git-wip-us.apache.org/repos/asf?p=yetus.git;f=precommit/personality;a=tree;hb=HEAD
#
# To add a new validation method (aka "plugin"):
# 1) Add its name to the PLUGIN_LIST below
# 2) Invoke "add_test_type" with it below
# 3) Add a "<plugin>_filefilter" function to decide whether the plugin needs to be run based on changed files
# 4) Add a "<plugin>_rebuild" function to call out to ant to perform the validation method.
# See examples of the above-described function types ^^ below.
PLUGIN_LIST="ant,testoutput,jira,compile,javac,junit,unit,test4tests,checkluceneversion"
PLUGIN_LIST+=",ratsources,checkforbiddenapis,checklicenses,validatesourcepatterns,validaterefguide"
personality_plugins "${PLUGIN_LIST}"
add_test_type "checkluceneversion"
add_test_type "ratsources"
add_test_type "checkforbiddenapis"
add_test_type "checklicenses"
add_test_type "validatesourcepatterns"
add_test_type "validaterefguide"
add_test_format "testoutput"
## @description Globals specific to this personality
## @audience private
## @stability evolving
function personality_globals
{
#shellcheck disable=SC2034
PATCH_BRANCH_DEFAULT=master
#shellcheck disable=SC2034
JIRA_ISSUE_RE='^(LUCENE|SOLR)-[0-9]+$'
#shellcheck disable=SC2034
JIRA_STATUS_RE='Patch Available'
#shellcheck disable=SC2034
GITHUB_REPO="apache/lucene-solr"
#shellcheck disable=SC2034
BUILDTOOL=ant
}
## @description Queue up modules for this personality
## @audience private
## @stability evolving
## @param repostatus
## @param testtype
function personality_modules
{
local repostatus=$1
local testtype=$2
local module
local extra
local moduleType="submodules"
yetus_debug "Personality (lucene-solr): ${repostatus} ${testtype}"
clear_personality_queue
case ${testtype} in
clean|distclean|validatesourcepatterns)
moduleType="top"
;;
checkluceneversion)
moduleType="solr"
;;
ratsources)
moduleType="submodules"
;;
checkforbiddenapis)
moduleType="both"
;;
checklicenses)
moduleType="mains"
;;
validaterefguide)
moduleType="solr-ref-guide"
;;
compile)
moduleType="submodules"
extra="compile-test"
;;
junit|unit)
moduleType="submodules"
extra="test"
;;
*)
;;
esac
case ${moduleType} in
submodules)
for module in "${CHANGED_MODULES[@]}"; do
if [[ ! "$module" =~ ^lucene/(licenses|site) ]]; then # blacklist lucene/ dirs that aren't modules
if [[ "$module" =~ ^(lucene/(analysis/[^/]+|[^/]+)) ]]; then
lucene_module=${BASH_REMATCH[0]}
personality_enqueue_module "${lucene_module}" "$extra"
elif [[ "$module" =~ ^solr/(core|solrj|test-framework|solr-ref-guide|contrib/[^.]+) ]]; then # whitelist solr/ modules
solr_module=${BASH_REMATCH[0]}
personality_enqueue_module "${solr_module}" "$extra"
fi
fi
done
;;
lucene|solr)
personality_enqueue_module "${moduleType}" "$extra"
;;
top)
personality_enqueue_module . "$extra"
;;
mains)
personality_enqueue_module "lucene" "$extra"
personality_enqueue_module "solr" "$extra"
;;
both) # solr, lucene, or both
# personality_enqueue_module KEEPS duplicates, so de-dupe first
local doSolr=0,doLucene=0
for module in "${CHANGED_MODULES[@]}"; do
if [[ "$module" =~ ^solr/ ]]; then doSolr=1; fi
if [[ "$module" =~ ^lucene/ ]]; then doLucene=1; fi
done
if [[ $doLucene == 1 ]]; then
if [[ $doSolr == 1 ]]; then
personality_enqueue_module . "$extra"
else
personality_enqueue_module "lucene" "$extra"
fi
elif [[ $doSolr == 1 ]]; then
personality_enqueue_module "solr" "$extra"
fi
;;
solr-ref-guide)
for module in "${CHANGED_MODULES[@]}"; do
if [[ "$module" =~ ^solr/solr-ref-guide ]]; then
personality_enqueue_module "solr/solr-ref-guide" "$extra"
fi
done
;;
*)
;;
esac
}
## @description Add tests based upon personality needs
## @audience private
## @stability evolving
## @param filename
function personality_file_tests
{
declare filename=$1
yetus_debug "Using Lucene/Solr-specific personality_file_tests"
if [[ ${filename} =~ build\.xml$ || ${filename} =~ /src/(java|resources|test|test-files|tools) ]]; then
yetus_debug "tests/unit: ${filename}"
add_test compile
add_test javac
add_test unit
fi
}
## @description hook to reroute junit folder to search test results based on the module
## @audience private
## @stability evolving
## @param module
## @param buildlogfile
function testoutput_process_tests
{
# shellcheck disable=SC2034
declare module=$1
declare buildlogfile=$2
if [[ "${module}" =~ ^lucene/analysis/ ]]; then
JUNIT_TEST_OUTPUT_DIR="../../build/${module#*/}"
elif [[ "${module}" =~ ^solr/contrib/extraction ]]; then
JUNIT_TEST_OUTPUT_DIR="../../build/contrib/solr-cell"
elif [[ "${module}" =~ ^solr/contrib/(.*) ]]; then
JUNIT_TEST_OUTPUT_DIR="../../build/contrib/solr-${BASH_REMATCH[1]}"
elif [[ "${module}" =~ ^(lucene|solr)/ ]]; then
JUNIT_TEST_OUTPUT_DIR="../build/${module#*/}"
fi
yetus_debug "Rerouting build dir for junit to ${JUNIT_TEST_OUTPUT_DIR}"
}
## @description checkluceneversion file filter
## @audience private
## @stability evolving
## @param filename
function checkluceneversion_filefilter
{
local filename=$1
if [[ ${filename} =~ ^solr/(example|server/solr/configsets) ]]; then
yetus_debug "tests/checkluceneversion: ${filename}"
add_test checkluceneversion
fi
}
## @description checkluceneversion test
## @audience private
## @stability evolving
## @param repostatus
function checkluceneversion_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "checkluceneversion" "check-example-lucene-match-version" "Check configsets' lucene version"
}
## @description ratsources file filter
## @audience private
## @stability evolving
## @param filename
function ratsources_filefilter
{
local filename=$1
if [[ ${filename} =~ /src/|\.xml$ ]] ; then
yetus_debug "tests/ratsources: ${filename}"
add_test ratsources
fi
}
## @description ratsources test
## @audience private
## @stability evolving
## @param repostatus
function ratsources_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "ratsources" "rat-sources" "Release audit (RAT)"
}
## @description checkforbiddenapis file filter
## @audience private
## @stability evolving
## @param filename
function checkforbiddenapis_filefilter
{
local filename=$1
if [[ ${filename} =~ \.java$ ]] ; then
yetus_debug "tests/checkforbiddenapis: ${filename}"
add_test checkforbiddenapis
fi
}
## @description checkforbiddenapis test
## @audience private
## @stability evolving
## @param repostatus
function checkforbiddenapis_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "checkforbiddenapis" "check-forbidden-apis" "Check forbidden APIs"
}
## @description checklicenses file filter
## @audience private
## @stability evolving
## @param filename
function checklicenses_filefilter
{
local filename=$1
if [[ ${filename} =~ (lucene|solr)/licenses/|lucene/ivy-versions.properties$ ]]; then
yetus_debug "tests/checklicenses: ${filename}"
add_test checklicenses
fi
}
## @description checklicenses test
## @audience private
## @stability evolving
## @param repostatus
function checklicenses_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "checklicenses" "check-licenses" "Check licenses"
}
## @description validaterefguide file filter
## @audience private
## @stability evolving
## @param filename
function validaterefguide_filefilter
{
local filename=$1
if [[ ${filename} =~ solr/solr-ref-guide ]]; then
yetus_debug "tests/validaterefguide: ${filename}"
add_test validaterefguide
fi
}
## @description validaterefguide test
## @audience private
## @stability evolving
## @param repostatus
function validaterefguide_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "validaterefguide" "bare-bones-html-validation" "Validate ref guide"
}
## @description validatesourcepatterns file filter
## @audience private
## @stability evolving
## @param filename
function validatesourcepatterns_filefilter
{
local filename=$1
if [[ ${filename} =~ \.(java|jflex|py|pl|g4|jj|html|js|css|xml|xsl|vm|sh|cmd|bat|policy|properties|mdtext|groovy|template|adoc|json)$ ]]; then
yetus_debug "tests/validatesourcepatterns: ${filename}"
add_test validatesourcepatterns
fi
}
## @description validatesourcepatterns test
## @audience private
## @stability evolving
## @param repostatus
function validatesourcepatterns_rebuild
{
local repostatus=$1
lucene_ant_command ${repostatus} "validatesourcepatterns" "validate-source-patterns" "Validate source patterns"
}
function lucene_ant_command
{
declare repostatus=$1
declare testname=$2
declare antcommand=$3
declare title=$4
declare result=0
declare i=0
declare module
declare fn
declare result
if [[ "${repostatus}" = branch ]]; then
return 0
fi
if ! verify_needed_test ${testname}; then
echo "${BUILDMODEMSG} does not need ${testname} testing."
return 0
fi
big_console_header "${title}"
personality_modules $repostatus $testname
until [[ ${i} -eq ${#MODULE[@]} ]]; do
if [[ ${MODULE_STATUS[${i}]} == -1 ]]; then
((result=result+1))
((i=i+1))
continue
fi
ANT_ARGS=${antcommand}
start_clock
module=${MODULE[$i]}
fn=$(module_file_fragment "${module}")
logfilename="${repostatus}-${antcommand}-${fn}.txt";
logfile="${PATCH_DIR}/${logfilename}"
buildtool_cwd "${i}"
echo_and_redirect "${logfile}" $(ant_executor)
if [[ $? == 0 ]] ; then
module_status ${i} +1 "${logfilename}" "${title}" "${antcommand} passed"
else
module_status ${i} -1 "${logfilename}" "${title}" "${antcommand} failed"
((result=result+1))
fi
((i=i+1))
savestop=$(stop_clock)
MODULE_STATUS_TIMER[${i}]=${savestop}
done
ANT_ARGS=""
if [[ ${result} -gt 0 ]]; then
modules_messages ${repostatus} "${title}" false
return 1
fi
modules_messages ${repostatus} "${title}" true
return 0
}

View File

@ -0,0 +1,91 @@
#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Invoke Yetus locally to validate a patch against Lucene/Solr, and
# (optionally) post a validation report comment on the passed-in JIRA issue
# from which the patch was downloaded.
#
# NB 1: The Lucene/Solr Yetus personality currently performs the equivalent
# of "ant precommit" and "ant test" in modified modules; instead of using
# this script to test your changes, please consider invoking those targets
# directly.
#
# NB 2: The Jenkins job "PreCommit-Admin" automatically detects new patches
# posted to LUCENE and SOLR JIRA issues that are in the "Patch Available"
# state, and then queues the appropriate "PreCommit-LUCENE-Build" or
# "PreCommit-SOLR-Build" job pointing to the JIRA hosting the new patch.
# Those jobs perform the same checks as this script, and like this script,
# will post a comment on the JIRA issue. As a result, manual invocation
# (e.g. via this script) should ordinarily not be necessary.
#
# Environment variable ${YETUS_HOME} must point to the separately installed
# Yetus home directory, e.g. the "rel/0.7.0" tag checked out from a local
# Yetus Git repository.
#
# Environment variable ${PROJECT_DIR} must point to a local Lucene/Solr git
# workspace dir.
#
# The sole cmdline param can be a JIRA issue, a local patch file,
# or a URL to a patch file.
#
# If the cmdline param is a JIRA issue, the patch to download and validate
# will be the most recently uploaded patch on the issue. See the patch
# naming schema that Yetus recognizes:
# https://yetus.apache.org/documentation/in-progress/precommit-patchnames/
#
# If the cmdline param is a JIRA issue and you provide JIRA user/password via
# environment variables ${JIRA_USER} and ${JIRA_PASSWORD}, a patch validation
# report will be posted as a comment on the JIRA issue.
help () {
echo "Usage 1: [ JIRA_USER=xxx JIRA_PASSWORD=yyy ] PROJECT_DIR=/path/to/lucene-solr YETUS_HOME=/path/to/yetus $0 SOLR-12345"
echo "Usage 2: [ JIRA_USER=xxx JIRA_PASSWORD=yyy ] PROJECT_DIR=/path/to/lucene-solr YETUS_HOME=/path/to/yetus $0 LUCENE-12345"
echo "Usage 3: PROJECT_DIR=/path/to/lucene-solr YETUS_HOME=/path/to/yetus $0 ../local.patch"
echo "Usage 4: PROJECT_DIR=/path/to/lucene-solr YETUS_HOME=/path/to/yetus $0 http://example.com/remote.patch"
}
if [[ -z "${PROJECT_DIR}" || -z "${YETUS_HOME}" || -z "${1}" || "${1}" =~ ^-(-?h(elp)?|\?)$ ]] ; then
help
exit 1
fi
PATCH_REF=${1}
TEST_PATCH_BIN="${YETUS_HOME}/precommit/test-patch.sh"
SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd )"
declare -a YETUS_ARGS
if [[ ${PATCH_REF} =~ ^(LUCENE|SOLR)- ]]; then
JIRA_PROJECT=${BASH_REMATCH[0]}
YETUS_ARGS+=("--project=${JIRA_PROJECT}")
if [[ -n "${JIRA_USER}" ]] && [[ -n "${JIRA_PASSWORD}" ]] ; then
YETUS_ARGS+=("--jira-user=${JIRA_USER}")
YETUS_ARGS+=("--jira-password=${JIRA_PASSWORD}")
YETUS_ARGS+=("--bugcomments=jira")
fi
fi
YETUS_ARGS+=("--basedir=${PROJECT_DIR}")
YETUS_ARGS+=("--personality=${SCRIPT_DIR}/lucene-solr-yetus-personality.sh")
YETUS_ARGS+=("--skip-dirs=dev-tools")
YETUS_ARGS+=("--resetrepo")
YETUS_ARGS+=("--run-tests")
YETUS_ARGS+=("--debug")
YETUS_ARGS+=("--robot")
YETUS_ARGS+=("${PATCH_REF}")
/bin/bash ${TEST_PATCH_BIN} "${YETUS_ARGS[@]}"

View File

@ -103,6 +103,10 @@ New Features
deleted documents around for later reuse. See "IW.softUpdateDocument(...)" deleted documents around for later reuse. See "IW.softUpdateDocument(...)"
for reference. (Simon Willnauer) for reference. (Simon Willnauer)
Other
* SOLR-10912: Add automatic patch validation. (Mano Kovacs, Steve Rowe)
======================= Lucene 7.3.0 ======================= ======================= Lucene 7.3.0 =======================
API Changes API Changes