testme.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #!/bin/bash
  2. #
  3. # return values of this script are:
  4. # 0 success
  5. # 128 a test failed
  6. # >0 the number of timed-out tests
  7. # 255 parsing of parameters failed
  8. set -e
  9. if [ -f /proc/cpuinfo ]
  10. then
  11. MAKE_JOBS=$(( ($(cat /proc/cpuinfo | grep -E '^processor[[:space:]]*:' | tail -n -1 | cut -d':' -f2) + 1) * 2 + 1 ))
  12. else
  13. MAKE_JOBS=8
  14. fi
  15. ret=0
  16. TEST_CFLAGS=""
  17. _help()
  18. {
  19. echo "Usage options for $(basename $0) [--with-cc=arg [other options]]"
  20. echo
  21. echo "Executing this script without any parameter will only run the default"
  22. echo "configuration that has automatically been determined for the"
  23. echo "architecture you're running."
  24. echo
  25. echo " --with-cc=* The compiler(s) to use for the tests"
  26. echo " This is an option that will be iterated."
  27. echo
  28. echo " --test-vs-mtest=* Run test vs. mtest for '*' operations."
  29. echo " Only the first of each options will be"
  30. echo " taken into account."
  31. echo
  32. echo "To be able to specify options a compiler has to be given with"
  33. echo "the option --with-cc=compilername"
  34. echo "All other options will be tested with all MP_xBIT configurations."
  35. echo
  36. echo " --with-{m64,m32,mx32} The architecture(s) to build and test"
  37. echo " for, e.g. --with-mx32."
  38. echo " This is an option that will be iterated,"
  39. echo " multiple selections are possible."
  40. echo " The mx32 architecture is not supported"
  41. echo " by clang and will not be executed."
  42. echo
  43. echo " --cflags=* Give an option to the compiler,"
  44. echo " e.g. --cflags=-g"
  45. echo " This is an option that will always be"
  46. echo " passed as parameter to CC."
  47. echo
  48. echo " --make-option=* Give an option to make,"
  49. echo " e.g. --make-option=\"-f makefile.shared\""
  50. echo " This is an option that will always be"
  51. echo " passed as parameter to make."
  52. echo
  53. echo " --with-low-mp Also build&run tests with -DMP_{8,16,32}BIT."
  54. echo
  55. echo " --mtest-real-rand Use real random data when running mtest."
  56. echo
  57. echo " --with-valgrind"
  58. echo " --with-valgrind=* Run in valgrind (slow!)."
  59. echo
  60. echo " --with-travis-valgrind Run with valgrind on Travis on specific branches."
  61. echo
  62. echo " --valgrind-options Additional Valgrind options"
  63. echo " Some of the options like e.g.:"
  64. echo " --track-origins=yes add a lot of extra"
  65. echo " runtime and may trigger the 30 minutes"
  66. echo " timeout."
  67. echo
  68. echo "Godmode:"
  69. echo
  70. echo " --all Choose all architectures and gcc and clang"
  71. echo " as compilers but does not run valgrind."
  72. echo
  73. echo " --format Runs the various source-code formatters"
  74. echo " and generators and checks if the sources"
  75. echo " are clean."
  76. echo
  77. echo " -h"
  78. echo " --help This message"
  79. echo
  80. echo " -v"
  81. echo " --version Prints the version. It is just the number"
  82. echo " of git commits to this file, no deeper"
  83. echo " meaning attached"
  84. exit 0
  85. }
  86. _die()
  87. {
  88. echo "error $2 while $1"
  89. if [ "$2" != "124" ]
  90. then
  91. exit 128
  92. else
  93. echo "assuming timeout while running test - continue"
  94. local _tail=""
  95. which tail >/dev/null && _tail="tail -n 1 test_${suffix}.log" && \
  96. echo "last line of test_"${suffix}".log was:" && $_tail && echo ""
  97. ret=$(( $ret + 1 ))
  98. fi
  99. }
  100. _make()
  101. {
  102. echo -ne " Compile $1 $2"
  103. suffix=$(echo ${1}${2} | tr ' ' '_')
  104. CC="$1" CFLAGS="$2 $TEST_CFLAGS" make -j$MAKE_JOBS $3 $MAKE_OPTIONS > /dev/null 2>gcc_errors_${suffix}.log
  105. errcnt=$(wc -l < gcc_errors_${suffix}.log)
  106. if [[ ${errcnt} -gt 1 ]]; then
  107. echo " failed"
  108. cat gcc_errors_${suffix}.log
  109. exit 128
  110. fi
  111. }
  112. _runtest()
  113. {
  114. make clean > /dev/null
  115. local _timeout=""
  116. which timeout >/dev/null && _timeout="timeout --foreground 90"
  117. if [[ "$MAKE_OPTIONS" =~ "tune" ]]
  118. then
  119. # "make tune" will run "tune_it.sh" automatically, hence "autotune", but it cannot
  120. # get switched off without some effort, so we just let it run twice for testing purposes
  121. echo -e "\rRun autotune $1 $2"
  122. _make "$1" "$2" ""
  123. $_timeout $TUNE_CMD > test_${suffix}.log || _die "running autotune" $?
  124. else
  125. _make "$1" "$2" "test"
  126. echo -e "\rRun test $1 $2"
  127. $_timeout ./test > test_${suffix}.log || _die "running tests" $?
  128. fi
  129. }
  130. # This is not much more of a C&P of _runtest with a different timeout
  131. # and the additional valgrind call.
  132. # TODO: merge
  133. _runvalgrind()
  134. {
  135. make clean > /dev/null
  136. local _timeout=""
  137. # 30 minutes? Yes. Had it at 20 minutes and the Valgrind run needed over 25 minutes.
  138. # A bit too close for comfort.
  139. which timeout >/dev/null && _timeout="timeout --foreground 1800"
  140. echo "MAKE_OPTIONS = \"$MAKE_OPTIONS\""
  141. if [[ "$MAKE_OPTIONS" =~ "tune" ]]
  142. then
  143. echo "autotune branch"
  144. _make "$1" "$2" ""
  145. # The shell used for /bin/sh is DASH 0.5.7-4ubuntu1 on the author's machine which fails valgrind, so
  146. # we just run on instance of etc/tune with the same options as in etc/tune_it.sh
  147. echo -e "\rRun etc/tune $1 $2 once inside valgrind"
  148. $_timeout $VALGRIND_BIN $VALGRIND_OPTS $TUNE_CMD > test_${suffix}.log || _die "running etc/tune" $?
  149. else
  150. _make "$1" "$2" "test"
  151. echo -e "\rRun test $1 $2 inside valgrind"
  152. $_timeout $VALGRIND_BIN $VALGRIND_OPTS ./test > test_${suffix}.log || _die "running tests" $?
  153. fi
  154. }
  155. _banner()
  156. {
  157. echo "uname="$(uname -a)
  158. [[ "$#" != "0" ]] && (echo $1=$($1 -dumpversion)) || true
  159. }
  160. _exit()
  161. {
  162. if [ "$ret" == "0" ]
  163. then
  164. echo "Tests successful"
  165. else
  166. echo "$ret tests timed out"
  167. fi
  168. exit $ret
  169. }
  170. ARCHFLAGS=""
  171. COMPILERS=""
  172. CFLAGS=""
  173. WITH_LOW_MP=""
  174. TEST_VS_MTEST=""
  175. MTEST_RAND=""
  176. # timed with an AMD A8-6600K
  177. # 25 minutes
  178. #VALGRIND_OPTS=" --track-origins=yes --leak-check=full --show-leak-kinds=all --error-exitcode=1 "
  179. # 9 minutes (14 minutes with --test-vs-mtest=333333 --mtest-real-rand)
  180. VALGRIND_OPTS=" --leak-check=full --show-leak-kinds=all --error-exitcode=1 "
  181. #VALGRIND_OPTS=""
  182. VALGRIND_BIN=""
  183. CHECK_FORMAT=""
  184. TUNE_CMD="./etc/tune -t -r 10 -L 3"
  185. alive_pid=0
  186. function kill_alive() {
  187. disown $alive_pid || true
  188. kill $alive_pid 2>/dev/null
  189. }
  190. function start_alive_printing() {
  191. [ "$alive_pid" == "0" ] || return 0;
  192. for i in `seq 1 10` ; do sleep 300 && echo "Tests still in Progress..."; done &
  193. alive_pid=$!
  194. trap kill_alive EXIT
  195. }
  196. while [ $# -gt 0 ];
  197. do
  198. case $1 in
  199. "--with-m64" | "--with-m32" | "--with-mx32")
  200. ARCHFLAGS="$ARCHFLAGS ${1:6}"
  201. ;;
  202. --with-cc=*)
  203. COMPILERS="$COMPILERS ${1#*=}"
  204. ;;
  205. --cflags=*)
  206. CFLAGS="$CFLAGS ${1#*=}"
  207. ;;
  208. --valgrind-options=*)
  209. VALGRIND_OPTS="$VALGRIND_OPTS ${1#*=}"
  210. ;;
  211. --with-valgrind*)
  212. if [[ ${1#*d} != "" ]]
  213. then
  214. VALGRIND_BIN="${1#*=}"
  215. else
  216. VALGRIND_BIN="valgrind"
  217. fi
  218. start_alive_printing
  219. ;;
  220. --with-travis-valgrind*)
  221. if [[ ("$TRAVIS_BRANCH" == "develop" && "$TRAVIS_PULL_REQUEST" == "false") || "$TRAVIS_BRANCH" == *"valgrind"* || "$TRAVIS_COMMIT_MESSAGE" == *"valgrind"* ]]
  222. then
  223. if [[ ${1#*d} != "" ]]
  224. then
  225. VALGRIND_BIN="${1#*=}"
  226. else
  227. VALGRIND_BIN="valgrind"
  228. fi
  229. start_alive_printing
  230. fi
  231. ;;
  232. --make-option=*)
  233. MAKE_OPTIONS="$MAKE_OPTIONS ${1#*=}"
  234. ;;
  235. --with-low-mp)
  236. WITH_LOW_MP="1"
  237. ;;
  238. --test-vs-mtest=*)
  239. TEST_VS_MTEST="${1#*=}"
  240. if ! [ "$TEST_VS_MTEST" -eq "$TEST_VS_MTEST" ] 2> /dev/null
  241. then
  242. echo "--test-vs-mtest Parameter has to be int"
  243. exit 255
  244. fi
  245. start_alive_printing
  246. ;;
  247. --mtest-real-rand)
  248. MTEST_RAND="-DLTM_MTEST_REAL_RAND"
  249. ;;
  250. --format)
  251. CHECK_FORMAT="1"
  252. ;;
  253. --all)
  254. COMPILERS="gcc clang"
  255. ARCHFLAGS="-m64 -m32 -mx32"
  256. ;;
  257. --help | -h)
  258. _help
  259. ;;
  260. --version | -v)
  261. echo $(git rev-list HEAD --count -- testme.sh) || echo "Unknown. Please run in original libtommath git repository."
  262. exit 0
  263. ;;
  264. *)
  265. echo "Ignoring option ${1}"
  266. ;;
  267. esac
  268. shift
  269. done
  270. function _check_git() {
  271. git update-index --refresh >/dev/null || true
  272. git diff-index --quiet HEAD -- . || ( echo "FAILURE: $*" && exit 1 )
  273. }
  274. if [[ "$CHECK_FORMAT" == "1" ]]
  275. then
  276. make astyle
  277. _check_git "make astyle"
  278. perl helper.pl --update-files
  279. _check_git "helper.pl --update-files"
  280. perl helper.pl --check-all
  281. _check_git "helper.pl --check-all"
  282. exit $?
  283. fi
  284. [[ "$VALGRIND_BIN" == "" ]] && VALGRIND_OPTS=""
  285. # default to CC environment variable if no compiler is defined but some other options
  286. if [[ "$COMPILERS" == "" ]] && [[ "$ARCHFLAGS$MAKE_OPTIONS$CFLAGS" != "" ]]
  287. then
  288. COMPILERS="$CC"
  289. # default to CC environment variable and run only default config if no option is given
  290. elif [[ "$COMPILERS" == "" ]]
  291. then
  292. _banner "$CC"
  293. if [[ "$VALGRIND_BIN" != "" ]]
  294. then
  295. _runvalgrind "$CC" ""
  296. else
  297. _runtest "$CC" ""
  298. fi
  299. _exit
  300. fi
  301. archflags=( $ARCHFLAGS )
  302. compilers=( $COMPILERS )
  303. # choosing a compiler without specifying an architecture will use the default architecture
  304. if [ "${#archflags[@]}" == "0" ]
  305. then
  306. archflags[0]=" "
  307. fi
  308. _banner
  309. if [[ "$TEST_VS_MTEST" != "" ]]
  310. then
  311. make clean > /dev/null
  312. _make "${compilers[0]} ${archflags[0]}" "$CFLAGS" "mtest_opponent"
  313. echo
  314. _make "gcc" "$MTEST_RAND" "mtest"
  315. echo
  316. echo "Run test vs. mtest for $TEST_VS_MTEST iterations"
  317. _timeout=""
  318. which timeout >/dev/null && _timeout="timeout --foreground 1800"
  319. $_timeout ./mtest/mtest $TEST_VS_MTEST | $VALGRIND_BIN $VALGRIND_OPTS ./mtest_opponent > valgrind_test.log 2> test_vs_mtest_err.log
  320. retval=$?
  321. head -n 5 valgrind_test.log
  322. tail -n 2 valgrind_test.log
  323. exit $retval
  324. fi
  325. for i in "${compilers[@]}"
  326. do
  327. if [ -z "$(which $i)" ]
  328. then
  329. echo "Skipped compiler $i, file not found"
  330. continue
  331. fi
  332. compiler_version=$(echo "$i="$($i -dumpversion))
  333. if [ "$compiler_version" == "clang=4.2.1" ]
  334. then
  335. # one of my versions of clang complains about some stuff in stdio.h and stdarg.h ...
  336. TEST_CFLAGS="-Wno-typedef-redefinition"
  337. else
  338. TEST_CFLAGS=""
  339. fi
  340. echo $compiler_version
  341. for a in "${archflags[@]}"
  342. do
  343. if [[ $(expr "$i" : "clang") -ne 0 && "$a" == "-mx32" ]]
  344. then
  345. echo "clang -mx32 tests skipped"
  346. continue
  347. fi
  348. if [[ "$VALGRIND_BIN" != "" ]]
  349. then
  350. _runvalgrind "$i $a" "$CFLAGS"
  351. [ "$WITH_LOW_MP" != "1" ] && continue
  352. _runvalgrind "$i $a" "-DMP_8BIT $CFLAGS"
  353. _runvalgrind "$i $a" "-DMP_16BIT $CFLAGS"
  354. _runvalgrind "$i $a" "-DMP_32BIT $CFLAGS"
  355. else
  356. _runtest "$i $a" "$CFLAGS"
  357. [ "$WITH_LOW_MP" != "1" ] && continue
  358. _runtest "$i $a" "-DMP_8BIT $CFLAGS"
  359. _runtest "$i $a" "-DMP_16BIT $CFLAGS"
  360. _runtest "$i $a" "-DMP_32BIT $CFLAGS"
  361. fi
  362. done
  363. done
  364. _exit