1 #!/bin/sh 2 # 3 # Copyright (C) 2010 The Android Open Source Project 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 # This shell script is used to run all NDK build tests in a row. 18 # "Build tests" are tests that check the building features of the NDK 19 # but do not run anything on target devices/emulators. 20 # 21 22 # You need to define the NDK 23 24 PROGDIR=`dirname $0` 25 PROGDIR=`cd $PROGDIR && pwd` 26 27 # Assume that we are under tests/ 28 # and that the samples will be under samples/ and platforms/android-N/samples/ 29 # 30 ROOTDIR=`cd $PROGDIR/.. && pwd` 31 . $ROOTDIR/build/core/ndk-common.sh 32 33 # The list of tests that are too long to be part of a normal run of 34 # run-tests.sh. Most of these do not run properly at the moment. 35 LONG_TESTS="prebuild-stlport test-stlport test-gnustl" 36 37 # 38 # Parse options 39 # 40 VERBOSE=no 41 ABI=armeabi 42 PLATFORM="" 43 NDK_ROOT= 44 JOBS=$BUILD_NUM_CPUS 45 find_program ADB_CMD adb 46 TESTABLES="samples build device awk" 47 FULL_TESTS=no 48 RUN_TESTS= 49 NDK_PACKAGE= 50 WINE= 51 52 while [ -n "$1" ]; do 53 opt="$1" 54 optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'` 55 case "$opt" in 56 --help|-h|-\?) 57 OPTION_HELP=yes 58 ;; 59 --verbose) 60 if [ "$VERBOSE" = "yes" ] ; then 61 VERBOSE2=yes 62 else 63 VERBOSE=yes 64 fi 65 ;; 66 --abi=*) 67 ABI="$optarg" 68 ;; 69 --platform=*) 70 PLATFORM="$optarg" 71 ;; 72 --ndk=*) 73 NDK_ROOT="$optarg" 74 ;; 75 --full) 76 FULL_TESTS=yes; 77 ;; 78 --test=*) # Deprecated, but keep it just in case. 79 RUN_TESTS="$RUN_TESTS $optarg" 80 ;; 81 --package=*) 82 NDK_PACKAGE="$optarg" 83 ;; 84 -j*) 85 JOBS=`expr "$opt" : '-j\(.*\)'` 86 shift 87 ;; 88 --jobs=*) 89 JOBS="$optarg" 90 ;; 91 --adb=*) 92 ADB_CMD="$optarg" 93 ;; 94 --only-samples) 95 TESTABLES=samples 96 ;; 97 --only-build) 98 TESTABLES=build 99 ;; 100 --only-device) 101 TESTABLES=device 102 ;; 103 --only-awk) 104 TESTABLES=awk 105 ;; 106 --wine) 107 WINE=yes 108 ;; 109 -*) # unknown options 110 echo "ERROR: Unknown option '$opt', use --help for list of valid ones." 111 exit 1 112 ;; 113 *) # Simply record new test name 114 RUN_TESTS=$RUN_TESTS" $opt" 115 ;; 116 esac 117 shift 118 done 119 120 if [ "$OPTION_HELP" = "yes" ] ; then 121 echo "Usage: $PROGNAME [options] [testname1 [testname2...]]" 122 echo "" 123 echo "Run NDK automated tests. Without any parameter, this will try to" 124 echo "run all standard tests, except those are tagged broken. You can" 125 echo "also select/enforce specific tests by listing their name on the" 126 echo "command-line." 127 echo "" 128 echo "Valid options:" 129 echo "" 130 echo " --help|-h|-? Print this help" 131 echo " --verbose Enable verbose mode (can be used several times)" 132 echo " --ndk=<path> Path to NDK to test [$ROOTDIR]" 133 echo " --package=<path> Path to NDK package to test" 134 echo " -j<N> --jobs=<N> Launch parallel builds [$JOBS]" 135 echo " --abi=<name> Only run tests for the specific ABI [$ABI]" 136 echo " --platform=<name> Force API level for testing; platform=<android-x>" 137 echo " --adb=<file> Specify adb executable for device tests" 138 echo " --only-samples Only rebuild samples" 139 echo " --only-build Only rebuild build tests" 140 echo " --only-device Only rebuild & run device tests" 141 echo " --only-awk Only run awk tests." 142 echo " --full Run all device tests, even very long ones." 143 echo " --wine Build all tests with wine on Linux" 144 echo "" 145 echo "NOTE: You cannot use --ndk and --package at the same time." 146 echo "" 147 exit 0 148 fi 149 150 # Run a command in ADB. 151 # 152 # This is needed because "adb shell" does not return the proper status 153 # of the launched command, so we need to add it to the output, and grab 154 # it after that. 155 # 156 adb_cmd () 157 { 158 local RET ADB_CMD_LOG 159 # mktemp under Mac OS X requires the -t option 160 ADB_CMD_LOG=$(mktemp -t XXXXXXXX) 161 if [ $VERBOSE = "yes" ] ; then 162 echo "$ADB_CMD shell $@" 163 $ADB_CMD shell $@ ";" echo \$? | tee $ADB_CMD_LOG 164 else 165 $ADB_CMD shell $@ ";" echo \$? > $ADB_CMD_LOG 166 fi 167 # Get last line in log, should be OK or KO 168 # +Get rid of \r at the end of lines 169 RET=`sed -e 's![[:cntrl:]]!!g' $ADB_CMD_LOG | tail -n1` 170 rm -f $ADB_CMD_LOG 171 return $RET 172 } 173 174 # Make a directory path on device 175 # 176 # The 'mkdir' command on the Android device does not 177 # support the '-p' option. This function will test 178 # for the existence of the parent directory and recursively 179 # call itself until it files a parent which exists; then 180 # create the requested directory. 181 adb_cmd_mkdir () 182 { 183 local FULLDIR BASEDIR 184 FULLDIR=$1 185 BASEDIR=`dirname $FULLDIR` 186 187 #run $ADB_CMD shell "ls $BASEDIR 1>/dev/null 2>&1" 188 adb_cmd "ls $BASEDIR 1>/dev/null 2>&1" 189 if [ $? != 0 ] ; then 190 if [ $BASEDIR = "/" ] ; then 191 dump "ERROR: Could not find the root (/) directory on the device!" 192 exit 1 193 else 194 adb_cmd_mkdir $BASEDIR 195 adb_cmd_mkdir $FULLDIR 196 fi 197 else 198 #run $ADB_CMD shell "mkdir $FULLDIR" 199 # If the directory doesn't exist, make it 200 adb_cmd "ls $FULLDIR 1>/dev/null 2>&1 || mkdir $FULLDIR" 201 if [ $? != 0 ] ; then 202 dump "ERROR: Could not mkdir '$FULLDIR' on the device!" 203 exit 1 204 fi 205 fi 206 } 207 208 # Returns 0 if a variable containing one or more items separated 209 # by spaces contains a given value. 210 # $1: variable name (e.g. FOO) 211 # $2: value to test 212 var_list_contains () 213 { 214 echo `var_value $1` | tr ' ' '\n' | grep -q -F -x -e "$2" 215 } 216 217 # 218 # List of stuff to actually tests 219 # 220 is_testable () { 221 var_list_contains TESTABLES "$1" 222 } 223 224 # is_buildable returns 0 if a test should be built/run for this invocation 225 # $1: test path 226 if [ -n "$RUN_TESTS" ] ; then 227 is_buildable () { 228 [ -f $1/build.sh -o -f $1/jni/Android.mk ] && 229 var_list_contains RUN_TESTS "`basename $1`" 230 } 231 elif [ "$FULL_TESTS" = "yes" ] ; then 232 is_buildable () { 233 [ -f $1/build.sh -o -f $1/jni/Android.mk ] 234 } 235 else # !FULL_TESTS 236 is_buildable () { 237 [ -f $1/build.sh -o -f $1/jni/Android.mk ] || return 1 238 ! var_list_contains LONG_TESTS "`basename $1`" || return 1 239 } 240 fi # !FULL_TESTS 241 242 243 TEST_DIR="/tmp/ndk-$USER/tests" 244 mkdir -p $TEST_DIR 245 setup_default_log_file "$TEST_DIR/build-tests.log" 246 247 if [ -n "$NDK_PACKAGE" ] ; then 248 if [ -n "$NDK_ROOT" ] ; then 249 dump "ERROR: You can't use --ndk and --package at the same time!" 250 exit 1 251 fi 252 NDK_ROOT=/tmp/ndk-tests/install 253 mkdir -p "$NDK_ROOT" && rm -rf "$NDK_ROOT/*" 254 dump "Unpacking NDK package to $NDK_ROOT" 255 unpack_archive "$NDK_PACKAGE" "$NDK_ROOT" 256 NDK_ROOT=`ls -d $NDK_ROOT/*` 257 fi 258 259 # 260 # Check the NDK install path. 261 # 262 if [ -n "$NDK_ROOT" ] ; then 263 if [ ! -d "$NDK_ROOT" ] ; then 264 dump "ERROR: Your --ndk option does not point to a directory: $NDK_ROOT" 265 dump "Please use a valid path for this option." 266 exit 1 267 fi 268 if [ ! -f "$NDK_ROOT/ndk-build" -o ! -f "$NDK_ROOT/build/core/ndk-common.sh" ] ; then 269 dump "ERROR: Your --ndk option does not point to a valid NDK install: $NDK_ROOT" 270 dump "Please use a valid NDK install path for this option." 271 exit 3 272 fi 273 NDK="$NDK_ROOT" 274 else 275 NDK="$ROOTDIR" 276 fi 277 278 # 279 # Create log file 280 # 281 282 BUILD_DIR=$TEST_DIR/build 283 mkdir -p "$BUILD_DIR" && rm -rf "$BUILD_DIR/*" 284 285 ### 286 ### RUN AWK TESTS 287 ### 288 289 # Run a simple awk script 290 # $1: awk script to run 291 # $2: input file 292 # $3: expected output file 293 # $4+: optional additional command-line arguments for the awk command 294 run_awk_test () 295 { 296 local SCRIPT="$1" 297 local SCRIPT_NAME="`basename $SCRIPT`" 298 local INPUT="$2" 299 local INPUT_NAME="`basename $INPUT`" 300 local EXPECTED="$3" 301 local EXPECTED_NAME="`basename $EXPECTED`" 302 shift; shift; shift; 303 local OUTPUT="$BUILD_DIR/$EXPECTED_NAME" 304 if [ "$VERBOSE2" = "yes" ]; then 305 echo "### COMMAND: awk -f \"$SCRIPT\" $@ < \"$INPUT\" > \"$OUTPUT\"" 306 fi 307 awk -f "$SCRIPT" $@ < "$INPUT" > "$OUTPUT" 308 fail_panic "Can't run awk script: $SCRIPT" 309 if [ "$VERBOSE2" = "yes" ]; then 310 echo "OUTPUT FROM SCRIPT:" 311 cat "$OUTPUT" 312 echo "EXPECTED VALUES:" 313 cat "$EXPECTED" 314 fi 315 cmp -s "$OUTPUT" "$EXPECTED" 316 if [ $? = 0 ] ; then 317 echo "Awk script: $SCRIPT_NAME: passed $INPUT_NAME" 318 if [ "$VERBOSE2" = "yes" ]; then 319 cat "$OUTPUT" 320 fi 321 else 322 if [ "$VERBOSE" = "yes" ]; then 323 run diff -burN "$EXPECTED" "$OUTPUT" 324 fi 325 echo "Awk script: $SCRIPT_NAME: $INPUT_NAME FAILED!!" 326 rm -f "$OUTPUT" 327 exit 1 328 fi 329 } 330 331 run_awk_test_dir () 332 { 333 local SCRIPT_NAME="`basename \"$DIR\"`" 334 local SCRIPT="$ROOTDIR/build/awk/$SCRIPT_NAME.awk" 335 local INPUT 336 local OUTPUT 337 if [ ! -f "$SCRIPT" ]; then 338 echo "Awk script: $SCRIPT_NAME: Missing script: $SCRIPT" 339 continue 340 fi 341 for INPUT in `ls "$PROGDIR"/awk/$SCRIPT_NAME/*.in`; do 342 OUTPUT=`echo $INPUT | sed 's/\.in$/.out/g'` 343 if [ ! -f "$OUTPUT" ]; then 344 echo "Awk script: $SCRIPT_NAME: Missing awk output file: $OUTPUT" 345 continue 346 fi 347 run_awk_test "$SCRIPT" "$INPUT" "$OUTPUT" 348 done 349 } 350 351 if is_testable awk; then 352 AWKDIR="$ROOTDIR/build/awk" 353 for DIR in `ls -d "$PROGDIR"/awk/*`; do 354 run_awk_test_dir "$DIR" 355 done 356 fi 357 358 ### 359 ### REBUILD ALL SAMPLES FIRST 360 ### 361 362 # Special case, if ABI is 'armeabi' or 'armeabi-v7a' 363 # we want to build both armeabi and armeabi-v7a machine code 364 # even if we will only run the armeabi test programs on the 365 # device. This is done by not forcing the definition of APP_ABI 366 NDK_BUILD_FLAGS="-B" 367 case $ABI in 368 armeabi|armeabi-v7a) 369 ;; 370 x86|mips) 371 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_ABI=$ABI" 372 ;; 373 *) 374 echo "ERROR: Unsupported abi value: $ABI" 375 exit 1 376 ;; 377 esac 378 379 # Force all tests to run at one API level 380 if [ "$PLATFORM" != "" ]; then 381 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_PLATFORM=$PLATFORM" 382 fi 383 384 # Use --verbose twice to see build commands for the tests 385 if [ "$VERBOSE2" = "yes" ] ; then 386 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS V=1" 387 fi 388 389 run_ndk_build () 390 { 391 if [ "$WINE" ]; then 392 run wine cmd /c Z:$NDK/ndk-build.cmd -j$JOBS "$@" 393 else 394 run $NDK/ndk-build -j$JOBS "$@" 395 fi 396 } 397 398 build_project () 399 { 400 local NAME=`basename $1` 401 local DIR="$BUILD_DIR/$NAME" 402 if [ -f "$1/BROKEN_BUILD" -a -z "$RUN_TESTS" ] ; then 403 echo "Skipping $1: (build)" 404 return 0 405 fi 406 rm -rf "$DIR" && cp -r "$1" "$DIR" 407 (cd "$DIR" && run_ndk_build $NDK_BUILD_FLAGS) 408 RET=$? 409 if [ -f "$1/BUILD_SHOULD_FAIL" ]; then 410 if [ $RET = 0 ]; then 411 echo "!!! FAILURE: BUILD SHOULD HAVE FAILED [$1]" 412 exit 1 413 fi 414 log "!!! SUCCESS: BUILD FAILED AS EXPECTED [$(basename $1)]" 415 RET=0 416 fi 417 if [ $RET != 0 ] ; then 418 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 419 exit 1 420 fi 421 } 422 423 # 424 # Determine list of samples directories. 425 # 426 if is_testable samples; then 427 if [ -f "$NDK/RELEASE.TXT" ] ; then 428 # This is a release package, all samples should be under $NDK/samples 429 SAMPLES_DIRS="$NDK/samples" 430 if [ ! -d "$SAMPLES_DIRS" ] ; then 431 dump "ERROR: Missing samples directory: $SAMPLES_DIRS" 432 dump "Your NDK release installation is broken!" 433 exit 1 434 fi 435 log "Using release NDK samples from: $SAMPLES_DIRS" 436 else 437 # This is a development work directory, we will take the samples 438 # directly from development/ndk. 439 DEVNDK_DIR=`dirname $NDK`/development/ndk 440 if [ ! -d "$DEVNDK_DIR" ] ; then 441 dump "ERROR: Could not find development NDK directory: $DEVNDK_DIR" 442 dump "Please clone platform/development.git from android.googlesource.com" 443 exit 1 444 fi 445 SAMPLES_DIRS="$DEVNDK_DIR/samples" 446 for DIR in `ls -d $DEVNDK_DIR/platforms/android-*/samples`; do 447 SAMPLES_DIRS="$SAMPLES_DIRS $DIR" 448 done 449 dump "Using development NDK samples from $DEVNDK_DIR" 450 if [ "$VERBOSE" = "yes" ] ; then 451 echo "$SAMPLES_DIRS" | tr ' ' '\n' 452 fi 453 fi 454 455 # 456 # Copy the samples to a temporary build directory 457 458 build_sample () 459 { 460 echo "Building NDK sample: `basename $1`" 461 build_project $1 462 } 463 464 for DIR in $SAMPLES_DIRS; do 465 for SUBDIR in `ls -d $DIR/*`; do 466 if is_buildable $SUBDIR; then 467 build_sample $SUBDIR 468 fi 469 done 470 done 471 fi 472 473 ### 474 ### BUILD PROJECTS UNDER tests/build/ 475 ### 476 477 if is_testable build; then 478 build_build_test () 479 { 480 echo "Building NDK build test: `basename $1`" 481 if [ -f $1/build.sh ]; then 482 export NDK 483 run $1/build.sh $NDK_BUILD_FLAGS 484 if [ $? != 0 ]; then 485 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!" 486 exit 1 487 fi 488 else 489 build_project $1 490 fi 491 } 492 493 for DIR in `ls -d $ROOTDIR/tests/build/*`; do 494 if is_buildable $DIR; then 495 build_build_test $DIR 496 fi 497 done 498 fi 499 500 ### 501 ### BUILD PROJECTS UNDER tests/device/ 502 ### XXX: TODO: RUN THEM ON A DEVICE/EMULATOR WITH ADB 503 ### 504 505 if is_testable device; then 506 build_device_test () 507 { 508 # Do not build test if BROKEN_BUILD is defined, except if we 509 # Have listed the test explicitely. 510 if [ -f "$1/BROKEN_BUILD" -a -z "$RUN_TESTS" ] ; then 511 echo "Skipping broken device test build: `basename $1`" 512 return 0 513 fi 514 echo "Building NDK device test: `basename $1` in $1" 515 build_project $1 516 } 517 518 run_device_test () 519 { 520 local SRCDIR="$BUILD_DIR/`basename $1`/libs/$ABI" 521 local DSTDIR="$2/ndk-tests" 522 local SRCFILE 523 local DSTFILE 524 local PROGRAMS= 525 local PROGRAM 526 # Do not run the test if BROKEN_RUN is defined 527 if [ -f "$1/BROKEN_RUN" -o -f "$1/BROKEN_BUILD" ] ; then 528 if [ -z "$RUN_TESTS" ]; then 529 dump "Skipping NDK device test run: `basename $1`" 530 return 0 531 fi 532 fi 533 if [ ! -d "$SRCDIR" ]; then 534 dump "Skipping NDK device test run (no $ABI binaries): `basename $1`" 535 return 0 536 fi 537 # First, copy all files to the device, except for gdbserver 538 # or gdb.setup. 539 adb_cmd_mkdir $DSTDIR 540 for SRCFILE in `ls $SRCDIR`; do 541 DSTFILE=`basename $SRCFILE` 542 if [ "$DSTFILE" = "gdbserver" -o "$DSTFILE" = "gdb.setup" ] ; then 543 continue 544 fi 545 DSTFILE="$DSTDIR/$DSTFILE" 546 run $ADB_CMD push "$SRCDIR/$SRCFILE" "$DSTFILE" && 547 run $ADB_CMD shell chmod 0755 $DSTFILE 548 if [ $? != 0 ] ; then 549 dump "ERROR: Could not install $SRCFILE to device!" 550 exit 1 551 fi 552 # If its name doesn't end with .so, add it to PROGRAMS 553 echo "$DSTFILE" | grep -q -e '\.so$' 554 if [ $? != 0 ] ; then 555 PROGRAMS="$PROGRAMS $DSTFILE" 556 fi 557 done 558 for PROGRAM in $PROGRAMS; do 559 dump "Running device test: `basename $PROGRAM`" 560 adb_cmd LD_LIBRARY_PATH="$DSTDIR" $PROGRAM 561 if [ $? != 0 ] ; then 562 dump " ---> TEST FAILED!!" 563 fi 564 done 565 # Cleanup 566 adb_cmd rm -r $DSTDIR 567 } 568 569 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 570 if is_buildable $DIR; then 571 build_device_test $DIR 572 fi 573 done 574 575 # Do we have adb and any device connected here? 576 # If not, we can't run our tests. 577 # 578 SKIP_TESTS=no 579 if [ -z "$ADB_CMD" ] ; then 580 dump "WARNING: No 'adb' in your path!" 581 SKIP_TESTS=yes 582 else 583 ADB_DEVICES=`$ADB_CMD devices` 584 log2 "ADB devices: $ADB_DEVICES" 585 ADB_DEVCOUNT=`echo "$ADB_DEVICES" | wc -l` 586 ADB_DEVCOUNT=`expr $ADB_DEVCOUNT - 1` 587 log2 "ADB Device count: $ADB_DEVCOUNT" 588 if [ "$ADB_DEVCOUNT" = "0" ]; then 589 dump "WARNING: No device connected to adb!" 590 SKIP_TESTS=yes 591 elif [ "$ADB_DEVCOUNT" != 1 -a -z "$ANDROID_SERIAL" ] ; then 592 dump "WARNING: More than one device connected to adb. Please define ANDROID_SERIAL!" 593 SKIP_TESTS=yes 594 fi 595 echo "$ADB_DEVICES" | grep -q -e "offline" 596 if [ $? = 0 ] ; then 597 dump "WARNING: Device is offline, can't run device tests!" 598 SKIP_TESTS=yes 599 fi 600 fi 601 602 if [ "$SKIP_TESTS" = "yes" ] ; then 603 dump "SKIPPING RUNNING TESTS ON DEVICE!" 604 else 605 for DIR in `ls -d $ROOTDIR/tests/device/*`; do 606 log "Running device test: $DIR" 607 if is_buildable $DIR; then 608 run_device_test $DIR /data/local/tmp 609 fi 610 done 611 fi 612 fi 613 614 dump "Cleaning up..." 615 rm -rf $BUILD_DIR 616 dump "Done." 617