Home | History | Annotate | Download | only in tests
      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 NDK_BUILDTOOLS_PATH=$ROOTDIR/build/tools
     32 . $ROOTDIR/build/core/ndk-common.sh
     33 . $ROOTDIR/build/tools/prebuilt-common.sh
     34 
     35 # The list of tests that are too long to be part of a normal run of
     36 # run-tests.sh. Most of these do not run properly at the moment.
     37 LONG_TESTS="prebuild-stlport test-stlport test-gnustl-full test-stlport_shared-exception test-stlport_static-exception"
     38 
     39 #
     40 # Parse options
     41 #
     42 VERBOSE=no
     43 ABI=default
     44 PLATFORM=""
     45 NDK_ROOT=
     46 JOBS=$BUILD_NUM_CPUS
     47 find_program ADB_CMD adb
     48 TESTABLES="samples build device awk"
     49 FULL_TESTS=no
     50 RUN_TESTS=
     51 NDK_PACKAGE=
     52 WINE=
     53 CONTINUE_ON_BUILD_FAIL=
     54 
     55 while [ -n "$1" ]; do
     56     opt="$1"
     57     optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
     58     case "$opt" in
     59         --help|-h|-\?)
     60             OPTION_HELP=yes
     61             ;;
     62         --verbose)
     63             if [ "$VERBOSE" = "yes" ] ; then
     64                 VERBOSE2=yes
     65             else
     66                 VERBOSE=yes
     67             fi
     68             ;;
     69         --abi=*)
     70             ABI="$optarg"
     71             ;;
     72         --platform=*)
     73             PLATFORM="$optarg"
     74             ;;
     75         --ndk=*)
     76             NDK_ROOT="$optarg"
     77             ;;
     78         --full)
     79             FULL_TESTS=yes;
     80             ;;
     81         --test=*)  # Deprecated, but keep it just in case.
     82             RUN_TESTS="$RUN_TESTS $optarg"
     83             ;;
     84         --package=*)
     85             NDK_PACKAGE="$optarg"
     86             ;;
     87         -j*)
     88             JOBS=`expr "$opt" : '-j\(.*\)'`
     89             shift
     90             ;;
     91         --jobs=*)
     92             JOBS="$optarg"
     93             ;;
     94         --adb=*)
     95             ADB_CMD="$optarg"
     96             ;;
     97         --only-samples)
     98             TESTABLES=samples
     99             ;;
    100         --only-build)
    101             TESTABLES=build
    102             ;;
    103         --only-device)
    104             TESTABLES=device
    105             ;;
    106         --only-awk)
    107             TESTABLES=awk
    108             ;;
    109         --wine)
    110             WINE=yes
    111             ;;
    112         --continue-on-build-fail)
    113             CONTINUE_ON_BUILD_FAIL=yes
    114             ;;
    115         -*) # unknown options
    116             echo "ERROR: Unknown option '$opt', use --help for list of valid ones."
    117             exit 1
    118         ;;
    119         *)  # Simply record new test name
    120             RUN_TESTS=$RUN_TESTS" $opt"
    121             ;;
    122     esac
    123     shift
    124 done
    125 
    126 if [ "$OPTION_HELP" = "yes" ] ; then
    127     echo "Usage: $PROGNAME [options] [testname1 [testname2...]]"
    128     echo ""
    129     echo "Run NDK automated tests. Without any parameter, this will try to"
    130     echo "run all standard tests, except those are tagged broken. You can"
    131     echo "also select/enforce specific tests by listing their name on the"
    132     echo "command-line."
    133     echo ""
    134     echo "Valid options:"
    135     echo ""
    136     echo "    --help|-h|-?      Print this help"
    137     echo "    --verbose         Enable verbose mode (can be used several times)"
    138     echo "    --ndk=<path>      Path to NDK to test [$ROOTDIR]"
    139     echo "    --package=<path>  Path to NDK package to test"
    140     echo "    -j<N> --jobs=<N>  Launch parallel builds [$JOBS]"
    141     echo "    --abi=<name>      Only run tests for the specific ABI [$ABI]"
    142     echo "    --platform=<name> Force API level for testing; platform=<android-x>"
    143     echo "    --adb=<file>      Specify adb executable for device tests"
    144     echo "    --only-samples    Only rebuild samples"
    145     echo "    --only-build      Only rebuild build tests"
    146     echo "    --only-device     Only rebuild & run device tests"
    147     echo "    --only-awk        Only run awk tests."
    148     echo "    --full            Run all device tests, even very long ones."
    149     echo "    --wine            Build all tests with wine on Linux"
    150     echo ""
    151     echo "NOTE: You cannot use --ndk and --package at the same time."
    152     echo ""
    153     exit 0
    154 fi
    155 
    156 # Run a command in ADB.
    157 #
    158 # This is needed because "adb shell" does not return the proper status
    159 # of the launched command, so we need to add it to the output, and grab
    160 # it after that.
    161 # $1: Device name
    162 # $2: Variable name that will contain the result
    163 # $3+: Command options
    164 adb_var_shell_cmd ()
    165 {
    166     # We need a temporary file to store the output of our command
    167     local ADB_SHELL_CMD_LOG RET OUT
    168     local DEVICE=$1
    169     local VARNAME=$2
    170     shift; shift;
    171     ADB_SHELL_CMD_LOG=$(mktemp -t XXXXXXXX)
    172     # Run the command, while storing the standard output to ADB_SHELL_CMD_LOG
    173     # and appending the exit code as the last line.
    174     if [ $VERBOSE = "yes" ] ; then
    175         echo "$ADB_CMD -s \"$DEVICE\" shell \"$@\""
    176         $ADB_CMD -s "$DEVICE" shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' | tee $ADB_SHELL_CMD_LOG
    177     else
    178         $ADB_CMD -s "$DEVICE" shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $ADB_SHELL_CMD_LOG
    179     fi
    180     # Get last line in log, which contains the exit code from the command
    181     RET=`sed -e '$!d' $ADB_SHELL_CMD_LOG`
    182     # Get output, which corresponds to everything except the last line
    183     OUT=`sed -e '$d' $ADB_SHELL_CMD_LOG`
    184     rm -f $ADB_SHELL_CMD_LOG
    185     if [ "$VARNAME" != "" ]; then
    186         eval $VARNAME=\"\$OUT\"
    187     fi
    188     return $RET
    189 }
    190 
    191 # Make a directory path on device
    192 #
    193 # The 'mkdir' command on the Android device does not
    194 # support the '-p' option. This function will test
    195 # for the existence of the parent directory and recursively
    196 # call itself until it files a parent which exists; then
    197 # create the requested directory.
    198 adb_shell_mkdir ()
    199 {
    200     local FULLDIR BASEDIR
    201     local DEVICE=$1
    202     local FULLDIR=$2
    203     local BASEDIR=`dirname $FULLDIR`
    204 
    205     adb_var_shell_cmd "$DEVICE" "" "ls $BASEDIR 1>/dev/null 2>&1"
    206     if [ $? != 0 ] ; then
    207         if [ $BASEDIR = "/" ] ; then
    208             dump "ERROR: Could not find the root (/) directory on the device!"
    209             exit 1
    210         else
    211             adb_shell_mkdir "$DEVICE" $BASEDIR
    212             adb_shell_mkdir "$DEVICE" $FULLDIR
    213         fi
    214     else
    215         #If the directory doesn't exist, make it
    216         adb_var_shell_cmd "$DEVICE" "" "ls $FULLDIR 1>/dev/null 2>&1 || mkdir $FULLDIR"
    217         if [ $? != 0 ] ; then
    218             dump "ERROR: Could not mkdir '$FULLDIR' on the device!"
    219             exit 1
    220         fi
    221     fi
    222 }
    223 
    224 # Returns 0 if a variable containing one or more items separated
    225 # by spaces contains a given value.
    226 # $1: variable name (e.g. FOO)
    227 # $2: value to test
    228 var_list_contains ()
    229 {
    230     echo `var_value $1` | tr ' ' '\n' | grep -q -F -x -e "$2"
    231 }
    232 
    233 #
    234 # List of stuff to actually tests
    235 #
    236 is_testable () {
    237     var_list_contains TESTABLES "$1"
    238 }
    239 
    240 # is_buildable returns 0 if a test should be built/run for this invocation
    241 # $1: test path
    242 if [ -n "$RUN_TESTS" ] ; then
    243     is_buildable () {
    244         [ -f $1/build.sh -o -f $1/jni/Android.mk ] &&
    245         var_list_contains RUN_TESTS "`basename $1`"
    246     }
    247 elif [ "$FULL_TESTS" = "yes" ] ; then
    248     is_buildable () {
    249         [ -f $1/build.sh -o -f $1/jni/Android.mk ]
    250     }
    251 else # !FULL_TESTS
    252     is_buildable () {
    253         [ -f $1/build.sh -o -f $1/jni/Android.mk ] || return 1
    254         ! var_list_contains LONG_TESTS "`basename $1`" || return 1
    255     }
    256 fi # !FULL_TESTS
    257 
    258 
    259 TEST_DIR="/tmp/ndk-$USER/tests"
    260 mkdir -p $TEST_DIR
    261 setup_default_log_file "$TEST_DIR/build-tests.log"
    262 
    263 if [ -n "$NDK_PACKAGE" ] ; then
    264     if [ -n "$NDK_ROOT" ] ; then
    265         dump "ERROR: You can't use --ndk and --package at the same time!"
    266         exit 1
    267     fi
    268     NDK_ROOT=/tmp/ndk-tests/install
    269     mkdir -p  "$NDK_ROOT" && rm -rf "$NDK_ROOT/*"
    270     dump "Unpacking NDK package to $NDK_ROOT"
    271     unpack_archive "$NDK_PACKAGE" "$NDK_ROOT"
    272     NDK_ROOT=`ls -d $NDK_ROOT/*`
    273 fi
    274 
    275 #
    276 # Check the NDK install path.
    277 #
    278 if [ -n "$NDK_ROOT" ] ; then
    279     if [ ! -d "$NDK_ROOT" ] ; then
    280         dump "ERROR: Your --ndk option does not point to a directory: $NDK_ROOT"
    281         dump "Please use a valid path for this option."
    282         exit 1
    283     fi
    284     if [ ! -f "$NDK_ROOT/ndk-build" -o ! -f "$NDK_ROOT/build/core/ndk-common.sh" ] ; then
    285         dump "ERROR: Your --ndk option does not point to a valid NDK install: $NDK_ROOT"
    286         dump "Please use a valid NDK install path for this option."
    287         exit 3
    288     fi
    289     NDK="$NDK_ROOT"
    290 else
    291     NDK="$ROOTDIR"
    292 fi
    293 
    294 #
    295 # Create log file
    296 #
    297 
    298 BUILD_DIR=$TEST_DIR/build
    299 mkdir -p "$BUILD_DIR" && rm -rf "$BUILD_DIR/*"
    300 
    301 ###
    302 ### RUN AWK TESTS
    303 ###
    304 
    305 # Run a simple awk script
    306 # $1: awk script to run
    307 # $2: input file
    308 # $3: expected output file
    309 # $4+: optional additional command-line arguments for the awk command
    310 run_awk_test ()
    311 {
    312     local SCRIPT="$1"
    313     local SCRIPT_NAME="`basename $SCRIPT`"
    314     local INPUT="$2"
    315     local INPUT_NAME="`basename $INPUT`"
    316     local EXPECTED="$3"
    317     local EXPECTED_NAME="`basename $EXPECTED`"
    318     shift; shift; shift;
    319     local OUTPUT="$BUILD_DIR/$EXPECTED_NAME"
    320     if [ "$VERBOSE2" = "yes" ]; then
    321         echo "### COMMAND: awk -f \"$SCRIPT\" $@ < \"$INPUT\" > \"$OUTPUT\""
    322     fi
    323     awk -f "$SCRIPT" $@ < "$INPUT" > "$OUTPUT"
    324     fail_panic "Can't run awk script: $SCRIPT"
    325     if [ "$VERBOSE2" = "yes" ]; then
    326         echo "OUTPUT FROM SCRIPT:"
    327         cat "$OUTPUT"
    328         echo "EXPECTED VALUES:"
    329         cat "$EXPECTED"
    330     fi
    331     cmp -s "$OUTPUT" "$EXPECTED"
    332     if [ $? = 0 ] ; then
    333         echo "Awk script: $SCRIPT_NAME: passed $INPUT_NAME"
    334         if [ "$VERBOSE2" = "yes" ]; then
    335             cat "$OUTPUT"
    336         fi
    337     else
    338         if [ "$VERBOSE" = "yes" ]; then
    339             run diff -burN "$EXPECTED" "$OUTPUT"
    340         fi
    341         echo "Awk script: $SCRIPT_NAME: $INPUT_NAME FAILED!!"
    342         rm -f "$OUTPUT"
    343         exit 1
    344     fi
    345 }
    346 
    347 run_awk_test_dir ()
    348 {
    349     local SCRIPT_NAME="`basename \"$DIR\"`"
    350     local SCRIPT="$ROOTDIR/build/awk/$SCRIPT_NAME.awk"
    351     local INPUT
    352     local OUTPUT
    353     if [ ! -f "$SCRIPT" ]; then
    354         echo "Awk script: $SCRIPT_NAME: Missing script: $SCRIPT"
    355         continue
    356     fi
    357     for INPUT in `ls "$PROGDIR"/awk/$SCRIPT_NAME/*.in`; do
    358         OUTPUT=`echo $INPUT | sed 's/\.in$/.out/g'`
    359         if [ ! -f "$OUTPUT" ]; then
    360             echo "Awk script: $SCRIPT_NAME: Missing awk output file: $OUTPUT"
    361             continue
    362         fi
    363         run_awk_test "$SCRIPT" "$INPUT" "$OUTPUT"
    364     done
    365 }
    366 
    367 if is_testable awk; then
    368     AWKDIR="$ROOTDIR/build/awk"
    369     for DIR in `ls -d "$PROGDIR"/awk/*`; do
    370         run_awk_test_dir "$DIR"
    371     done
    372 fi
    373 
    374 ###
    375 ###  REBUILD ALL SAMPLES FIRST
    376 ###
    377 
    378 NDK_BUILD_FLAGS="-B"
    379 if [ "$WINE" ]; then
    380     case "$NDK_HOST_32BIT" in
    381         1|true)
    382             WINE=wine12
    383             ;;
    384         *)
    385             WINE=wine15
    386             NDK_BUILD_FLAGS=""  # make.exe -B hangs in wine > 1.2.x
    387             if [ "$NDK_TOOLCHAIN_VERSION" != "4.4.3" ] ; then
    388                 APP_LDFLAGS=-fuse-ld=bfd # 64-bit ld.gold can't run in any wine!
    389             fi
    390             ;;
    391     esac
    392     find_program WINE_PROG $WINE
    393     fail_panic "Can't locate $WINE"
    394 fi
    395 
    396 case $ABI in
    397     default)  # Let the APP_ABI in jni/Application.mk decide what to build
    398         ;;
    399     armeabi|armeabi-v7a|x86|mips)
    400         NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_ABI=$ABI"
    401         ;;
    402     *)
    403         echo "ERROR: Unsupported abi value: $ABI"
    404         exit 1
    405         ;;
    406 esac
    407 
    408 # Force all tests to run at one API level
    409 if [ "$PLATFORM" != "" ]; then
    410     NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS APP_PLATFORM=$PLATFORM"
    411 fi
    412 
    413 # Use --verbose twice to see build commands for the tests
    414 if [ "$VERBOSE2" = "yes" ] ; then
    415     NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS V=1"
    416 fi
    417 
    418 run_ndk_build ()
    419 {
    420     EXTRA_FLAGS=
    421     if [ -n "$APP_LDFLAGS" ] ; then
    422         # APP_LDFLAGS in env. var. doesn't work
    423         EXTRA_FLAGS="APP_LDFLAGS=$APP_LDFLAGS"
    424     fi
    425     if [ "$WINE" ]; then
    426         if [ "$WINE" = "wine12" ]; then
    427             run $WINE cmd /c Z:$NDK/ndk-build.cmd -j$JOBS "$@" $EXTRA_FLAGS
    428         else
    429             # do "clean" instead of -B
    430             run $WINE cmd /c Z:$NDK/ndk-build.cmd clean
    431             # make.exe can't do parallel build in wine > 1.2.x
    432             run $WINE cmd /c Z:$NDK/ndk-build.cmd "$@" -j1 $EXTRA_FLAGS
    433         fi
    434     else
    435         run $NDK/ndk-build -j$JOBS "$@" $EXTRA_FLAGS
    436     fi
    437 }
    438 
    439 # get build var
    440 # $1: project directory
    441 # $2: var
    442 get_build_var ()
    443 {
    444     local PROJECT=$1
    445     local VAR=$2
    446 
    447     if [ -z "$GNUMAKE" ] ; then
    448         GNUMAKE=make
    449     fi
    450     $GNUMAKE --no-print-dir -f $NDK/build/core/build-local.mk -C $PROJECT DUMP_$VAR | tail -1
    451 }
    452 
    453 
    454 # check if the project is broken and shouldn't be built
    455 # $1: project directory
    456 # $2: optional error message
    457 is_broken_build ()
    458 {
    459     local PROJECT="$1"
    460     local ERRMSG="$2"
    461 
    462     if [ -z $RUN_TESTS ] ; then
    463         if [ -f "$PROJECT/BROKEN_BUILD" ] ; then
    464             if [ ! -s "$PROJECT/BROKEN_BUILD" ] ; then
    465                 # skip all
    466                 if [ -z "$ERRMSG" ] ; then
    467                     echo "Skipping `basename $PROJECT`: (build)"
    468                 else
    469                     echo "Skipping $ERRMSG: `basename $PROJECT`"
    470                 fi
    471                 return 0
    472             else
    473                 # only skip listed in file
    474                 TARGET_TOOLCHAIN=`get_build_var $PROJECT TARGET_TOOLCHAIN`
    475                 TARGET_TOOLCHAIN_VERSION=`echo $TARGET_TOOLCHAIN | tr '-' '\n' | tail -1`
    476                 grep -q -e "$TARGET_TOOLCHAIN_VERSION" "$PROJECT/BROKEN_BUILD"
    477                 if [ $? = 0 ] ; then
    478                     if [ -z "$ERRMSG" ] ; then
    479                         echo "Skipping `basename $PROJECT`: (no build for $TARGET_TOOLCHAIN_VERSION)"
    480                     else
    481                         echo "Skipping $ERRMSG: `basename $PROJECT` (no build for $TARGET_TOOLCHAIN_VERSION)"
    482                     fi
    483                     return 0
    484                 fi
    485             fi
    486         fi
    487     fi
    488     return 1
    489 }
    490 
    491 # check if $ABI is incompatible and shouldn't be built
    492 # $1: project directory
    493 is_incompatible_abi ()
    494 {
    495     local PROJECT="$1"
    496 
    497     if [ "$ABI" != "default" ] ; then
    498         # check APP_ABI
    499         local APP_ABIS=`get_build_var $PROJECT APP_ABI`
    500         APP_ABIS=$APP_ABIS" "
    501         if [ "$APP_ABIS" != "${APP_ABIS%%all*}" ] ; then
    502         # replace the first "all" with all available ABIs
    503           ALL_ABIS=`get_build_var $PROJECT NDK_ALL_ABIS`
    504           APP_ABIS_FRONT="${APP_ABIS%%all*}"
    505           APP_ABIS_BACK="${APP_ABIS#*all}"
    506           APP_ABIS="${APP_ABIS_FRONT}${ALL_ABIS}${APP_ABIS_BACK}"
    507         fi
    508         if [ "$APP_ABIS" = "${APP_ABIS%$ABI *}" ] ; then
    509             echo "Skipping `basename $PROJECT`: incompatible ABI, needs $APP_ABIS"
    510             return 0
    511         fi
    512     fi
    513     return 1
    514 }
    515 
    516 build_project ()
    517 {
    518     local NAME=`basename $1`
    519     local CHECK_ABI=$2
    520     local DIR="$BUILD_DIR/$NAME"
    521 
    522     if is_broken_build $1; then
    523         return 0;
    524     fi
    525     if [ "$CHECK_ABI" = "yes" ] ; then
    526         if is_incompatible_abi $1 ; then
    527             return 0
    528         fi
    529     fi
    530     rm -rf "$DIR" && cp -r "$1" "$DIR"
    531     # build it
    532     (run cd "$DIR" && run_ndk_build $NDK_BUILD_FLAGS)
    533     RET=$?
    534     if [ -f "$1/BUILD_SHOULD_FAIL" ]; then
    535         if [ $RET = 0 ]; then
    536             echo "!!! FAILURE: BUILD SHOULD HAVE FAILED [$1]"
    537             if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then
    538                 exit 1
    539             fi
    540         fi
    541         log "!!! SUCCESS: BUILD FAILED AS EXPECTED [$(basename $1)]"
    542         RET=0
    543     fi
    544     if [ $RET != 0 ] ; then
    545         echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!"
    546         if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then
    547             exit 1
    548         fi
    549     fi
    550 }
    551 
    552 #
    553 # Determine list of samples directories.
    554 #
    555 if is_testable samples; then
    556     if [ -f "$NDK/RELEASE.TXT" ] ; then
    557         # This is a release package, all samples should be under $NDK/samples
    558         SAMPLES_DIRS="$NDK/samples"
    559         if [ ! -d "$SAMPLES_DIRS" ] ; then
    560             dump "ERROR: Missing samples directory: $SAMPLES_DIRS"
    561             dump "Your NDK release installation is broken!"
    562             exit 1
    563         fi
    564         log "Using release NDK samples from: $SAMPLES_DIRS"
    565     else
    566         # This is a development work directory, we will take the samples
    567         # directly from development/ndk.
    568         DEVNDK_DIR=`dirname $NDK`/development/ndk
    569         if [ ! -d "$DEVNDK_DIR" ] ; then
    570             dump "ERROR: Could not find development NDK directory: $DEVNDK_DIR"
    571             dump "Please clone platform/development.git from android.googlesource.com"
    572             exit 1
    573         fi
    574         SAMPLES_DIRS="$DEVNDK_DIR/samples"
    575         for DIR in `ls -d $DEVNDK_DIR/platforms/android-*/samples`; do
    576             SAMPLES_DIRS="$SAMPLES_DIRS $DIR"
    577         done
    578         dump "Using development NDK samples from $DEVNDK_DIR"
    579         if [ "$VERBOSE" = "yes" ] ; then
    580             echo "$SAMPLES_DIRS" | tr ' ' '\n'
    581         fi
    582     fi
    583 
    584     #
    585     # Copy the samples to a temporary build directory
    586 
    587     build_sample ()
    588     {
    589         echo "Building NDK sample: `basename $1`"
    590         build_project $1 "no"
    591     }
    592 
    593     for DIR in $SAMPLES_DIRS; do
    594         for SUBDIR in `ls -d $DIR/*`; do
    595             if is_buildable $SUBDIR; then
    596                 build_sample $SUBDIR
    597             fi
    598         done
    599     done
    600 fi
    601 
    602 ###
    603 ###  BUILD PROJECTS UNDER tests/build/
    604 ###
    605 
    606 if is_testable build; then
    607     build_build_test ()
    608     {
    609         local NAME="$(basename $1)"
    610         echo "Building NDK build test: `basename $1`"
    611         if [ -f $1/build.sh ]; then
    612             local DIR="$BUILD_DIR/$NAME"
    613             if [ -f "$1/jni/Android.mk" -a -f "$1/jni/Application.mk" ] ; then
    614                 # exclude jni/Android.mk with import-module because it needs NDK_MODULE_PATH
    615                 grep -q  "call import-module" "$1/jni/Android.mk"
    616                 if [ $? != 0 ] ; then
    617                     if (is_broken_build $1 || is_incompatible_abi $1) then
    618                         return 0;
    619                     fi
    620                 fi
    621             fi
    622             rm -rf "$DIR" && cp -r "$1" "$DIR"
    623             export NDK
    624             (cd "$DIR" && run ./build.sh -j$JOBS $NDK_BUILD_FLAGS)
    625             if [ $? != 0 ]; then
    626                 echo "!!! BUILD FAILURE [$1]!!! See $NDK_LOGFILE for details or use --verbose option!"
    627                 if [ "$CONTINUE_ON_BUILD_FAIL" != yes ] ; then
    628                     exit 1
    629                 fi
    630             fi
    631         else
    632             build_project $1 "yes"
    633         fi
    634     }
    635 
    636     for DIR in `ls -d $ROOTDIR/tests/build/*`; do
    637         if is_buildable $DIR; then
    638             build_build_test $DIR
    639         fi
    640     done
    641 fi
    642 
    643 ###
    644 ###  BUILD PROJECTS UNDER tests/device/
    645 ###
    646 
    647 CPU_ABIS=
    648 if is_testable device; then
    649     build_device_test ()
    650     {
    651         if is_broken_build $1 "broken device test build"; then
    652             return 0;
    653         fi
    654         echo "Building NDK device test: `basename $1`"
    655         build_project $1 "yes"
    656     }
    657 
    658     # $1: DEVICE
    659     # $2: DEVICE CPU ABI
    660     # $3: test
    661     # $4: tmp dir
    662     run_device_test ()
    663     {
    664         local DEVICE=$1
    665         local CPU_ABI=$2
    666         local TEST=$3
    667         local TEST_NAME="$(basename $TEST)"
    668         local SRCDIR
    669         local DSTDIR="$4/ndk-tests"
    670         local SRCFILE
    671         local DSTFILE
    672         local PROGRAM
    673         # Do not run the test if BROKEN_RUN is defined
    674         if [ -z "$RUN_TESTS" ]; then
    675             if is_broken_build $TEST "NDK device test not built"; then
    676                 return 0
    677             fi
    678             if [ -f "$TEST/BROKEN_RUN" ] ; then
    679                 if [ ! -s "$TEST/BROKEN_RUN" ] ; then
    680                     # skip all
    681                     dump "Skipping NDK device test run: $TEST_NAME"
    682                     return 0
    683                 else
    684                     # skip all tests built by toolchain
    685                     TARGET_TOOLCHAIN=`get_build_var $TEST TARGET_TOOLCHAIN`
    686                     TARGET_TOOLCHAIN_VERSION=`echo $TARGET_TOOLCHAIN | tr '-' '\n' | tail -1`
    687                     grep -q -e "$TARGET_TOOLCHAIN_VERSION" "$TEST/BROKEN_RUN"
    688                     if [ $? = 0 ] ; then
    689                         dump "Skipping NDK device test run: $TEST_NAME (no run for binary built by $TARGET_TOOLCHAIN_VERSION)"
    690                         return 0
    691                     fi
    692                     # skip tests listed in file
    693                     SKIPPED_EXECUTABLES=`cat $TEST/BROKEN_RUN | tr '\n' ' '`
    694                     dump "Skipping NDK device test run: $TEST_NAME ($SKIPPED_EXECUTABLES)"
    695                 fi
    696             fi
    697         fi
    698         SRCDIR="$BUILD_DIR/`basename $TEST`/libs/$CPU_ABI"
    699         if [ ! -d "$SRCDIR" ]; then
    700             dump "Skipping NDK device test run (no $CPU_ABI binaries): $TEST_NAME"
    701             return 0
    702         fi
    703         # First, copy all files to the device, except for gdbserver, gdb.setup, and
    704         # those declared in $TEST/BROKEN_RUN
    705         adb_shell_mkdir "$DEVICE" $DSTDIR
    706 
    707         for SRCFILE in `ls $SRCDIR`; do
    708             DSTFILE=`basename $SRCFILE`
    709             echo "$DSTFILE" | grep -q -e '\.so$'
    710             if [ $? != 0 ] ; then
    711                 continue
    712             fi
    713             SRCFILE="$SRCDIR/$SRCFILE"
    714             if [ $HOST_OS = cygwin ]; then
    715                 SRCFILE=`cygpath -m $SRCFILE`
    716             fi
    717             DSTFILE="$DSTDIR/$DSTFILE"
    718             run $ADB_CMD -s "$DEVICE" push "$SRCFILE" "$DSTFILE" &&
    719             run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTFILE
    720             if [ $? != 0 ] ; then
    721                 dump "ERROR: Could not install $SRCFILE to device $DEVICE!"
    722                 exit 1
    723             fi
    724         done
    725 
    726         for SRCFILE in `ls $SRCDIR`; do
    727             DSTFILE=`basename $SRCFILE`
    728             if [ "$DSTFILE" = "gdbserver" -o "$DSTFILE" = "gdb.setup" ] ; then
    729                 continue
    730             fi
    731             echo "$DSTFILE" | grep -q -e '\.so$'
    732             if [ $? = 0 ] ; then
    733               continue
    734             fi
    735             if [ -z "$RUN_TESTS" -a -f "$TEST/BROKEN_RUN" ]; then
    736                 grep -q -w -e "$DSTFILE" "$TEST/BROKEN_RUN"
    737                 if [ $? = 0 ] ; then
    738                     continue
    739                 fi
    740             fi
    741             SRCFILE="$SRCDIR/$SRCFILE"
    742             if [ $HOST_OS = cygwin ]; then
    743                 SRCFILE=`cygpath -m $SRCFILE`
    744             fi
    745             DSTFILE="$DSTDIR/$DSTFILE"
    746             run $ADB_CMD -s "$DEVICE" push "$SRCFILE" "$DSTFILE" &&
    747             run $ADB_CMD -s "$DEVICE" shell chmod 0755 $DSTFILE
    748             if [ $? != 0 ] ; then
    749                 dump "ERROR: Could not install $SRCFILE to device $DEVICE!"
    750                 exit 1
    751             fi
    752             PROGRAM="`basename $DSTFILE`"
    753             dump "Running device test [$CPU_ABI]: $TEST_NAME (`basename $PROGRAM`)"
    754             adb_var_shell_cmd "$DEVICE" "" "cd $DSTDIR && LD_LIBRARY_PATH=$DSTDIR ./$PROGRAM"
    755             if [ $? != 0 ] ; then
    756                 dump "   ---> TEST FAILED!!"
    757             fi
    758         done
    759         # Cleanup
    760         adb_var_shell_cmd "$DEVICE" "" rm -r $DSTDIR
    761     }
    762 
    763     for DIR in `ls -d $ROOTDIR/tests/device/*`; do
    764         if is_buildable $DIR; then
    765             build_device_test $DIR
    766         fi
    767     done
    768 
    769     # Do we have adb and any device connected here?
    770     # If not, we can't run our tests.
    771     #
    772     SKIP_TESTS=no
    773     if [ -z "$ADB_CMD" ] ; then
    774         dump "WARNING: No 'adb' in your path!"
    775         SKIP_TESTS=yes
    776     else
    777         # Get list of online devices, turn ' ' in device into '.'
    778         ADB_DEVICES=`$ADB_CMD devices | grep -v offline | awk 'NR>1 {gsub(/[ \t]+device$/,""); print;}' | sed '/^$/d' | sort | tr ' ' '.'`
    779         ADB_DEVICES=$(echo $ADB_DEVICES | tr '\n' ' ')
    780         log2 "ADB online devices (sorted): $ADB_DEVICES"
    781         ADB_DEVCOUNT=`echo "$ADB_DEVICES" | wc -w`
    782         if [ "$ADB_DEVCOUNT" = "0" ]; then
    783             dump "WARNING: No device connected to adb!"
    784             SKIP_TESTS=yes
    785         else
    786             ADB_DEVICES="$ADB_DEVICES "
    787             if [ -n "$ANDROID_SERIAL" ] ; then
    788                 ADB_SERIAL=$(echo "$ANDROID_SERIAL" | tr ' ' '.')  # turn ' ' into '.'
    789                 if [ "$ADB_DEVICES" = "${ADB_DEVICES%$ADB_SERIAL *}" ] ; then
    790                     dump "WARNING: Device $ANDROID_SERIAL cannot be found or offline!"
    791                     SKIP_TESTS=yes
    792                 else
    793                     ADB_DEVICES="$ANDROID_SERIAL"
    794                 fi
    795             fi
    796         fi
    797     fi
    798     if [ "$SKIP_TESTS" = "yes" ] ; then
    799         dump "SKIPPING RUNNING TESTS ON DEVICE!"
    800     else
    801         AT_LEAST_CPU_ABI_MATCH=
    802         for DEVICE in $ADB_DEVICES; do
    803             # undo earlier ' '-to-'.' translation
    804             DEVICE=$(echo $DEVICE | tr '.' ' ')
    805             # get device CPU_ABI and CPU_ABI2, each may contain list of abi, comma-delimited.
    806             adb_var_shell_cmd "$DEVICE" CPU_ABI1 getprop ro.product.cpu.abi
    807             adb_var_shell_cmd "$DEVICE" CPU_ABI2 getprop ro.product.cpu.abi2
    808             CPU_ABIS="$CPU_ABI1,$CPU_ABI2"
    809             CPU_ABIS=$(commas_to_spaces $CPU_ABIS)
    810             if [ "$CPU_ABIS" = " " ]; then
    811               # Very old cupcake-based Android devices don't have these properties
    812               # defined. Fortunately, they are all armeabi-based.
    813               CPU_ABIS=armeabi
    814             fi
    815             for CPU_ABI in $CPU_ABIS; do
    816                 if [ "$ABI" = "default" -o "$ABI" = "$CPU_ABI" ] ; then
    817                     AT_LEAST_CPU_ABI_MATCH="yes"
    818                     for DIR in `ls -d $ROOTDIR/tests/device/*`; do
    819                         if is_buildable $DIR; then
    820                             log "Running device test on $DEVICE [$CPU_ABI]: $DIR"
    821                             run_device_test "$DEVICE" "$CPU_ABI" "$DIR" /data/local/tmp
    822                         fi
    823                     done
    824                 fi
    825             done
    826         done
    827         if [ "$AT_LEAST_CPU_ABI_MATCH" != "yes" ] ; then
    828             dump "WARNING: No device matches ABI $ABI! SKIPPING RUNNING TESTS ON DEVICE!"
    829         fi
    830     fi
    831 fi
    832 
    833 dump "Cleaning up..."
    834 rm -rf $BUILD_DIR
    835 dump "Done."
    836