blob: ce74d70fb9cc1382885e78c409fffe478728642d [file] [log] [blame]
#!/usr/bin/env bash
#
# Licensed 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.
if [ "${TESTPATCHDEBUG}" == "true" ] ; then
set -x
fi
BASEDIR=$(pwd)
TESTPATCHDIR=${BASEDIR}/test-patch
TOOLSDIR=${TESTPATCHDIR}/tools
TEMPDIR=${TESTPATCHDIR}/tmp
REPORTDIR=${TESTPATCHDIR}/reports
SUMMARYFILE=${REPORTDIR}/TEST-SUMMARY.jira
SUMMARYFILETXT=${REPORTDIR}/TEST-SUMMARY.txt
SUMMARYFILE_FULL=${REPORTDIR}/TEST-SUMMARY-FULL.jira
SUMMARYFILE_FULL_TXT=${REPORTDIR}/TEST-SUMMARY-FULL.txt
JIRAHOST="https://issues.apache.org"
JIRAURL="${JIRAHOST}/jira"
JIRAURLISSUEPREFIX="${JIRAURL}/browse/"
JIRAUPDATE="false"
JIRAUSER="oozieqa"
JIRAPASSWORD=""
VERBOSEOPTION=""
JIRAISSUE=""
PATCHFILE=""
TASKSTORUN=""
TASKSTOSKIP=""
RESETSCM="false"
DIRTYSCM="false"
STDOUT="/dev/null"
MVNPASSTHRU=""
###############################################################################
gitOrSvn() {
SCM="NONE"
which git &> /dev/null
if [[ $? == 0 ]] ; then
git status &> /dev/null
if [[ $? == 0 ]] ; then
SCM="git"
fi
fi
if [ "${SCM}" == "NONE" ] ; then
which svn &> /dev/null
if [[ $? == 0 ]] ; then
svnOutput=`svn status 2>&1`
if [[ "$svnOutput" != *"is not a working copy" ]] ; then
SCM="svn"
fi
fi
fi
if [ "${SCM}" == "NONE" ] ; then
echo "The current workspace is not under Source Control (GIT or SVN)"
exit 1
fi
}
###############################################################################
prepareSCM() {
gitOrSvn
if [ "${DIRTYSCM}" != "true" ] ; then
if [ "${RESETSCM}" == "true" ] ; then
if [ "${SCM}" == "git" ] ; then
git reset --hard HEAD > /dev/null
git clean -f -d > /dev/null
fi
if [ "${SCM}" == "svn" ] ; then
svn revert -R . > /dev/null
svn status | grep "\?" | awk '{print $2}' | xargs rm -rf
fi
else
echo "It should not happen DIRTYSCM=false & RESETSCM=false"
exit 1
fi
summary_both "Cleaning local ${SCM} workspace"
else
summary_both "WARNING: Running test-patch on a dirty local ${SCM} workspace"
fi
}
###############################################################################
prepareTestPatchDirs() {
mkdir ${TESTPATCHDIR} 2> /dev/null
rm -rf ${REPORTDIR} 2> /dev/null
rm -rf ${TEMPDIR} 2> /dev/null
mkdir ${TOOLSDIR} 2> /dev/null
mkdir ${TEMPDIR} 2> /dev/null
mkdir ${REPORTDIR} 2> /dev/null
if [ ! -e "${TESTPATCHDIR}" ] ; then
echo "Could not create test-patch/ dir"
exit 1
fi
}
###############################################################################
updateJira() {
if [[ "${JIRAUPDATE}" != "" && "${JIRAISSUE}" != "" ]] ; then
if [[ "$JIRAPASSWORD" != "" ]] ; then
echo "Adding comment to JIRA"
# Replace newlines with \n so that summary can be sent via JSON to JIRA
comment=$(awk '{printf "%s\\n", $0}' ${SUMMARYFILE})
curl -u "${JIRAUSER}:${JIRAPASSWORD}"\
-H "Content-type: application/json"\
-H "Accept: application/json"\
-X POST\
--data "{\"body\": \"${comment}\"}"\
${JIRAURL}/rest/api/2/issue/${JIRAISSUE}/comment || echo "Failed to add comment to JIRA"
echo
else
echo "Skipping JIRA update"
echo
fi
fi
}
###############################################################################
cleanupAndExit() {
updateJira
echo "test-patch exit code: $1"
echo
exit $1
}
###############################################################################
printUsage() {
echo "Usage: $0 <OPTIONS>"
echo " (--jira=<JIRA ISSUE> | --patch=<PATCH PATH>)"
echo " (--reset-scm | --dirty-scm)"
echo " [--tasks=<TASK,...>]"
echo " [--skip-tasks=<TASK,...>]"
echo " [--jira-cli=<JIRA CLIENT>]"
echo " [--jira-user=<JIRA USER>]"
echo " [--jira-password=<JIRA PASSWORD>]"
echo " [-D<MVN PROPERTY>...]"
echo " [-P<MVN PROFILE>...]"
echo " [--list-tasks]"
echo " [--verbose]"
echo
}
###############################################################################
parseArgs() {
for i in $*
do
case $i in
--jira=*)
JIRAISSUE=${i#*=}
;;
--patch=*)
PATCHFILE=${i#*=}
;;
--tasks=*)
TASKSTORUN=${i#*=}
;;
--skip-tasks=*)
TASKSTOSKIP=${i#*=}
;;
--list-tasks)
listTasks
cleanupAndExit 0
;;
--jira-cli=*)
JIRACLI=${i#*=}
;;
--jira-user=*)
JIRAUSER=${i#*=}
;;
--jira-password=*)
JIRAPASSWORD=${i#*=}
JIRAUPDATE="true"
;;
-D*)
MVNPASSTHRU="${MVNPASSTHRU} $i"
;;
-P*)
MVNPASSTHRU="${MVNPASSTHRU} $i"
;;
--reset-scm)
RESETSCM="true"
;;
--dirty-scm)
DIRTYSCM="true"
;;
--verbose)
VERBOSEOPTION="--verbose"
STDOUT="/dev/stdout"
;;
*)
echo "Invalid option"
echo
printUsage
exit 1
;;
esac
done
if [[ "${JIRAISSUE}" == "" && "${PATCHFILE}" == "" ]] ; then
echo "Either --jira or --patch option must be specified"
echo
printUsage
exit 1
fi
if [[ "${JIRAISSUE}" != "" && "${PATCHFILE}" != "" ]] ; then
echo "Cannot specify --jira or --patch options together"
echo
printUsage
exit 1
fi
if [[ "${RESETSCM}" == "false" && "${DIRTYSCM}" == "false" ]] ; then
echo "Either --reset-scm or --dirty-scm option must be specified"
echo
printUsage
exit 1
fi
if [[ "${RESETSCM}" == "true" && "${DIRTYSCM}" == "true" ]] ; then
echo "Cannot specify --reset-scm and --dirty-scm options together"
echo
printUsage
exit 1
fi
}
###############################################################################
listTasks() {
echo "Available Tasks:"
echo ""
getAllTasks
for taskFile in ${TASKFILES} ; do
taskName=`bash $taskFile --taskname`
echo " $taskName"
done
echo
}
###############################################################################
downloadPatch () {
PATCHFILE=${TEMPDIR}/test.patch
jiraPage=${TEMPDIR}/jira.txt
curl "${JIRAURLISSUEPREFIX}${JIRAISSUE}" > ${jiraPage}
if [[ `grep -c 'Patch Available' ${jiraPage}` == 0 ]] ; then
echo "$JIRAISSUE is not \"Patch Available\". Exiting."
echo
cleanupAndExit 1
fi
relativePatchURL=`grep -o '"/jira/secure/attachment/[0-9]*/[^"]*' ${jiraPage} \
| grep -v -e 'htm[l]*$' | sort | tail -1 \
| grep -o '/jira/secure/attachment/[0-9]*/[^"]*'`
patchURL="${JIRAHOST}${relativePatchURL}"
patchNum=`echo $patchURL | grep -o '[0-9]*/' | grep -o '[0-9]*'`
curl ${patchURL} > ${PATCHFILE}
if [[ $? != 0 ]] ; then
echo "Could not download patch for ${JIRAISSUE} from ${patchURL}"
echo
cleanupAndExit 1
fi
echo "JIRA ${JIRAISSUE}, patch downloaded at `date` from ${patchURL}"
echo
}
###############################################################################
applyPatch() {
echo "Applying patch" >> $STDOUT
echo "" >> $STDOUT
git apply --check -v -p0 < ${PATCHFILE} | tee ${REPORTDIR}/APPLY-PATCH.txt \
>> $STDOUT
if [[ ${PIPESTATUS[0]} == 0 ]] ; then
git apply -v -p0 < ${PATCHFILE} > ${REPORTDIR}/APPLY-PATCH.txt
if [[ $? != 0 ]] ; then
echo "ODD!, git apply --check -p0 passed, but patch failed to apply to head of branch"
echo
cleanupAndExit 1
fi
else
git apply --check -v < ${PATCHFILE} | tee ${REPORTDIR}/APPLY-PATCH.txt \
>> $STDOUT
if [[ ${PIPESTATUS[0]} == 0 ]] ; then
git apply -v < ${PATCHFILE} > ${REPORTDIR}/APPLY-PATCH.txt
if [[ $? != 0 ]] ; then
echo "ODD!, git apply --check passed, but patch failed to apply to head of branch"
echo
cleanupAndExit 1
fi
else
echo "Patch failed to apply to head of branch"
summary_both "{color:red}-1{color} Patch failed to apply to head of branch"
summary_both ""
summary_both "----------------------------"
echo
cleanupAndExit 1
fi
fi
echo "" >> $STDOUT
echo "Patch applied"
summary_both "{color:green}+1 PATCH_APPLIES{color}"
echo
}
###############################################################################
run() {
task=`bash $1 --taskname`
if [[ "${TASKSTORUN}" == "" || "${TASKSTORUN}" =~ "${task}" ]] ; then
if [[ ! "${TASKSTOSKIP}" =~ "${task}" ]] ; then
echo " Running test-patch task ${task}"
outputFile="`basename $1`-$2.out"
$1 --op=$2 --tempdir=${TEMPDIR} --reportdir=${REPORTDIR} \
--summaryfile=${SUMMARYFILE} --summaryfile-full=${SUMMARYFILE_FULL} --patchfile=${PATCHFILE} ${MVNPASSTHRU} \
${VERBOSEOPTION} | tee ${TEMPDIR}/${outputFile} >> $STDOUT
if [[ $? != 0 ]] ; then
echo " Failure, check for details ${TEMPDIR}/${outputFile}"
echo
cleanupAndExit 1
fi
fi
fi
}
###############################################################################
getAllTasks() {
TASKFILES=`ls -a bin/test\-patch\-[0-9][0-9]\-*`
}
###############################################################################
prePatchRun() {
echo "Pre patch"
for taskFile in ${TASKFILES} ; do
run $taskFile pre
done
echo
}
###############################################################################
postPatchRun() {
echo "Post patch"
for taskFile in ${TASKFILES} ; do
run $taskFile post
done
echo
}
###############################################################################
createReports() {
echo "Reports"
for taskFile in ${TASKFILES} ; do
run $taskFile report
done
echo
}
###############################################################################
summary_both() {
LINE=$1
echo ${LINE} >> ${SUMMARYFILE}
echo ${LINE} >> ${SUMMARYFILE_FULL}
}
###############################################################################
echo
parseArgs "$@"
prepareTestPatchDirs
echo -n "PreCommit-OOZIE-Build started" > ${SUMMARYFILE}
updateJira
echo "" > ${SUMMARYFILE}
echo "" > ${SUMMARYFILE_FULL}
if [ "${PATCHFILE}" == "" ] ; then
echo "Testing JIRA ${JIRAISSUE}"
echo
summary_both "Testing JIRA ${JIRAISSUE}"
summary_both ""
else
if [ ! -e ${PATCHFILE} ] ; then
echo "Patch file does not exist"
cleanupAndExit 1
fi
echo "Testing patch ${PATCHFILE}"
echo
summary_both "Testing patch ${PATCHFILE}"
summary_both ""
fi
prepareSCM
summary_both ""
if [ "${PATCHFILE}" == "" ] ; then
downloadPatch ${JIRAISSUE}
fi
summary_both "----------------------------"
summary_both ""
getAllTasks
prePatchRun
applyPatch
postPatchRun
createReports
summary_both ""
summary_both "----------------------------"
MINUSONES=`grep -c "\}\-1" ${SUMMARYFILE}`
if [[ $MINUSONES == 0 ]]; then
summary_both "{color:green}*+1 Overall result, good!, no -1s*{color}"
else
summary_both "{color:red}*-1 Overall result, please check the reported -1(s)*{color}"
fi
summary_both ""
WARNINGS=`grep -c "\}WARNING" ${SUMMARYFILE}`
if [[ $WARNINGS != 0 ]]; then
summary_both "{color:red}. There is at least one warning, please check{color}"
fi
summary_both ""
if [ ! -z "${JIRAISSUE}" ]; then
summary_both "The full output of the test-patch run is available at"
summary_both ""
summary_both ". ${BUILD_URL}"
summary_both ""
else
echo
echo "Refer to ${REPORTDIR} for detailed test-patch reports"
echo
fi
cat ${SUMMARYFILE} | sed -e 's/{color}//' -e 's/{color:green}//' -e 's/{color:red}//' -e 's/{color:orange}//' -e 's/^\.//' -e 's/^\*//' -e 's/\*$//' > ${SUMMARYFILETXT}
cat ${SUMMARYFILETXT}
cat ${SUMMARYFILE_FULL} | sed -e 's/{color}//' -e 's/{color:green}//' -e 's/{color:red}//' -e 's/{color:orange}//' -e 's/^\.//' -e 's/^\*//' -e 's/\*$//' > ${SUMMARYFILE_FULL_TXT}
grep "^+1 Overall result" ${SUMMARYFILETXT} &> /dev/null
grep "^+1 Overall result" ${SUMMARYFILE_FULL_TXT} &> /dev/null
cleanupAndExit "$?"