test-patch.sh 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. #!/usr/bin/env bash
  2. # Licensed under the Apache License, Version 2.0 (the "License");
  3. # you may not use this file except in compliance with the License.
  4. # You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software
  9. # distributed under the License is distributed on an "AS IS" BASIS,
  10. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. # See the License for the specific language governing permissions and
  12. # limitations under the License.
  13. #set -x
  14. ### Setup some variables.
  15. ### BUILD_URL is set by Hudson if it is run by patch process
  16. ### Read variables from properties file
  17. bindir=$(dirname $0)
  18. # Defaults
  19. if [ -z "$MAVEN_HOME" ]; then
  20. MVN=mvn
  21. else
  22. MVN=$MAVEN_HOME/bin/mvn
  23. fi
  24. PROJECT_NAME=Hadoop
  25. JENKINS=false
  26. PATCH_DIR=/tmp
  27. SUPPORT_DIR=/tmp
  28. BASEDIR=$(pwd)
  29. BUILD_NATIVE=true
  30. PS=${PS:-ps}
  31. AWK=${AWK:-awk}
  32. WGET=${WGET:-wget}
  33. GIT=${GIT:-git}
  34. GREP=${GREP:-grep}
  35. PATCH=${PATCH:-patch}
  36. DIFF=${DIFF:-diff}
  37. JIRACLI=${JIRA:-jira}
  38. FINDBUGS_HOME=${FINDBUGS_HOME}
  39. FORREST_HOME=${FORREST_HOME}
  40. ECLIPSE_HOME=${ECLIPSE_HOME}
  41. ###############################################################################
  42. printUsage() {
  43. echo "Usage: $0 [options] patch-file | defect-number"
  44. echo
  45. echo "Where:"
  46. echo " patch-file is a local patch file containing the changes to test"
  47. echo " defect-number is a JIRA defect number (e.g. 'HADOOP-1234') to test (Jenkins only)"
  48. echo
  49. echo "Options:"
  50. echo "--patch-dir=<dir> The directory for working and output files (default '/tmp')"
  51. echo "--basedir=<dir> The directory to apply the patch to (default current directory)"
  52. echo "--mvn-cmd=<cmd> The 'mvn' command to use (default \$MAVEN_HOME/bin/mvn, or 'mvn')"
  53. echo "--ps-cmd=<cmd> The 'ps' command to use (default 'ps')"
  54. echo "--awk-cmd=<cmd> The 'awk' command to use (default 'awk')"
  55. echo "--git-cmd=<cmd> The 'git' command to use (default 'git')"
  56. echo "--grep-cmd=<cmd> The 'grep' command to use (default 'grep')"
  57. echo "--patch-cmd=<cmd> The 'patch' command to use (default 'patch')"
  58. echo "--diff-cmd=<cmd> The 'diff' command to use (default 'diff')"
  59. echo "--findbugs-home=<path> Findbugs home directory (default FINDBUGS_HOME environment variable)"
  60. echo "--forrest-home=<path> Forrest home directory (default FORREST_HOME environment variable)"
  61. echo "--dirty-workspace Allow the local git workspace to have uncommitted changes"
  62. echo "--run-tests Run all tests below the base directory"
  63. echo "--build-native=<bool> If true, then build native components (default 'true')"
  64. echo
  65. echo "Jenkins-only options:"
  66. echo "--jenkins Run by Jenkins (runs tests and posts results to JIRA)"
  67. echo "--support-dir=<dir> The directory to find support files in"
  68. echo "--wget-cmd=<cmd> The 'wget' command to use (default 'wget')"
  69. echo "--jira-cmd=<cmd> The 'jira' command to use (default 'jira')"
  70. echo "--jira-password=<pw> The password for the 'jira' command"
  71. echo "--eclipse-home=<path> Eclipse home directory (default ECLIPSE_HOME environment variable)"
  72. }
  73. ###############################################################################
  74. parseArgs() {
  75. for i in $*
  76. do
  77. case $i in
  78. --jenkins)
  79. JENKINS=true
  80. ;;
  81. --patch-dir=*)
  82. PATCH_DIR=${i#*=}
  83. ;;
  84. --support-dir=*)
  85. SUPPORT_DIR=${i#*=}
  86. ;;
  87. --basedir=*)
  88. BASEDIR=${i#*=}
  89. ;;
  90. --mvn-cmd=*)
  91. MVN=${i#*=}
  92. ;;
  93. --ps-cmd=*)
  94. PS=${i#*=}
  95. ;;
  96. --awk-cmd=*)
  97. AWK=${i#*=}
  98. ;;
  99. --wget-cmd=*)
  100. WGET=${i#*=}
  101. ;;
  102. --git-cmd=*)
  103. GIT=${i#*=}
  104. ;;
  105. --grep-cmd=*)
  106. GREP=${i#*=}
  107. ;;
  108. --patch-cmd=*)
  109. PATCH=${i#*=}
  110. ;;
  111. --diff-cmd=*)
  112. DIFF=${i#*=}
  113. ;;
  114. --jira-cmd=*)
  115. JIRACLI=${i#*=}
  116. ;;
  117. --jira-password=*)
  118. JIRA_PASSWD=${i#*=}
  119. ;;
  120. --findbugs-home=*)
  121. FINDBUGS_HOME=${i#*=}
  122. ;;
  123. --forrest-home=*)
  124. FORREST_HOME=${i#*=}
  125. ;;
  126. --eclipse-home=*)
  127. ECLIPSE_HOME=${i#*=}
  128. ;;
  129. --dirty-workspace)
  130. DIRTY_WORKSPACE=true
  131. ;;
  132. --run-tests)
  133. RUN_TESTS=true
  134. ;;
  135. --build-native=*)
  136. BUILD_NATIVE=${i#*=}
  137. ;;
  138. *)
  139. PATCH_OR_DEFECT=$i
  140. ;;
  141. esac
  142. done
  143. if [[ $BUILD_NATIVE == "true" ]] ; then
  144. NATIVE_PROFILE=-Pnative
  145. REQUIRE_TEST_LIB_HADOOP=-Drequire.test.libhadoop
  146. fi
  147. if [ -z "$PATCH_OR_DEFECT" ]; then
  148. printUsage
  149. exit 1
  150. fi
  151. if [[ $JENKINS == "true" ]] ; then
  152. echo "Running in Jenkins mode"
  153. defect=$PATCH_OR_DEFECT
  154. ECLIPSE_PROPERTY="-Declipse.home=$ECLIPSE_HOME"
  155. else
  156. echo "Running in developer mode"
  157. JENKINS=false
  158. ### PATCH_FILE contains the location of the patchfile
  159. PATCH_FILE=$PATCH_OR_DEFECT
  160. if [[ ! -e "$PATCH_FILE" ]] ; then
  161. echo "Unable to locate the patch file $PATCH_FILE"
  162. cleanupAndExit 0
  163. fi
  164. ### Check if $PATCH_DIR exists. If it does not exist, create a new directory
  165. if [[ ! -e "$PATCH_DIR" ]] ; then
  166. mkdir "$PATCH_DIR"
  167. if [[ $? == 0 ]] ; then
  168. echo "$PATCH_DIR has been created"
  169. else
  170. echo "Unable to create $PATCH_DIR"
  171. cleanupAndExit 0
  172. fi
  173. fi
  174. ### Obtain the patch filename to append it to the version number
  175. defect=`basename $PATCH_FILE`
  176. fi
  177. }
  178. ###############################################################################
  179. checkout () {
  180. echo ""
  181. echo ""
  182. echo "======================================================================"
  183. echo "======================================================================"
  184. echo " Testing patch for ${defect}."
  185. echo "======================================================================"
  186. echo "======================================================================"
  187. echo ""
  188. echo ""
  189. ### When run by a developer, if the workspace contains modifications, do not continue
  190. ### unless the --dirty-workspace option was set
  191. status=`$GIT status --porcelain`
  192. if [[ $JENKINS == "false" ]] ; then
  193. if [[ "$status" != "" && -z $DIRTY_WORKSPACE ]] ; then
  194. echo "ERROR: can't run in a workspace that contains the following modifications"
  195. echo "$status"
  196. cleanupAndExit 1
  197. fi
  198. echo
  199. else
  200. cd $BASEDIR
  201. $GIT reset --hard
  202. $GIT clean -xdf
  203. $GIT checkout trunk
  204. $GIT pull --rebase
  205. fi
  206. GIT_REVISION=`git rev-parse --verify --short HEAD`
  207. return $?
  208. }
  209. ###############################################################################
  210. downloadPatch () {
  211. ### Download latest patch file (ignoring .htm and .html) when run from patch process
  212. if [[ $JENKINS == "true" ]] ; then
  213. $WGET -q -O $PATCH_DIR/jira http://issues.apache.org/jira/browse/$defect
  214. if [[ `$GREP -c 'Patch Available' $PATCH_DIR/jira` == 0 ]] ; then
  215. echo "$defect is not \"Patch Available\". Exiting."
  216. cleanupAndExit 0
  217. fi
  218. relativePatchURL=`$GREP -o '"/jira/secure/attachment/[0-9]*/[^"]*' $PATCH_DIR/jira | $GREP -v -e 'htm[l]*$' | sort | tail -1 | $GREP -o '/jira/secure/attachment/[0-9]*/[^"]*'`
  219. patchURL="http://issues.apache.org${relativePatchURL}"
  220. patchNum=`echo $patchURL | $GREP -o '[0-9]*/' | $GREP -o '[0-9]*'`
  221. echo "$defect patch is being downloaded at `date` from"
  222. echo "$patchURL"
  223. $WGET -q -O $PATCH_DIR/patch $patchURL
  224. VERSION=${GIT_REVISION}_${defect}_PATCH-${patchNum}
  225. JIRA_COMMENT="Here are the results of testing the latest attachment
  226. $patchURL
  227. against trunk revision ${GIT_REVISION}."
  228. ### Copy in any supporting files needed by this process
  229. cp -r $SUPPORT_DIR/lib/* ./lib
  230. #PENDING: cp -f $SUPPORT_DIR/etc/checkstyle* ./src/test
  231. ### Copy the patch file to $PATCH_DIR
  232. else
  233. VERSION=PATCH-${defect}
  234. cp $PATCH_FILE $PATCH_DIR/patch
  235. if [[ $? == 0 ]] ; then
  236. echo "Patch file $PATCH_FILE copied to $PATCH_DIR"
  237. else
  238. echo "Could not copy $PATCH_FILE to $PATCH_DIR"
  239. cleanupAndExit 0
  240. fi
  241. fi
  242. }
  243. ###############################################################################
  244. verifyPatch () {
  245. # Before building, check to make sure that the patch is valid
  246. $bindir/smart-apply-patch.sh $PATCH_DIR/patch dryrun
  247. if [[ $? != 0 ]] ; then
  248. echo "PATCH APPLICATION FAILED"
  249. JIRA_COMMENT="$JIRA_COMMENT
  250. {color:red}-1 patch{color}. The patch command could not apply the patch."
  251. return 1
  252. else
  253. return 0
  254. fi
  255. }
  256. ###############################################################################
  257. prebuildWithoutPatch () {
  258. echo ""
  259. echo ""
  260. echo "======================================================================"
  261. echo "======================================================================"
  262. echo " Pre-build trunk to verify trunk stability and javac warnings"
  263. echo "======================================================================"
  264. echo "======================================================================"
  265. echo ""
  266. echo ""
  267. if [[ ! -d hadoop-common-project ]]; then
  268. cd $bindir/..
  269. echo "Compiling $(pwd)"
  270. echo "$MVN clean test -DskipTests > $PATCH_DIR/trunkCompile.txt 2>&1"
  271. $MVN clean test -DskipTests > $PATCH_DIR/trunkCompile.txt 2>&1
  272. if [[ $? != 0 ]] ; then
  273. echo "Top-level trunk compilation is broken?"
  274. JIRA_COMMENT="$JIRA_COMMENT
  275. {color:red}-1 patch{color}. Top-level trunk compilation may be broken."
  276. return 1
  277. fi
  278. cd -
  279. fi
  280. echo "Compiling $(pwd)"
  281. echo "$MVN clean test -DskipTests -D${PROJECT_NAME}PatchProcess -Ptest-patch > $PATCH_DIR/trunkJavacWarnings.txt 2>&1"
  282. $MVN clean test -DskipTests -D${PROJECT_NAME}PatchProcess -Ptest-patch > $PATCH_DIR/trunkJavacWarnings.txt 2>&1
  283. if [[ $? != 0 ]] ; then
  284. echo "Trunk compilation is broken?"
  285. JIRA_COMMENT="$JIRA_COMMENT
  286. {color:red}-1 patch{color}. Trunk compilation may be broken."
  287. return 1
  288. fi
  289. echo "$MVN clean test javadoc:javadoc -DskipTests -Pdocs -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/trunkJavadocWarnings.txt 2>&1"
  290. $MVN clean test javadoc:javadoc -DskipTests -Pdocs -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/trunkJavadocWarnings.txt 2>&1
  291. if [[ $? != 0 ]] ; then
  292. echo "Trunk javadoc compilation is broken?"
  293. JIRA_COMMENT="$JIRA_COMMENT
  294. {color:red}-1 patch{color}. Trunk compilation may be broken."
  295. return 1
  296. fi
  297. return 0
  298. }
  299. ###############################################################################
  300. ### Check for @author tags in the patch
  301. checkAuthor () {
  302. echo ""
  303. echo ""
  304. echo "======================================================================"
  305. echo "======================================================================"
  306. echo " Checking there are no @author tags in the patch."
  307. echo "======================================================================"
  308. echo "======================================================================"
  309. echo ""
  310. echo ""
  311. authorTags=`$GREP -c -i '@author' $PATCH_DIR/patch`
  312. echo "There appear to be $authorTags @author tags in the patch."
  313. if [[ $authorTags != 0 ]] ; then
  314. JIRA_COMMENT="$JIRA_COMMENT
  315. {color:red}-1 @author{color}. The patch appears to contain $authorTags @author tags which the Hadoop community has agreed to not allow in code contributions."
  316. return 1
  317. fi
  318. JIRA_COMMENT="$JIRA_COMMENT
  319. {color:green}+1 @author{color}. The patch does not contain any @author tags."
  320. return 0
  321. }
  322. ###############################################################################
  323. ### Check for tests in the patch
  324. checkTests () {
  325. echo ""
  326. echo ""
  327. echo "======================================================================"
  328. echo "======================================================================"
  329. echo " Checking there are new or changed tests in the patch."
  330. echo "======================================================================"
  331. echo "======================================================================"
  332. echo ""
  333. echo ""
  334. testReferences=`$GREP -c -i -e '^+++.*/test' $PATCH_DIR/patch`
  335. echo "There appear to be $testReferences test files referenced in the patch."
  336. if [[ $testReferences == 0 ]] ; then
  337. if [[ $JENKINS == "true" ]] ; then
  338. patchIsDoc=`$GREP -c -i 'title="documentation' $PATCH_DIR/jira`
  339. if [[ $patchIsDoc != 0 ]] ; then
  340. echo "The patch appears to be a documentation patch that doesn't require tests."
  341. JIRA_COMMENT="$JIRA_COMMENT
  342. {color:green}+0 tests included{color}. The patch appears to be a documentation patch that doesn't require tests."
  343. return 0
  344. fi
  345. fi
  346. JIRA_COMMENT="$JIRA_COMMENT
  347. {color:red}-1 tests included{color}. The patch doesn't appear to include any new or modified tests.
  348. Please justify why no new tests are needed for this patch.
  349. Also please list what manual steps were performed to verify this patch."
  350. return 1
  351. fi
  352. JIRA_COMMENT="$JIRA_COMMENT
  353. {color:green}+1 tests included{color}. The patch appears to include $testReferences new or modified test files."
  354. return 0
  355. }
  356. cleanUpXml () {
  357. cd $BASEDIR/conf
  358. for file in `ls *.xml.template`
  359. do
  360. rm -f `basename $file .template`
  361. done
  362. cd $BASEDIR
  363. }
  364. ###############################################################################
  365. ### Attempt to apply the patch
  366. applyPatch () {
  367. echo ""
  368. echo ""
  369. echo "======================================================================"
  370. echo "======================================================================"
  371. echo " Applying patch."
  372. echo "======================================================================"
  373. echo "======================================================================"
  374. echo ""
  375. echo ""
  376. export PATCH
  377. $bindir/smart-apply-patch.sh $PATCH_DIR/patch
  378. if [[ $? != 0 ]] ; then
  379. echo "PATCH APPLICATION FAILED"
  380. JIRA_COMMENT="$JIRA_COMMENT
  381. {color:red}-1 patch{color}. The patch command could not apply the patch."
  382. return 1
  383. fi
  384. return 0
  385. }
  386. ###############################################################################
  387. calculateJavadocWarnings() {
  388. WARNING_FILE="$1"
  389. RET=$(egrep "^[0-9]+ warnings$" "$WARNING_FILE" | awk '{sum+=$1} END {print sum}')
  390. }
  391. ### Check there are no javadoc warnings
  392. checkJavadocWarnings () {
  393. echo ""
  394. echo ""
  395. echo "======================================================================"
  396. echo "======================================================================"
  397. echo " Determining number of patched javadoc warnings."
  398. echo "======================================================================"
  399. echo "======================================================================"
  400. echo ""
  401. echo ""
  402. echo "$MVN clean test javadoc:javadoc -DskipTests -Pdocs -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1"
  403. if [ -d hadoop-project ]; then
  404. (cd hadoop-project; $MVN install > /dev/null 2>&1)
  405. fi
  406. if [ -d hadoop-common-project/hadoop-annotations ]; then
  407. (cd hadoop-common-project/hadoop-annotations; $MVN install > /dev/null 2>&1)
  408. fi
  409. $MVN clean test javadoc:javadoc -DskipTests -Pdocs -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchJavadocWarnings.txt 2>&1
  410. calculateJavadocWarnings "$PATCH_DIR/trunkJavadocWarnings.txt"
  411. numTrunkJavadocWarnings=$RET
  412. calculateJavadocWarnings "$PATCH_DIR/patchJavadocWarnings.txt"
  413. numPatchJavadocWarnings=$RET
  414. grep -i warning "$PATCH_DIR/trunkJavadocWarnings.txt" > "$PATCH_DIR/trunkJavadocWarningsFiltered.txt"
  415. grep -i warning "$PATCH_DIR/patchJavadocWarnings.txt" > "$PATCH_DIR/patchJavadocWarningsFiltered.txt"
  416. diff -u "$PATCH_DIR/trunkJavadocWarningsFiltered.txt" \
  417. "$PATCH_DIR/patchJavadocWarningsFiltered.txt" > \
  418. "$PATCH_DIR/diffJavadocWarnings.txt"
  419. rm -f "$PATCH_DIR/trunkJavadocWarningsFiltered.txt" "$PATCH_DIR/patchJavadocWarningsFiltered.txt"
  420. echo "There appear to be $numTrunkJavadocWarnings javadoc warnings before the patch and $numPatchJavadocWarnings javadoc warnings after applying the patch."
  421. if [[ $numTrunkJavadocWarnings != "" && $numPatchJavadocWarnings != "" ]] ; then
  422. if [[ $numPatchJavadocWarnings -gt $numTrunkJavadocWarnings ]] ; then
  423. JIRA_COMMENT="$JIRA_COMMENT
  424. {color:red}-1 javadoc{color}. The javadoc tool appears to have generated `expr $(($numPatchJavadocWarnings-$numTrunkJavadocWarnings))` warning messages.
  425. See $BUILD_URL/artifact/patchprocess/diffJavadocWarnings.txt for details."
  426. return 1
  427. fi
  428. fi
  429. JIRA_COMMENT="$JIRA_COMMENT
  430. {color:green}+1 javadoc{color}. There were no new javadoc warning messages."
  431. return 0
  432. }
  433. ###############################################################################
  434. ### Check there are no changes in the number of Javac warnings
  435. checkJavacWarnings () {
  436. echo ""
  437. echo ""
  438. echo "======================================================================"
  439. echo "======================================================================"
  440. echo " Determining number of patched javac warnings."
  441. echo "======================================================================"
  442. echo "======================================================================"
  443. echo ""
  444. echo ""
  445. echo "$MVN clean test -DskipTests -D${PROJECT_NAME}PatchProcess $NATIVE_PROFILE -Ptest-patch > $PATCH_DIR/patchJavacWarnings.txt 2>&1"
  446. $MVN clean test -DskipTests -D${PROJECT_NAME}PatchProcess $NATIVE_PROFILE -Ptest-patch > $PATCH_DIR/patchJavacWarnings.txt 2>&1
  447. if [[ $? != 0 ]] ; then
  448. JIRA_COMMENT="$JIRA_COMMENT
  449. {color:red}-1 javac{color:red}. The patch appears to cause the build to fail."
  450. return 2
  451. fi
  452. ### Compare trunk and patch javac warning numbers
  453. if [[ -f $PATCH_DIR/patchJavacWarnings.txt ]] ; then
  454. $GREP '\[WARNING\]' $PATCH_DIR/trunkJavacWarnings.txt > $PATCH_DIR/filteredTrunkJavacWarnings.txt
  455. $GREP '\[WARNING\]' $PATCH_DIR/patchJavacWarnings.txt > $PATCH_DIR/filteredPatchJavacWarnings.txt
  456. trunkJavacWarnings=`cat $PATCH_DIR/filteredTrunkJavacWarnings.txt | $AWK 'BEGIN {total = 0} {total += 1} END {print total}'`
  457. patchJavacWarnings=`cat $PATCH_DIR/filteredPatchJavacWarnings.txt | $AWK 'BEGIN {total = 0} {total += 1} END {print total}'`
  458. echo "There appear to be $trunkJavacWarnings javac compiler warnings before the patch and $patchJavacWarnings javac compiler warnings after applying the patch."
  459. if [[ $patchJavacWarnings != "" && $trunkJavacWarnings != "" ]] ; then
  460. if [[ $patchJavacWarnings -gt $trunkJavacWarnings ]] ; then
  461. JIRA_COMMENT="$JIRA_COMMENT
  462. {color:red}-1 javac{color}. The applied patch generated $patchJavacWarnings javac compiler warnings (more than the trunk's current $trunkJavacWarnings warnings)."
  463. $DIFF $PATCH_DIR/filteredTrunkJavacWarnings.txt $PATCH_DIR/filteredPatchJavacWarnings.txt > $PATCH_DIR/diffJavacWarnings.txt
  464. JIRA_COMMENT_FOOTER="Javac warnings: $BUILD_URL/artifact/patchprocess/diffJavacWarnings.txt
  465. $JIRA_COMMENT_FOOTER"
  466. return 1
  467. fi
  468. fi
  469. fi
  470. JIRA_COMMENT="$JIRA_COMMENT
  471. {color:green}+1 javac{color}. The applied patch does not increase the total number of javac compiler warnings."
  472. return 0
  473. }
  474. ###############################################################################
  475. ### Check there are no changes in the number of release audit (RAT) warnings
  476. checkReleaseAuditWarnings () {
  477. echo ""
  478. echo ""
  479. echo "======================================================================"
  480. echo "======================================================================"
  481. echo " Determining number of patched release audit warnings."
  482. echo "======================================================================"
  483. echo "======================================================================"
  484. echo ""
  485. echo ""
  486. echo "$MVN apache-rat:check -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchReleaseAuditOutput.txt 2>&1"
  487. $MVN apache-rat:check -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchReleaseAuditOutput.txt 2>&1
  488. find $BASEDIR -name rat.txt | xargs cat > $PATCH_DIR/patchReleaseAuditWarnings.txt
  489. ### Compare trunk and patch release audit warning numbers
  490. if [[ -f $PATCH_DIR/patchReleaseAuditWarnings.txt ]] ; then
  491. patchReleaseAuditWarnings=`$GREP -c '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt`
  492. echo ""
  493. echo ""
  494. echo "There appear to be $patchReleaseAuditWarnings release audit warnings after applying the patch."
  495. if [[ $patchReleaseAuditWarnings != "" ]] ; then
  496. if [[ $patchReleaseAuditWarnings -gt 0 ]] ; then
  497. JIRA_COMMENT="$JIRA_COMMENT
  498. {color:red}-1 release audit{color}. The applied patch generated $patchReleaseAuditWarnings release audit warnings."
  499. $GREP '\!?????' $PATCH_DIR/patchReleaseAuditWarnings.txt > $PATCH_DIR/patchReleaseAuditProblems.txt
  500. echo "Lines that start with ????? in the release audit report indicate files that do not have an Apache license header." >> $PATCH_DIR/patchReleaseAuditProblems.txt
  501. JIRA_COMMENT_FOOTER="Release audit warnings: $BUILD_URL/artifact/patchprocess/patchReleaseAuditProblems.txt
  502. $JIRA_COMMENT_FOOTER"
  503. return 1
  504. fi
  505. fi
  506. fi
  507. JIRA_COMMENT="$JIRA_COMMENT
  508. {color:green}+1 release audit{color}. The applied patch does not increase the total number of release audit warnings."
  509. return 0
  510. }
  511. ###############################################################################
  512. ### Check there are no changes in the number of Checkstyle warnings
  513. checkStyle () {
  514. echo ""
  515. echo ""
  516. echo "======================================================================"
  517. echo "======================================================================"
  518. echo " Determining number of patched checkstyle warnings."
  519. echo "======================================================================"
  520. echo "======================================================================"
  521. echo ""
  522. echo ""
  523. echo "THIS IS NOT IMPLEMENTED YET"
  524. echo ""
  525. echo ""
  526. echo "$MVN test checkstyle:checkstyle -DskipTests -D${PROJECT_NAME}PatchProcess"
  527. $MVN test checkstyle:checkstyle -DskipTests -D${PROJECT_NAME}PatchProcess
  528. JIRA_COMMENT_FOOTER="Checkstyle results: $BUILD_URL/artifact/trunk/build/test/checkstyle-errors.html
  529. $JIRA_COMMENT_FOOTER"
  530. ### TODO: calculate actual patchStyleErrors
  531. # patchStyleErrors=0
  532. # if [[ $patchStyleErrors != 0 ]] ; then
  533. # JIRA_COMMENT="$JIRA_COMMENT
  534. #
  535. # {color:red}-1 checkstyle{color}. The patch generated $patchStyleErrors code style errors."
  536. # return 1
  537. # fi
  538. # JIRA_COMMENT="$JIRA_COMMENT
  539. #
  540. # {color:green}+1 checkstyle{color}. The patch generated 0 code style errors."
  541. return 0
  542. }
  543. ###############################################################################
  544. ### Install the new jars so tests and findbugs can find all of the updated jars
  545. buildAndInstall () {
  546. echo ""
  547. echo ""
  548. echo "======================================================================"
  549. echo "======================================================================"
  550. echo " Installing all of the jars"
  551. echo "======================================================================"
  552. echo "======================================================================"
  553. echo ""
  554. echo ""
  555. echo "$MVN install -Dmaven.javadoc.skip=true -DskipTests -D${PROJECT_NAME}PatchProcess"
  556. $MVN install -Dmaven.javadoc.skip=true -DskipTests -D${PROJECT_NAME}PatchProcess
  557. return $?
  558. }
  559. ###############################################################################
  560. ### Check there are no changes in the number of Findbugs warnings
  561. checkFindbugsWarnings () {
  562. findbugs_version=`${FINDBUGS_HOME}/bin/findbugs -version`
  563. echo ""
  564. echo ""
  565. echo "======================================================================"
  566. echo "======================================================================"
  567. echo " Determining number of patched Findbugs warnings."
  568. echo "======================================================================"
  569. echo "======================================================================"
  570. echo ""
  571. echo ""
  572. modules=$(findModules)
  573. rc=0
  574. for module in $modules;
  575. do
  576. cd $module
  577. echo " Running findbugs in $module"
  578. module_suffix=`basename ${module}`
  579. echo "$MVN clean test findbugs:findbugs -DskipTests -D${PROJECT_NAME}PatchProcess < /dev/null > $PATCH_DIR/patchFindBugsOutput${module_suffix}.txt 2>&1"
  580. $MVN clean test findbugs:findbugs -DskipTests -D${PROJECT_NAME}PatchProcess < /dev/null > $PATCH_DIR/patchFindBugsOutput${module_suffix}.txt 2>&1
  581. (( rc = rc + $? ))
  582. cd -
  583. done
  584. if [ $rc != 0 ] ; then
  585. JIRA_COMMENT="$JIRA_COMMENT
  586. {color:red}-1 findbugs{color}. The patch appears to cause Findbugs (version ${findbugs_version}) to fail."
  587. return 1
  588. fi
  589. findbugsWarnings=0
  590. for file in $(find $BASEDIR -name findbugsXml.xml)
  591. do
  592. relative_file=${file#$BASEDIR/} # strip leading $BASEDIR prefix
  593. if [ ! $relative_file == "target/findbugsXml.xml" ]; then
  594. module_suffix=${relative_file%/target/findbugsXml.xml} # strip trailing path
  595. module_suffix=`basename ${module_suffix}`
  596. fi
  597. cp $file $PATCH_DIR/patchFindbugsWarnings${module_suffix}.xml
  598. $FINDBUGS_HOME/bin/setBugDatabaseInfo -timestamp "01/01/2000" \
  599. $PATCH_DIR/patchFindbugsWarnings${module_suffix}.xml \
  600. $PATCH_DIR/patchFindbugsWarnings${module_suffix}.xml
  601. newFindbugsWarnings=`$FINDBUGS_HOME/bin/filterBugs -first "01/01/2000" $PATCH_DIR/patchFindbugsWarnings${module_suffix}.xml \
  602. $PATCH_DIR/newPatchFindbugsWarnings${module_suffix}.xml | $AWK '{print $1}'`
  603. echo "Found $newFindbugsWarnings Findbugs warnings ($file)"
  604. findbugsWarnings=$((findbugsWarnings+newFindbugsWarnings))
  605. $FINDBUGS_HOME/bin/convertXmlToText -html \
  606. $PATCH_DIR/newPatchFindbugsWarnings${module_suffix}.xml \
  607. $PATCH_DIR/newPatchFindbugsWarnings${module_suffix}.html
  608. if [[ $newFindbugsWarnings > 0 ]] ; then
  609. JIRA_COMMENT_FOOTER="Findbugs warnings: $BUILD_URL/artifact/patchprocess/newPatchFindbugsWarnings${module_suffix}.html
  610. $JIRA_COMMENT_FOOTER"
  611. fi
  612. done
  613. if [[ $findbugsWarnings -gt 0 ]] ; then
  614. JIRA_COMMENT="$JIRA_COMMENT
  615. {color:red}-1 findbugs{color}. The patch appears to introduce $findbugsWarnings new Findbugs (version ${findbugs_version}) warnings."
  616. return 1
  617. fi
  618. JIRA_COMMENT="$JIRA_COMMENT
  619. {color:green}+1 findbugs{color}. The patch does not introduce any new Findbugs (version ${findbugs_version}) warnings."
  620. return 0
  621. }
  622. ###############################################################################
  623. ### Verify eclipse:eclipse works
  624. checkEclipseGeneration () {
  625. echo ""
  626. echo ""
  627. echo "======================================================================"
  628. echo "======================================================================"
  629. echo " Running mvn eclipse:eclipse."
  630. echo "======================================================================"
  631. echo "======================================================================"
  632. echo ""
  633. echo ""
  634. echo "$MVN eclipse:eclipse -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchEclipseOutput.txt 2>&1"
  635. $MVN eclipse:eclipse -D${PROJECT_NAME}PatchProcess > $PATCH_DIR/patchEclipseOutput.txt 2>&1
  636. if [[ $? != 0 ]] ; then
  637. JIRA_COMMENT="$JIRA_COMMENT
  638. {color:red}-1 eclipse:eclipse{color}. The patch failed to build with eclipse:eclipse."
  639. return 1
  640. fi
  641. JIRA_COMMENT="$JIRA_COMMENT
  642. {color:green}+1 eclipse:eclipse{color}. The patch built with eclipse:eclipse."
  643. return 0
  644. }
  645. ###############################################################################
  646. ### Run the tests
  647. runTests () {
  648. echo ""
  649. echo ""
  650. echo "======================================================================"
  651. echo "======================================================================"
  652. echo " Running tests."
  653. echo "======================================================================"
  654. echo "======================================================================"
  655. echo ""
  656. echo ""
  657. failed_tests=""
  658. modules=$(findModules)
  659. #
  660. # If we are building hadoop-hdfs-project, we must build the native component
  661. # of hadoop-common-project first. In order to accomplish this, we move the
  662. # hadoop-hdfs subprojects to the end of the list so that common will come
  663. # first.
  664. #
  665. # Of course, we may not be building hadoop-common at all-- in this case, we
  666. # explicitly insert a mvn compile -Pnative of common, to ensure that the
  667. # native libraries show up where we need them.
  668. #
  669. building_common=0
  670. for module in $modules; do
  671. if [[ $module == hadoop-hdfs-project* ]]; then
  672. hdfs_modules="$hdfs_modules $module"
  673. elif [[ $module == hadoop-common-project* ]]; then
  674. ordered_modules="$ordered_modules $module"
  675. building_common=1
  676. else
  677. ordered_modules="$ordered_modules $module"
  678. fi
  679. done
  680. if [ -n "$hdfs_modules" ]; then
  681. ordered_modules="$ordered_modules $hdfs_modules"
  682. if [[ $building_common -eq 0 ]]; then
  683. echo " Building hadoop-common with -Pnative in order to provide \
  684. libhadoop.so to the hadoop-hdfs unit tests."
  685. echo " $MVN compile $NATIVE_PROFILE -D${PROJECT_NAME}PatchProcess"
  686. if ! $MVN compile $NATIVE_PROFILE -D${PROJECT_NAME}PatchProcess; then
  687. JIRA_COMMENT="$JIRA_COMMENT
  688. {color:red}-1 core tests{color}. Failed to build the native portion \
  689. of hadoop-common prior to running the unit tests in $ordered_modules"
  690. return 1
  691. fi
  692. fi
  693. fi
  694. failed_test_builds=""
  695. test_timeouts=""
  696. for module in $ordered_modules; do
  697. cd $module
  698. module_suffix=`basename ${module}`
  699. test_logfile=$PATCH_DIR/testrun_${module_suffix}.txt
  700. echo " Running tests in $module"
  701. echo " $MVN clean install -fn $NATIVE_PROFILE $REQUIRE_TEST_LIB_HADOOP -D${PROJECT_NAME}PatchProcess"
  702. $MVN clean install -fae $NATIVE_PROFILE $REQUIRE_TEST_LIB_HADOOP -D${PROJECT_NAME}PatchProcess > $test_logfile 2>&1
  703. test_build_result=$?
  704. cat $test_logfile
  705. module_test_timeouts=`$AWK '/^Running / { if (last) { print last } last=$2 } /^Tests run: / { last="" }' $test_logfile`
  706. if [[ -n "$module_test_timeouts" ]] ; then
  707. test_timeouts="$test_timeouts
  708. $module_test_timeouts"
  709. fi
  710. module_failed_tests=`find . -name 'TEST*.xml' | xargs $GREP -l -E "<failure|<error" | sed -e "s|.*target/surefire-reports/TEST-| |g" | sed -e "s|\.xml||g"`
  711. if [[ -n "$module_failed_tests" ]] ; then
  712. failed_tests="${failed_tests}
  713. ${module_failed_tests}"
  714. fi
  715. if [[ $test_build_result != 0 && -z "$module_failed_tests" && -z "$module_test_timeouts" ]] ; then
  716. failed_test_builds="$module $failed_test_builds"
  717. fi
  718. cd -
  719. done
  720. result=0
  721. comment_prefix=" {color:red}-1 core tests{color}."
  722. if [[ -n "$failed_tests" ]] ; then
  723. JIRA_COMMENT="$JIRA_COMMENT
  724. $comment_prefix The patch failed these unit tests in $modules:
  725. $failed_tests"
  726. comment_prefix=" "
  727. result=1
  728. fi
  729. if [[ -n "$test_timeouts" ]] ; then
  730. JIRA_COMMENT="$JIRA_COMMENT
  731. $comment_prefix The following test timeouts occurred in $modules:
  732. $test_timeouts"
  733. comment_prefix=" "
  734. result=1
  735. fi
  736. if [[ -n "$failed_test_builds" ]] ; then
  737. JIRA_COMMENT="$JIRA_COMMENT
  738. $comment_prefix The test build failed in $failed_test_builds"
  739. result=1
  740. fi
  741. if [[ $result == 0 ]] ; then
  742. JIRA_COMMENT="$JIRA_COMMENT
  743. {color:green}+1 core tests{color}. The patch passed unit tests in $modules."
  744. fi
  745. return $result
  746. }
  747. ###############################################################################
  748. # Find the maven module containing the given file.
  749. findModule (){
  750. dir=`dirname $1`
  751. while [ 1 ]
  752. do
  753. if [ -f "$dir/pom.xml" ]
  754. then
  755. echo $dir
  756. return
  757. else
  758. dir=`dirname $dir`
  759. fi
  760. done
  761. }
  762. findModules () {
  763. # Come up with a list of changed files into $TMP
  764. TMP=/tmp/tmp.paths.$$
  765. $GREP '^+++ \|^--- ' $PATCH_DIR/patch | cut -c '5-' | $GREP -v /dev/null | sort | uniq > $TMP
  766. # if all of the lines start with a/ or b/, then this is a git patch that
  767. # was generated without --no-prefix
  768. if ! $GREP -qv '^a/\|^b/' $TMP ; then
  769. sed -i -e 's,^[ab]/,,' $TMP
  770. fi
  771. # Now find all the modules that were changed
  772. TMP_MODULES=/tmp/tmp.modules.$$
  773. for file in $(cut -f 1 $TMP | sort | uniq); do
  774. echo $(findModule $file) >> $TMP_MODULES
  775. done
  776. rm $TMP
  777. # Filter out modules without code
  778. CHANGED_MODULES=""
  779. for module in $(cat $TMP_MODULES | sort | uniq); do
  780. $GREP "<packaging>pom</packaging>" $module/pom.xml > /dev/null
  781. if [ "$?" != 0 ]; then
  782. CHANGED_MODULES="$CHANGED_MODULES $module"
  783. fi
  784. done
  785. rm $TMP_MODULES
  786. echo $CHANGED_MODULES
  787. }
  788. ###############################################################################
  789. ### Run the test-contrib target
  790. runContribTests () {
  791. echo ""
  792. echo ""
  793. echo "======================================================================"
  794. echo "======================================================================"
  795. echo " Running contrib tests."
  796. echo "======================================================================"
  797. echo "======================================================================"
  798. echo ""
  799. echo ""
  800. if [[ `$GREP -c 'test-contrib' build.xml` == 0 ]] ; then
  801. echo "No contrib tests in this project."
  802. return 0
  803. fi
  804. ### Kill any rogue build processes from the last attempt
  805. $PS auxwww | $GREP ${PROJECT_NAME}PatchProcess | $AWK '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
  806. #echo "$ANT_HOME/bin/ant -Dversion="${VERSION}" $ECLIPSE_PROPERTY -DHadoopPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=no test-contrib"
  807. #$ANT_HOME/bin/ant -Dversion="${VERSION}" $ECLIPSE_PROPERTY -DHadoopPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=no test-contrib
  808. echo "NOP"
  809. if [[ $? != 0 ]] ; then
  810. JIRA_COMMENT="$JIRA_COMMENT
  811. {color:red}-1 contrib tests{color}. The patch failed contrib unit tests."
  812. return 1
  813. fi
  814. JIRA_COMMENT="$JIRA_COMMENT
  815. {color:green}+1 contrib tests{color}. The patch passed contrib unit tests."
  816. return 0
  817. }
  818. ###############################################################################
  819. ### Run the inject-system-faults target
  820. checkInjectSystemFaults () {
  821. echo ""
  822. echo ""
  823. echo "======================================================================"
  824. echo "======================================================================"
  825. echo " Checking the integrity of system test framework code."
  826. echo "======================================================================"
  827. echo "======================================================================"
  828. echo ""
  829. echo ""
  830. ### Kill any rogue build processes from the last attempt
  831. $PS auxwww | $GREP ${PROJECT_NAME}PatchProcess | $AWK '{print $2}' | /usr/bin/xargs -t -I {} /bin/kill -9 {} > /dev/null
  832. #echo "$ANT_HOME/bin/ant -Dversion="${VERSION}" -DHadoopPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=no -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME inject-system-faults"
  833. #$ANT_HOME/bin/ant -Dversion="${VERSION}" -DHadoopPatchProcess= -Dtest.junit.output.format=xml -Dtest.output=no -Dcompile.c++=yes -Dforrest.home=$FORREST_HOME inject-system-faults
  834. echo "NOP"
  835. return 0
  836. if [[ $? != 0 ]] ; then
  837. JIRA_COMMENT="$JIRA_COMMENT
  838. {color:red}-1 system test framework{color}. The patch failed system test framework compile."
  839. return 1
  840. fi
  841. JIRA_COMMENT="$JIRA_COMMENT
  842. {color:green}+1 system test framework{color}. The patch passed system test framework compile."
  843. return 0
  844. }
  845. ###############################################################################
  846. ### Submit a comment to the defect's Jira
  847. submitJiraComment () {
  848. local result=$1
  849. ### Do not output the value of JIRA_COMMENT_FOOTER when run by a developer
  850. if [[ $JENKINS == "false" ]] ; then
  851. JIRA_COMMENT_FOOTER=""
  852. fi
  853. if [[ $result == 0 ]] ; then
  854. comment="{color:green}+1 overall{color}. $JIRA_COMMENT
  855. $JIRA_COMMENT_FOOTER"
  856. else
  857. comment="{color:red}-1 overall{color}. $JIRA_COMMENT
  858. $JIRA_COMMENT_FOOTER"
  859. fi
  860. ### Output the test result to the console
  861. echo "
  862. $comment"
  863. if [[ $JENKINS == "true" ]] ; then
  864. echo ""
  865. echo ""
  866. echo "======================================================================"
  867. echo "======================================================================"
  868. echo " Adding comment to Jira."
  869. echo "======================================================================"
  870. echo "======================================================================"
  871. echo ""
  872. echo ""
  873. ### Update Jira with a comment
  874. export USER=hudson
  875. $JIRACLI -s https://issues.apache.org/jira -a addcomment -u hadoopqa -p $JIRA_PASSWD --comment "$comment" --issue $defect
  876. $JIRACLI -s https://issues.apache.org/jira -a logout -u hadoopqa -p $JIRA_PASSWD
  877. fi
  878. }
  879. ###############################################################################
  880. ### Cleanup files
  881. cleanupAndExit () {
  882. local result=$1
  883. if [[ $JENKINS == "true" ]] ; then
  884. if [ -e "$PATCH_DIR" ] ; then
  885. mv $PATCH_DIR $BASEDIR
  886. fi
  887. fi
  888. echo ""
  889. echo ""
  890. echo "======================================================================"
  891. echo "======================================================================"
  892. echo " Finished build."
  893. echo "======================================================================"
  894. echo "======================================================================"
  895. echo ""
  896. echo ""
  897. exit $result
  898. }
  899. ###############################################################################
  900. ###############################################################################
  901. ###############################################################################
  902. JIRA_COMMENT=""
  903. JIRA_COMMENT_FOOTER="Console output: $BUILD_URL/console
  904. This message is automatically generated."
  905. ### Check if arguments to the script have been specified properly or not
  906. parseArgs $@
  907. cd $BASEDIR
  908. checkout
  909. RESULT=$?
  910. if [[ $JENKINS == "true" ]] ; then
  911. if [[ $RESULT != 0 ]] ; then
  912. exit 100
  913. fi
  914. fi
  915. downloadPatch
  916. verifyPatch
  917. (( RESULT = RESULT + $? ))
  918. if [[ $RESULT != 0 ]] ; then
  919. submitJiraComment 1
  920. cleanupAndExit 1
  921. fi
  922. prebuildWithoutPatch
  923. (( RESULT = RESULT + $? ))
  924. if [[ $RESULT != 0 ]] ; then
  925. submitJiraComment 1
  926. cleanupAndExit 1
  927. fi
  928. checkAuthor
  929. (( RESULT = RESULT + $? ))
  930. if [[ $JENKINS == "true" ]] ; then
  931. cleanUpXml
  932. fi
  933. checkTests
  934. (( RESULT = RESULT + $? ))
  935. applyPatch
  936. APPLY_PATCH_RET=$?
  937. (( RESULT = RESULT + $APPLY_PATCH_RET ))
  938. if [[ $APPLY_PATCH_RET != 0 ]] ; then
  939. submitJiraComment 1
  940. cleanupAndExit 1
  941. fi
  942. checkJavacWarnings
  943. JAVAC_RET=$?
  944. #2 is returned if the code could not compile
  945. if [[ $JAVAC_RET == 2 ]] ; then
  946. submitJiraComment 1
  947. cleanupAndExit 1
  948. fi
  949. (( RESULT = RESULT + $JAVAC_RET ))
  950. checkJavadocWarnings
  951. (( RESULT = RESULT + $? ))
  952. ### Checkstyle not implemented yet
  953. #checkStyle
  954. #(( RESULT = RESULT + $? ))
  955. buildAndInstall
  956. checkEclipseGeneration
  957. (( RESULT = RESULT + $? ))
  958. checkFindbugsWarnings
  959. (( RESULT = RESULT + $? ))
  960. checkReleaseAuditWarnings
  961. (( RESULT = RESULT + $? ))
  962. ### Run tests for Jenkins or if explictly asked for by a developer
  963. if [[ $JENKINS == "true" || $RUN_TESTS == "true" ]] ; then
  964. runTests
  965. (( RESULT = RESULT + $? ))
  966. runContribTests
  967. (( RESULT = RESULT + $? ))
  968. fi
  969. checkInjectSystemFaults
  970. (( RESULT = RESULT + $? ))
  971. JIRA_COMMENT_FOOTER="Test results: $BUILD_URL/testReport/
  972. $JIRA_COMMENT_FOOTER"
  973. submitJiraComment $RESULT
  974. cleanupAndExit $RESULT