xref: /aosp_15_r20/dalvik/dx/tests/run-all-tests (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui#!/bin/bash
2*055d4590SKeyi Gui#
3*055d4590SKeyi Gui# Copyright (C) 2007 The Android Open Source Project
4*055d4590SKeyi Gui#
5*055d4590SKeyi Gui# Licensed under the Apache License, Version 2.0 (the "License");
6*055d4590SKeyi Gui# you may not use this file except in compliance with the License.
7*055d4590SKeyi Gui# You may obtain a copy of the License at
8*055d4590SKeyi Gui#
9*055d4590SKeyi Gui#     http://www.apache.org/licenses/LICENSE-2.0
10*055d4590SKeyi Gui#
11*055d4590SKeyi Gui# Unless required by applicable law or agreed to in writing, software
12*055d4590SKeyi Gui# distributed under the License is distributed on an "AS IS" BASIS,
13*055d4590SKeyi Gui# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*055d4590SKeyi Gui# See the License for the specific language governing permissions and
15*055d4590SKeyi Gui# limitations under the License.
16*055d4590SKeyi Gui
17*055d4590SKeyi Gui# Set up prog to be the path of this script, including following symlinks,
18*055d4590SKeyi Gui# and set up progdir to be the fully-qualified pathname of its directory.
19*055d4590SKeyi Guiprog="$0"
20*055d4590SKeyi Guiwhile [ -h "${prog}" ]; do
21*055d4590SKeyi Gui    newProg=`/bin/ls -ld "${prog}"`
22*055d4590SKeyi Gui    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
23*055d4590SKeyi Gui    if expr "x${newProg}" : 'x/' >/dev/null; then
24*055d4590SKeyi Gui        prog="${newProg}"
25*055d4590SKeyi Gui    else
26*055d4590SKeyi Gui        progdir=`dirname "${prog}"`
27*055d4590SKeyi Gui        prog="${progdir}/${newProg}"
28*055d4590SKeyi Gui    fi
29*055d4590SKeyi Guidone
30*055d4590SKeyi Guioldwd=`pwd`
31*055d4590SKeyi Guiprogdir=`dirname "${prog}"`
32*055d4590SKeyi Guicd "${progdir}"
33*055d4590SKeyi Guiprogdir=`pwd`
34*055d4590SKeyi Guiprog="${progdir}"/`basename "${prog}"`
35*055d4590SKeyi Gui
36*055d4590SKeyi Guiskip_tests="115-merge 127-merge-stress 129-numthread-deterministic 130-numthread-multidex-deterministic 143-interface-methods"
37*055d4590SKeyi Gui
38*055d4590SKeyi Gui# Command-line options
39*055d4590SKeyi Guisequential="no"
40*055d4590SKeyi Guiusage="no"
41*055d4590SKeyi Guiwhile [[ "$1" == "-"* ]]; do
42*055d4590SKeyi Gui  case $1 in
43*055d4590SKeyi Gui    --seq) sequential="yes" ;;
44*055d4590SKeyi Gui    --skip) skip_tests="$2 $skip_tests"
45*055d4590SKeyi Gui            shift ;;
46*055d4590SKeyi Gui    *) usage="yes" ;;
47*055d4590SKeyi Gui  esac
48*055d4590SKeyi Gui  shift
49*055d4590SKeyi Guidone
50*055d4590SKeyi Gui
51*055d4590SKeyi Guiif [ $usage = "yes" ]; then
52*055d4590SKeyi Gui    prog=`basename $prog`
53*055d4590SKeyi Gui    cat 1>&2 <<END_USAGE
54*055d4590SKeyi GuiUsage:
55*055d4590SKeyi Gui  $prog [options]   Run all tests with given options.
56*055d4590SKeyi GuiOptions:
57*055d4590SKeyi Gui  --seq             Run tests sequentially (default: parallel)
58*055d4590SKeyi Gui  --skip <test>     Skip running specified test
59*055d4590SKeyi GuiEND_USAGE
60*055d4590SKeyi Gui    exit 1
61*055d4590SKeyi Guifi
62*055d4590SKeyi Gui
63*055d4590SKeyi Gui# Globals for tracking numbers of successes and failures and their names.
64*055d4590SKeyi Guipassed=()
65*055d4590SKeyi Guisurprised=()
66*055d4590SKeyi Guiignored=()
67*055d4590SKeyi Guifailed=()
68*055d4590SKeyi Guiskipped=()
69*055d4590SKeyi Gui
70*055d4590SKeyi Gui# Tests failing and require attention (e.g. 115-merge)
71*055d4590SKeyi Guiknown_bad="100-local-mismatch 115-merge 119-merge-conflict"
72*055d4590SKeyi Gui
73*055d4590SKeyi Guifunction display_results {
74*055d4590SKeyi Gui  printf    "\n\nTest Results\n"
75*055d4590SKeyi Gui  printf -- "----------------------------\n"
76*055d4590SKeyi Gui  printf    "Pass:                   % 4d\n" ${#passed[@]}
77*055d4590SKeyi Gui  printf    "Surprise pass:          % 4d\n" ${#surprised[@]}
78*055d4590SKeyi Gui  printf    "Known failures:         % 4d\n" ${#ignored[@]}
79*055d4590SKeyi Gui  printf    "Failures:               % 4d\n" ${#failed[@]}
80*055d4590SKeyi Gui  printf    "Skipped:                % 4d\n" ${#skipped[@]}
81*055d4590SKeyi Gui  printf -- "----------------------------\n"
82*055d4590SKeyi Gui  printf    "Elapsed time(s):        % 4d\n" $SECONDS
83*055d4590SKeyi Gui
84*055d4590SKeyi Gui  list_files "Unexpected successes" ${surprised[@]}
85*055d4590SKeyi Gui  list_files "Known failures" ${ignored[@]}
86*055d4590SKeyi Gui  list_files "Failures" ${failed[@]}
87*055d4590SKeyi Gui  list_files "Skipped" ${skipped[@]}
88*055d4590SKeyi Gui
89*055d4590SKeyi Gui  needing_attention=$(( ${#failed[@]} + ${#surprised[@]} ))
90*055d4590SKeyi Gui  exit ${needing_attention}
91*055d4590SKeyi Gui}
92*055d4590SKeyi Gui
93*055d4590SKeyi Guifunction list_files {
94*055d4590SKeyi Gui  # Arguments: Title test_name0 test_name1 ... test_nameN
95*055d4590SKeyi Gui  echo "$1:"
96*055d4590SKeyi Gui  shift
97*055d4590SKeyi Gui  if [[ "$1" = "" ]]; then
98*055d4590SKeyi Gui    echo "  NONE"
99*055d4590SKeyi Gui    return
100*055d4590SKeyi Gui  fi
101*055d4590SKeyi Gui  while [[ "$1" != "" ]]; do
102*055d4590SKeyi Gui    echo "  $1"
103*055d4590SKeyi Gui    shift
104*055d4590SKeyi Gui  done
105*055d4590SKeyi Gui}
106*055d4590SKeyi Gui
107*055d4590SKeyi Guifunction update_result {
108*055d4590SKeyi Gui  local -r test_name=$1
109*055d4590SKeyi Gui  local -r output=$2
110*055d4590SKeyi Gui  local -r result=$3
111*055d4590SKeyi Gui  local expectFail
112*055d4590SKeyi Gui
113*055d4590SKeyi Gui  if [[ "$known_bad" == *"$test_name"* ]]; then
114*055d4590SKeyi Gui    expectFail=1
115*055d4590SKeyi Gui  else
116*055d4590SKeyi Gui    expectFail=0
117*055d4590SKeyi Gui  fi
118*055d4590SKeyi Gui  if [ $result = 0 ]; then
119*055d4590SKeyi Gui    if [[ $expectFail = 0 ]]; then
120*055d4590SKeyi Gui      passed+=(${test_name})
121*055d4590SKeyi Gui    else
122*055d4590SKeyi Gui      echo "Failing on unexpected success of $test_name"
123*055d4590SKeyi Gui      surprised+=(${test_name})
124*055d4590SKeyi Gui    fi
125*055d4590SKeyi Gui  else
126*055d4590SKeyi Gui    if [[ $expectFail = 0 ]]; then
127*055d4590SKeyi Gui      failed+=(${test_name})
128*055d4590SKeyi Gui    else
129*055d4590SKeyi Gui      echo "Ignoring expected failure of $test_name"
130*055d4590SKeyi Gui      ignored+=(${test_name})
131*055d4590SKeyi Gui      # Clean up when we expect a test to fail.
132*055d4590SKeyi Gui      # run-test only does this on success.
133*055d4590SKeyi Gui      rm -rf "$output"
134*055d4590SKeyi Gui    fi
135*055d4590SKeyi Gui  fi
136*055d4590SKeyi Gui}
137*055d4590SKeyi Gui
138*055d4590SKeyi Guifunction run_one_test_with_flock {
139*055d4590SKeyi Gui  local -r output_dir=$1
140*055d4590SKeyi Gui  local -r test_name=$2
141*055d4590SKeyi Gui  local -r lock_file=$3
142*055d4590SKeyi Gui
143*055d4590SKeyi Gui  # Wait for the lock and run the test when acquired
144*055d4590SKeyi Gui  flock "${lock_file}" ./run-test --output_dir "${output_dir}" "${test_name}"
145*055d4590SKeyi Gui}
146*055d4590SKeyi Gui
147*055d4590SKeyi Guifunction run_tests {
148*055d4590SKeyi Gui  readonly test_root=$(mktemp -d)
149*055d4590SKeyi Gui  trap "rm -rf ${test_root}" EXIT
150*055d4590SKeyi Gui  if [[ "$sequential" = "yes" ]]; then
151*055d4590SKeyi Gui    for test_name in *; do
152*055d4590SKeyi Gui      if [[ "$skip_tests" = *"$test_name"* ]]; then
153*055d4590SKeyi Gui        skipped+=(${test_name})
154*055d4590SKeyi Gui        continue
155*055d4590SKeyi Gui      fi
156*055d4590SKeyi Gui      if [ -d "$test_name" -a -r "$test_name" ]; then
157*055d4590SKeyi Gui        output="${test_root}/${test_name}"
158*055d4590SKeyi Gui        ./run-test --output_dir "${output}" "${test_name}"
159*055d4590SKeyi Gui        update_result "${test_name}" "${output}" $?
160*055d4590SKeyi Gui      fi
161*055d4590SKeyi Gui    done
162*055d4590SKeyi Gui  else
163*055d4590SKeyi Gui    readonly num_workers=4
164*055d4590SKeyi Gui    local i=0
165*055d4590SKeyi Gui    for test_name in *; do
166*055d4590SKeyi Gui      if [[ "$skip_tests" = *"$test_name"* ]]; then
167*055d4590SKeyi Gui        skipped+=(${test_name})
168*055d4590SKeyi Gui        continue
169*055d4590SKeyi Gui      fi
170*055d4590SKeyi Gui      local lock_file=${test_root}/lock.$((i % num_workers))
171*055d4590SKeyi Gui      if [ -d "${test_name}" -a -r "${test_name}" ]; then
172*055d4590SKeyi Gui        output="${test_root}/${test_name}"
173*055d4590SKeyi Gui        run_one_test_with_flock "$output" "$test_name" "$lock_file" &
174*055d4590SKeyi Gui        test_pids[i]=$!
175*055d4590SKeyi Gui        test_names[test_pids[i]]="$test_name"
176*055d4590SKeyi Gui        test_outputs[test_pids[i]]="output"
177*055d4590SKeyi Gui        let i+=1
178*055d4590SKeyi Gui      fi
179*055d4590SKeyi Gui    done
180*055d4590SKeyi Gui
181*055d4590SKeyi Gui    for pid in ${test_pids[@]}; do
182*055d4590SKeyi Gui      wait $pid
183*055d4590SKeyi Gui      update_result ${test_names[$pid]} ${test_outputs[$pid]} $?
184*055d4590SKeyi Gui    done
185*055d4590SKeyi Gui  fi
186*055d4590SKeyi Gui}
187*055d4590SKeyi Gui
188*055d4590SKeyi Guifunction handle_interrupt {
189*055d4590SKeyi Gui  trap INT
190*055d4590SKeyi Gui  display_results
191*055d4590SKeyi Gui  if [ ! -z "${test_pids}" ]; then
192*055d4590SKeyi Gui    killall ${test_pids}
193*055d4590SKeyi Gui  fi
194*055d4590SKeyi Gui}
195*055d4590SKeyi Gui
196*055d4590SKeyi Guitrap handle_interrupt INT
197*055d4590SKeyi Guirun_tests
198*055d4590SKeyi Guidisplay_results
199