1#! /bin/sh 2# 3# Copyright (c) 2018-2019 Gavin D. Howard and contributors. 4# 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, this 11# list of conditions and the following disclaimer. 12# 13# * Redistributions in binary form must reproduce the above copyright notice, 14# this list of conditions and the following disclaimer in the documentation 15# and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30usage() { 31 printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script" 32 printf ' [run_sanitizers] [run_valgrind] [run_64_bit] [run_gen_script]\n' 33 exit 1 34} 35 36header() { 37 38 _header_msg="$1" 39 shift 40 41 printf '\n' 42 printf '*******************\n' 43 printf "$_header_msg" 44 printf '\n' 45 printf '*******************\n' 46 printf '\n' 47} 48 49do_make() { 50 make -j4 "$@" 51} 52 53configure() { 54 55 _configure_CFLAGS="$1" 56 shift 57 58 _configure_CC="$1" 59 shift 60 61 _configure_configure_flags="-f $1" 62 shift 63 64 _configure_GEN_HOST="$1" 65 shift 66 67 _configure_LONG_BIT="$1" 68 shift 69 70 if [ "$gen_tests" -eq 0 ]; then 71 _configure_configure_flags="-G $_configure_configure_flags" 72 fi 73 74 if [ "$_configure_CC" = "clang" ]; then 75 _configure_CFLAGS="$clang_flags $_configure_CFLAGS" 76 elif [ "$_configure_CC" = "gcc" ]; then 77 _configure_CFLAGS="$gcc_flags $_configure_CFLAGS" 78 fi 79 80 _configure_header=$(printf 'Running ./configure.sh %s ...' "$_configure_configure_flags") 81 _configure_header=$(printf "$_configure_header\n CC=\"%s\"\n" "$_configure_CC") 82 _configure_header=$(printf "$_configure_header\n CFLAGS=\"%s\"\n" "$_configure_CFLAGS") 83 _configure_header=$(printf "$_configure_header\n LONG_BIT=%s" "$_configure_LONG_BIT") 84 _configure_header=$(printf "$_configure_header\n GEN_HOST=%s" "$_configure_GEN_HOST") 85 86 header "$_configure_header" 87 CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \ 88 LONG_BIT="$_configure_LONG_BIT" ./configure.sh $_configure_configure_flags > /dev/null 89 90} 91 92build() { 93 94 _build_CFLAGS="$1" 95 shift 96 97 _build_CC="$1" 98 shift 99 100 _build_configure_flags="$1" 101 shift 102 103 _build_GEN_HOST="$1" 104 shift 105 106 _build_LONG_BIT="$1" 107 shift 108 109 configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT" 110 111 _build_header=$(printf 'Building...\n CC=%s' "$_build_CC") 112 _build_header=$(printf "$_build_header\n CFLAGS=\"%s\"" "$_build_CFLAGS") 113 _build_header=$(printf "$_build_header\n LONG_BIT=%s" "$_build_LONG_BIT") 114 _build_header=$(printf "$_build_header\n GEN_HOST=%s" "$_build_GEN_HOST") 115 116 header "$_build_header" 117 118 do_make > /dev/null 2> "$scriptdir/.test.txt" 119 120 if [ -s "$scriptdir/.test.txt" ]; then 121 printf '%s generated warning(s):\n' "$_build_CC" 122 printf '\n' 123 cat "$scriptdir/.test.txt" 124 exit 1 125 fi 126} 127 128runtest() { 129 130 header "Running tests" 131 132 if [ "$#" -gt 0 ]; then 133 do_make "$@" 134 else 135 do_make test 136 fi 137} 138 139runconfigtests() { 140 141 _runconfigtests_CFLAGS="$1" 142 shift 143 144 _runconfigtests_CC="$1" 145 shift 146 147 _runconfigtests_configure_flags="$1" 148 shift 149 150 _runconfigtests_GEN_HOST="$1" 151 shift 152 153 _runconfigtests_LONG_BIT="$1" 154 shift 155 156 _runconfigtests_run_tests="$1" 157 shift 158 159 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 160 _runconfigtests_header=$(printf 'Running tests with configure flags') 161 else 162 _runconfigtests_header=$(printf 'Building with configure flags') 163 fi 164 165 _runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags") 166 _runconfigtests_header=$(printf "$_runconfigtests_header\n CC=%s\n" "$_runconfigseries_CC") 167 _runconfigtests_header=$(printf "$_runconfigtests_header\n CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS") 168 _runconfigtests_header=$(printf "$_runconfigtests_header\n LONG_BIT=%s" "$_runconfigtests_LONG_BIT") 169 _runconfigtests_header=$(printf "$_runconfigtests_header\n GEN_HOST=%s" "$_runconfigtests_GEN_HOST") 170 171 header "$_runconfigtests_header" 172 173 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 174 "$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \ 175 "$_runconfigtests_LONG_BIT" 176 177 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 178 runtest 179 fi 180 181 do_make clean 182 183 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 184 "$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \ 185 "$_runconfigtests_LONG_BIT" 186 187 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 188 runtest 189 fi 190 191 do_make clean 192 193 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 194 "$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \ 195 "$_runconfigtests_LONG_BIT" 196 197 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 198 runtest 199 fi 200 201 do_make clean 202} 203 204runconfigseries() { 205 206 _runconfigseries_CFLAGS="$1" 207 shift 208 209 _runconfigseries_CC="$1" 210 shift 211 212 _runconfigseries_configure_flags="$1" 213 shift 214 215 _runconfigseries_run_tests="$1" 216 shift 217 218 if [ "$run_64_bit" -ne 0 ]; then 219 220 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 221 "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" 222 223 if [ "$run_gen_script" -ne 0 ]; then 224 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 225 "$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests" 226 fi 227 228 fi 229 230 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 231 "$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests" 232 233 if [ "$run_gen_script" -ne 0 ]; then 234 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 235 "$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests" 236 fi 237} 238 239runtestseries() { 240 241 _runtestseries_CFLAGS="$1" 242 shift 243 244 _runtestseries_CC="$1" 245 shift 246 247 _runtestseries_configure_flags="$1" 248 shift 249 250 _runtestseries_run_tests="$1" 251 shift 252 253 _runtestseries_flags="E H N P S EH EN EP ES HN HP HS NP NS PS EHN EHP EHS 254 ENP ENS EPS HNP HNS HPS NPS EHNP EHNS EHPS ENPS HNPS EHNPS" 255 256 runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 257 "$_runtestseries_configure_flags" "$_runtestseries_run_tests" 258 259 for f in $_runtestseries_flags; do 260 runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 261 "$_runtestseries_configure_flags -$f" "$_runtestseries_run_tests" 262 done 263} 264 265runtests() { 266 267 _runtests_CFLAGS="$1" 268 shift 269 270 _runtests_CC="$1" 271 shift 272 273 _runtests_configure_flags="$1" 274 shift 275 276 _runtests_run_tests="$1" 277 shift 278 279 runtestseries "$_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" 280} 281 282karatsuba() { 283 284 header "Running Karatsuba tests" 285 do_make karatsuba_test 286} 287 288vg() { 289 290 header "Running valgrind" 291 292 if [ "$run_64_bit" -ne 0 ]; then 293 _vg_bits=64 294 else 295 _vg_bits=32 296 fi 297 298 build "$debug" "gcc" "-O0 -g" "1" "$_vg_bits" 299 runtest valgrind 300 301 do_make clean_config 302 303 build "$debug" "gcc" "-O0 -gb" "1" "$_vg_bits" 304 runtest valgrind 305 306 do_make clean_config 307 308 build "$debug" "gcc" "-O0 -gd" "1" "$_vg_bits" 309 runtest valgrind 310 311 do_make clean_config 312} 313 314debug() { 315 316 _debug_CC="$1" 317 shift 318 319 _debug_run_tests="$1" 320 shift 321 322 runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" 323 324 if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 325 runtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests" 326 fi 327} 328 329release() { 330 331 _release_CC="$1" 332 shift 333 334 _release_run_tests="$1" 335 shift 336 337 runtests "$release" "$_release_CC" "-O3" "$_release_run_tests" 338} 339 340reldebug() { 341 342 _reldebug_CC="$1" 343 shift 344 345 _reldebug_run_tests="$1" 346 shift 347 348 runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 349 350 if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 351 runtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 352 runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 353 fi 354} 355 356minsize() { 357 358 _minsize_CC="$1" 359 shift 360 361 _minsize_run_tests="$1" 362 shift 363 364 runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" 365} 366 367build_set() { 368 369 _build_set_CC="$1" 370 shift 371 372 _build_set_run_tests="$1" 373 shift 374 375 debug "$_build_set_CC" "$_build_set_run_tests" 376 release "$_build_set_CC" "$_build_set_run_tests" 377 reldebug "$_build_set_CC" "$_build_set_run_tests" 378 minsize "$_build_set_CC" "$_build_set_run_tests" 379} 380 381clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral" 382clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion" 383clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return" 384gcc_flags="-Wno-maybe-uninitialized" 385 386cflags="-Wall -Wextra -Werror -pedantic -std=c99 -Wno-conditional-uninitialized" 387 388debug="$cflags -fno-omit-frame-pointer" 389release="$cflags -DNDEBUG" 390 391set -e 392 393script="$0" 394scriptdir=$(dirname "$script") 395 396if [ "$#" -gt 0 ]; then 397 run_tests="$1" 398 shift 399else 400 run_tests=1 401fi 402 403if [ "$#" -gt 0 ]; then 404 gen_tests="$1" 405 shift 406else 407 gen_tests=1 408fi 409 410if [ "$#" -gt 0 ]; then 411 test_with_clang="$1" 412 shift 413else 414 test_with_clang=1 415fi 416 417if [ "$#" -gt 0 ]; then 418 test_with_gcc="$1" 419 shift 420else 421 test_with_gcc=1 422fi 423 424if [ "$#" -gt 0 ]; then 425 run_sanitizers="$1" 426 shift 427else 428 run_sanitizers=1 429fi 430 431if [ "$#" -gt 0 ]; then 432 run_valgrind="$1" 433 shift 434else 435 run_valgrind=1 436fi 437 438if [ "$#" -gt 0 ]; then 439 run_64_bit="$1" 440 shift 441else 442 run_64_bit=1 443fi 444 445if [ "$#" -gt 0 ]; then 446 run_gen_script="$1" 447 shift 448else 449 run_gen_script=0 450fi 451 452if [ "$run_64_bit" -ne 0 ]; then 453 bits=64 454else 455 bits=32 456fi 457 458cd "$scriptdir" 459 460if [ "$test_with_clang" -ne 0 ]; then 461 defcc="clang" 462elif [ "$test_with_gcc" -ne 0 ]; then 463 defcc="gcc" 464else 465 defcc="c99" 466fi 467 468build "$debug" "$defcc" "-g" "1" "$bits" 469 470header "Running math library under --standard" 471 472printf 'quit\n' | bin/bc -ls 473 474version=$(make version) 475 476do_make clean_tests 477 478if [ "$test_with_clang" -ne 0 ]; then 479 build_set "clang" "$run_tests" 480fi 481 482if [ "$test_with_gcc" -ne 0 ]; then 483 build_set "gcc" "$run_tests" 484fi 485 486if [ "$run_tests" -ne 0 ]; then 487 488 build "$release" "$defcc" "-O3" "1" "$bits" 489 490 karatsuba 491 492 if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then 493 vg 494 fi 495 496 printf '\n' 497 printf 'Tests successful.\n' 498 499 set +e 500 501 command -v afl-gcc > /dev/null 2>&1 502 err="$?" 503 504 set -e 505 506 if [ "$err" -eq 0 ]; then 507 508 header "Configuring for afl-gcc..." 509 510 configure "$debug" "afl-gcc" "-HNPS -gO3" "1" "$bits" 511 512 printf '\n' 513 printf 'Run make\n' 514 printf '\n' 515 printf 'Then run %s/tests/randmath.py and the fuzzer.\n' "$scriptdir" 516 printf '\n' 517 printf 'Then run ASan on the fuzzer test cases with the following build:\n' 518 printf '\n' 519 printf ' CFLAGS="-fsanitize=address -fno-omit-frame-pointer" ./configure.sh -gO3 -HNPS\n' 520 printf ' make\n' 521 printf '\n' 522 printf 'Then run the GitHub release script as follows:\n' 523 printf '\n' 524 printf ' <github_release> %s .travis.yml codecov.yml release.sh \\\n' "$version" 525 printf ' RELEASE.md tests/afl.py tests/randmath.py tests/bc/scripts/timeconst.bc\n' 526 527 fi 528 529fi 530