Home | History | Annotate | Download | only in tests
      1 #!/bin/bash
      2 #
      3 # Copyright (C) 2007 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 # Set up prog to be the path of this script, including following symlinks,
     18 # and set up progdir to be the fully-qualified pathname of its directory.
     19 prog="$0"
     20 while [ -h "${prog}" ]; do
     21     newProg=`/bin/ls -ld "${prog}"`
     22     newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
     23     if expr "x${newProg}" : 'x/' >/dev/null; then
     24         prog="${newProg}"
     25     else
     26         progdir=`dirname "${prog}"`
     27         prog="${progdir}/${newProg}"
     28     fi
     29 done
     30 oldwd=`pwd`
     31 progdir=`dirname "${prog}"`
     32 cd "${progdir}"
     33 progdir=`pwd`
     34 prog="${progdir}"/`basename "${prog}"`
     35 
     36 skip_tests=""
     37 
     38 # Command-line options
     39 sequential="no"
     40 usage="no"
     41 while [[ "$1" == "-"* ]]; do
     42   case $1 in
     43     --seq) sequential="yes" ;;
     44     --skip) skip_tests="$2 $skip_tests"
     45             shift ;;
     46     *) usage="yes" ;;
     47   esac
     48   shift
     49 done
     50 
     51 if [ $usage = "yes" ]; then
     52     prog=`basename $prog`
     53     cat 1>&2 <<END_USAGE
     54 Usage:
     55   $prog [options]   Run all tests with given options.
     56 Options:
     57   --seq             Run tests sequentially (default: parallel)
     58   --skip <test>     Skip running specified test
     59 END_USAGE
     60     exit 1
     61 fi
     62 
     63 # Globals for tracking numbers of successes and failures and their names.
     64 passed=()
     65 surprised=()
     66 ignored=()
     67 failed=()
     68 skipped=()
     69 
     70 # Tests failing and require attention (e.g. 115-merge)
     71 known_bad="100-local-mismatch 115-merge 119-merge-conflict"
     72 
     73 function display_results {
     74   printf    "\n\nTest Results\n"
     75   printf -- "----------------------------\n"
     76   printf    "Pass:                   % 4d\n" ${#passed[@]}
     77   printf    "Surprise pass:          % 4d\n" ${#surprised[@]}
     78   printf    "Known failures:         % 4d\n" ${#ignored[@]}
     79   printf    "Failures:               % 4d\n" ${#failed[@]}
     80   printf    "Skipped:                % 4d\n" ${#skipped[@]}
     81   printf -- "----------------------------\n"
     82   printf    "Elapsed time(s):        % 4d\n" $SECONDS
     83 
     84   list_files "Unexpected successes" ${surprised[@]}
     85   list_files "Known failures" ${ignored[@]}
     86   list_files "Failures" ${failed[@]}
     87   list_files "Skipped" ${skipped[@]}
     88 
     89   needing_attention=$(( ${#failed[@]} + ${#surprised[@]} ))
     90   exit ${needing_attention}
     91 }
     92 
     93 function list_files {
     94   # Arguments: Title test_name0 test_name1 ... test_nameN
     95   echo "$1:"
     96   shift
     97   if [[ "$1" = "" ]]; then
     98     echo "  NONE"
     99     return
    100   fi
    101   while [[ "$1" != "" ]]; do
    102     echo "  $1"
    103     shift
    104   done
    105 }
    106 
    107 function update_result {
    108   local -r test_name=$1
    109   local -r output=$2
    110   local -r result=$3
    111   local expectFail
    112 
    113   if [[ "$known_bad" == *"$test_name"* ]]; then
    114     expectFail=1
    115   else
    116     expectFail=0
    117   fi
    118   if [ $result = 0 ]; then
    119     if [[ $expectFail = 0 ]]; then
    120       passed+=(${test_name})
    121     else
    122       echo "Failing on unexpected success of $test_name"
    123       surprised+=(${test_name})
    124     fi
    125   else
    126     if [[ $expectFail = 0 ]]; then
    127       failed+=(${test_name})
    128     else
    129       echo "Ignoring expected failure of $test_name"
    130       ignored+=(${test_name})
    131       # Clean up when we expect a test to fail.
    132       # run-test only does this on success.
    133       rm -rf "$output"
    134     fi
    135   fi
    136 }
    137 
    138 function run_one_test_with_flock {
    139   local -r output_dir=$1
    140   local -r test_name=$2
    141   local -r lock_file=$3
    142 
    143   # Wait for the lock and run the test when acquired
    144   flock "${lock_file}" ./run-test --output_dir "${output_dir}" "${test_name}"
    145 }
    146 
    147 function run_tests {
    148   readonly test_root=$(mktemp -d)
    149   trap "rm -rf ${test_root}" EXIT
    150   if [[ "$sequential" = "yes" ]]; then
    151     for test_name in *; do
    152       if [[ "$skip_tests" = *"$test_name"* ]]; then
    153         skipped+=(${test_name})
    154         continue
    155       fi
    156       if [ -d "$test_name" -a -r "$test_name" ]; then
    157         output="${test_root}/${test_name}"
    158         ./run-test --output_dir "${output}" "${test_name}"
    159         update_result "${test_name}" "${output}" $?
    160       fi
    161     done
    162   else
    163     readonly num_workers=4
    164     local i=0
    165     for test_name in *; do
    166       if [[ "$skip_tests" = *"$test_name"* ]]; then
    167         skipped+=(${test_name})
    168         continue
    169       fi
    170       local lock_file=${test_root}/lock.$((i % num_workers))
    171       if [ -d "${test_name}" -a -r "${test_name}" ]; then
    172         output="${test_root}/${test_name}"
    173         run_one_test_with_flock "$output" "$test_name" "$lock_file" &
    174         test_pids[i]=$!
    175         test_names[test_pids[i]]="$test_name"
    176         test_outputs[test_pids[i]]="output"
    177         let i+=1
    178       fi
    179     done
    180 
    181     for pid in ${test_pids[@]}; do
    182       wait $pid
    183       update_result ${test_names[$pid]} ${test_outputs[$pid]} $?
    184     done
    185   fi
    186 }
    187 
    188 function handle_interrupt {
    189   trap INT
    190   display_results
    191   if [ ! -z "${test_pids}" ]; then
    192     killall ${test_pids}
    193   fi
    194 }
    195 
    196 trap handle_interrupt INT
    197 run_tests
    198 display_results
    199