Merge pull request #10776 from sdmaclea/PR-ARM64-CpBlkUnroll
[platform/upstream/coreclr.git] / tests / runparallel.sh
1 #!/usr/bin/env bash
2
3 function print_usage {
4     echo ''
5     echo 'CoreCLR parallel test runner script.'
6     echo ''
7     echo 'Required arguments:'
8     echo '  --testRootDir=<path>             : Root directory of the test build (e.g. coreclr/bin/tests/Windows_NT.x64.Debug).'
9     echo '  --coreOverlayDir=<path>          : Directory containing core binaries and test dependencies. If not specified, the'
10     echo '                                     default is testRootDir/Tests/coreoverlay. This switch overrides --coreClrBinDir,'
11     echo '                                     --mscorlibDir, --coreFxBinDir, and --coreFxNativeBinDir.'
12     echo '  --playlist=<path>                : Run only the tests that are specified in the file at <path>, in the same format as'
13     echo ''
14     echo 'Optional arguments:'
15     echo '  -h|--help                        : Show usage information.'
16     echo '  --test-env                       : Script to set environment variables for tests'
17     echo ''
18 }
19
20 function print_results {
21     echo -e \
22        "Results @ $(date +%r)\n\t"\
23        "Pass:$countPassedTests\t"\
24        "Fail:$countFailedTests\n\t"\
25        "Finish:$countFinishedTests\t"\
26        "Incomplete: $countIncompleteTests\n\t"\
27        "Total: $countTotalTests"
28 }
29
30 function update_results {
31     # Initialize counters for bookkeeping.
32     countTotalTests=$(wc -l < $playlistFile)
33
34     countFinishedTests=$(cd results.int; grep -r 'RUN_TEST_EXIT_CODE' . | wc -l)
35     countPassedTests=$(cd results.int; grep -r 'RUN_TEST_EXIT_CODE=0' . | wc -l)
36     countFailedTests=$((countFinishedTests - countPassedTests))
37     countIncompleteTests=$((countTotalTests - countFinishedTests))
38
39     print_results
40 }
41
42 function print_elapsed_time {
43     time_end=$(date +"%s")
44     time_diff=$(($time_end-$time_start))
45     echo "$(($time_diff / 60)) minutes and $(($time_diff % 60)) seconds taken to run CoreCLR tests."
46 }
47
48
49
50 # Handle Ctrl-C. We will stop execution and print the results that
51 # we gathered so far.
52 function handle_ctrl_c {
53     local errorSource='handle_ctrl_c'
54
55     echo ""
56     echo "*** Stopping... ***"
57
58     update_results
59     echo "$errorSource" "Test run aborted by Ctrl+C."
60
61     print_elapsed_time
62
63     exit 1
64 }
65
66 function cleanup
67 {
68     kill -TERM % >/dev/null
69     mv results.int results.$(date +%F_%I%M%p)
70 }
71
72
73 prep_test() {
74     # This function runs in a background process. It should not echo anything, and should not use global variables.
75
76     #remove any NI
77     rm -f $(dirname "$1")/*.ni.*
78 }
79
80 run_test() {
81     # This function runs in a background process. It should not echo anything, and should not use global variables.
82
83     local scriptFilePath=$1
84
85     local scriptFileName=$(basename "$scriptFilePath")
86     local outputFileName=$PWD/results.int/${scriptFilePath////.}
87
88     nice "$scriptFilePath" -debug=$(which time) >"$outputFileName" 2>&1
89
90     echo RUN_TEST_EXIT_CODE="$?" >>"$outputFileName"
91 }
92
93 # Argument variables
94 testRootDir=
95 coreOverlayDir=
96 testEnv=
97 playlistFile=
98
99 for i in "$@"
100 do
101     case $i in
102         -h|--help)
103             print_usage
104             exit $EXIT_CODE_SUCCESS
105             ;;
106         --coreOverlayDir=*)# Exit code constants
107             coreOverlayDir=${i#*=}
108             ;;
109         --playlist=*)
110             playlistFile=${i#*=}
111             ;;
112         --testRootDir=*)
113             testRootDir=${i#*=}
114             ;;
115         --test-env=*)
116             testEnv=${i#*=}
117             ;;
118         *)
119             echo "Unknown switch: $i"
120             print_usage
121             exit $EXIT_CODE_SUCCESS
122             ;;
123     esac
124 done
125
126 if [ -z "$coreOverlayDir" ]; then
127     echo "--coreOverlayDir is required."
128     print_usage
129     exit $EXIT_CODE_EXCEPTION
130 fi
131
132 if [ ! -d "$coreOverlayDir" ]; then
133     echo "Directory specified by --coreOverlayDir does not exist: $coreOverlayDir"
134     exit $EXIT_CODE_EXCEPTION
135 fi
136
137 if [ -z "$playlistFile" ]; then
138     echo "--playlist is required."
139     print_usage
140     exit $EXIT_CODE_EXCEPTION
141 fi
142
143 if [ ! -e "$playlistFile" ]; then
144     echo "File specified by --playlist does not exist: $playlistFile"
145     exit $EXIT_CODE_EXCEPTION
146 fi
147
148 if [ -z "$testRootDir" ]; then
149     echo "--testRootDir is required."
150     print_usage
151     exit $EXIT_CODE_EXCEPTION
152 fi
153
154 if [ ! -d "$testRootDir" ]; then
155     echo "Directory specified by --testRootDir does not exist: $testRootDir"
156     exit $EXIT_CODE_EXCEPTION
157 fi
158
159 if [ ! -z "$testEnv" ] && [ ! -e "$testEnv" ]; then
160     echo "File specified by --playlist does not exist: $testEnv"
161     exit $EXIT_CODE_EXCEPTION
162 fi
163
164 export CORE_ROOT="$coreOverlayDir"
165 export __TestEnv=$testEnv
166
167
168 # Variables for running tests in the background
169 if [ `uname` = "NetBSD" ]; then
170     NumProc=$(getconf NPROCESSORS_ONLN)
171 else
172     NumProc=$(getconf _NPROCESSORS_ONLN)
173 fi
174
175 export TIME='<Command time="%U %S %e" mem="%M %t %K" swap="%W %c %w" fault="%F %R %k %r %s" IO="%I %O" exit="%x"/>'
176
177 export -f prep_test
178 export -f run_test
179
180 cd $testRootDir
181 time_start=$(date +"%s")
182
183 rm -rf results.int/* results.int
184
185 echo "Prepping tests $(date +%r)"
186 xargs -d "\n" -P $NumProc -I{} bash -c prep_test  {} < $playlistFile
187
188
189 trap cleanup EXIT
190 mkdir results.int
191 echo $$ > results.int/pid
192 cp $testEnv results.int
193
194 trap handle_ctrl_c INT TERM
195
196 xargs -d "\n" -P $NumProc -I{} bash -c 'run_test "{}" >/dev/null 2>&1' < $playlistFile &
197
198 while true
199 do
200     update_results
201     sleep 20 &
202     wait -n %
203     if (( $(jobs %xargs 2>/dev/null | wc -l) == 0 )) ;
204     then
205         break
206     fi
207
208     jobs -p > /dev/null
209 done
210
211 update_results
212
213 print_elapsed_time