[Tizen] Fix module setup in mcj-edit for generic args and fnptr args
[platform/upstream/dotnet/runtime.git] / runtest_fx.sh
1 #!/usr/bin/env bash
2
3 function print_usage {
4     echo ''
5     echo 'CoreFX test runner script.'
6     echo ''
7     echo 'Typical Tizen command:'
8     echo '    corefx/runtest.sh'
9     echo '    --testRootDir="/opt/usr/corefx-tc/tests"'
10     echo '    --coreOverlayDir="/opt/usr/corefx-tc/coreroot"'
11     echo '    --outerloop=on/off'
12     echo '    --netcoreDir="/usr/share/dotnet.tizen/netcoreapp"'
13     echo '    --copy-netcore-to-coreroot'
14     echo '    --outputDir="/opt/usr/corefx-tc/results"'
15     echo '    --tmpDir="/opt/usr/corefx-tc/tmp"'
16     echo ''
17     echo 'Required arguments:'
18     echo '  --testRootDir=<path>             : Root directory of the test build (default: /opt/usr/corefx-tc/tests).'
19     echo '  --coreOverlayDir=<path>          : Directory containing CLR and FX (default: /opt/usr/corefx-tc/coreroot).'
20     echo "  --outerloop=<value>              : OuterLoop category: on/off"
21     echo ''
22     echo 'Optional arguments:'
23     echo '  --netcoreDir=<path>              : Netcore (CLR and FX) system dir (default: /usr/share/dotnet.tizen/netcoreapp).'
24     echo '  --copy-netcore-to-coreroot       : Copy netcore (CLR and FX) from netcore system dir to coreroot.'
25     echo '  --testDir=<path>                 : Run tests only in the specified directory. The path is relative to the directory'
26     echo '                                     specified by --testRootDir. Multiple of this switch may be specified.'
27     echo '  --testDirFile=<path>             : Run tests only in the directories specified by the file at <path>. Paths are listed'
28     echo '                                     one line, relative to the directory specified by --testRootDir.'
29     echo '  --num-procs=<N>                  : Run N test processes at the same time (default is 1).'
30     echo '  -h, --help                       : Show usage information.'
31     echo '  --outputDir                      : Dir to save results to (default: /opt/usr/corefx-tc/results).'
32     echo '  --tmpDir                         : Local tmp dir (default: /opt/usr/corefx-tc/tmp).'
33 }
34
35 function print_results {
36     echo ""
37     echo "======================="
38     echo "     Test Results"
39     echo "======================="
40     echo "# Overlay          : $coreOverlayDir"
41     echo "# Tests Discovered : $countTotalTests"
42     echo "# Passed           : $countPassedTests"
43     echo "# Errored          : $countErroredTests"
44     echo "# Failed           : $countFailedTests"
45     echo "# Skipped          : $countSkippedTests"
46     echo "#"
47     echo "# Errored dlls     : $countErroredDlls"
48     echo "======================="
49 }
50
51 # Initialize counters for bookkeeping.
52 countTotalTests=0
53 countPassedTests=0
54 countErroredTests=0
55 countFailedTests=0
56 countSkippedTests=0
57 countErroredDlls=0
58
59 # Variables for running tests in the background
60 ((maxProcesses = 1)) # long tests delay process creation, use a few more processors
61
62 ((processCount = 0))
63 declare -a testDirPaths
64 declare -a processIds
65 waitProcessIndex=
66 pidNone=0
67
68 function waitany {
69     local pid
70     local exitcode
71     while true; do
72         for (( i=0; i<$maxProcesses; i++ )); do
73             pid=${processIds[$i]}
74             if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then
75                 continue
76             fi
77             if ! kill -0 $pid 2>/dev/null; then
78                 wait $pid
79                 exitcode=$?
80                 waitProcessIndex=$i
81                 processIds[$i]=$pidNone
82                 return $exitcode
83             fi
84         done
85         sleep 0.1
86     done
87 }
88
89 function get_available_process_index {
90     local pid
91     local i=0
92     for (( i=0; i<$maxProcesses; i++ )); do
93         pid=${processIds[$i]}
94         if [ -z "$pid" ] || [ "$pid" == "$pidNone" ]; then
95             break
96         fi
97     done
98     echo $i
99 }
100
101 function finish_test {
102     waitany
103     local testScriptExitCode=$?
104     local finishedProcessIndex=$waitProcessIndex
105     ((--processCount))
106
107     local dirName=${testDirPaths[$finishedProcessIndex]}
108     local testProject=`basename $dirName`
109     local outputFilePath="$testsOutputDir/$testProject/log.out"
110
111     local resultsStr=$(grep "Total:.*Errors:.*Failed:.*Skipped:.*Time:" $outputFilePath)
112
113     if [ "$resultsStr" == "" ]; then
114         if [ $testScriptExitCode -ne 0 ]
115         then
116             echo "$testProject: dll errored, see log $outputFilePath"
117             countErroredDlls=$(($countErroredDlls+1))
118         else
119             # No appropriate tests were found in dll
120             echo "$testProject: no tests found, see log $outputFilePath"
121         fi
122     else
123         local curTotal=$(echo $resultsStr | awk '{print $4}' | sed 's/,//')
124         local curErrored=$(echo $resultsStr | awk '{print $6}' | sed 's/,//')
125         local curFailed=$(echo $resultsStr | awk '{print $8}' | sed 's/,//')
126         local curSkipped=$(echo $resultsStr | awk '{print $10}' | sed 's/,//')
127         local curTime=$(echo $resultsStr | awk '{print $12}' | sed 's/s//')
128         local curPassed=$(echo $curTotal $curErrored $curFailed $curSkipped | awk '{print $1-$2-$3-$4}')
129
130         countTotalTests=$(echo $countTotalTests $curTotal | awk '{print $1+$2}')
131         countPassedTests=$(echo $countPassedTests $curPassed | awk '{print $1+$2}')
132         countErroredTests=$(echo $countErroredTests $curErrored | awk '{print $1+$2}')
133         countFailedTests=$(echo $countFailedTests $curFailed | awk '{print $1+$2}')
134         countSkippedTests=$(echo $countSkippedTests $curSkipped | awk '{print $1+$2}')
135
136         if [ $testScriptExitCode -ne 0 ]
137         then
138             echo "$testProject: failed, Total:$curTotal Passed:$curPassed Errored:$curErrored Failed:$curFailed Skipped:$curSkipped Time:$curTime, see log $outputFilePath"
139         else
140             echo "$testProject: ok, Total:$curTotal Passed:$curPassed Errored:$curErrored Failed:$curFailed Skipped:$curSkipped Time:$curTime, see log $outputFilePath"
141         fi
142     fi
143 }
144
145 function finish_remaining_tests {
146     # Finish the remaining tests in the order in which they were started
147     while ((processCount > 0)); do
148         finish_test
149     done
150 }
151
152 function start_test {
153     local nextProcessIndex=$(get_available_process_index)
154     local dirName="$1"
155     local testProject=`basename $dirName`
156
157     if ((nextProcessIndex == maxProcesses)); then
158         finish_test
159         nextProcessIndex=$(get_available_process_index)
160     fi
161
162     testDirPaths[$nextProcessIndex]=$dirName
163
164     run_test "$dirName" &
165     processIds[$nextProcessIndex]=$!
166
167     ((++processCount))
168 }
169
170 # Handle Ctrl-C.
171 function handle_ctrl_c
172 {
173     echo ""
174     echo "*** Stopping... ***"
175     print_results
176     exit $EXIT_CODE_EXCEPTION
177 }
178
179 # $1 is the path of list file
180 function read_array()
181 {
182     local theArray=()
183
184     if [ ! -f "$1" ]; then
185         return
186     fi
187
188     # bash in Mac OS X doesn't support 'readarray', so using alternate way instead.
189     # readarray -t theArray < "$1"
190     # Any line that starts with '#' is ignored.
191     while IFS='' read -r line || [ -n "$line" ]; do
192         if [[ $line != "#"* ]]; then
193             theArray[${#theArray[@]}]=$line
194         fi
195     done < "$1"
196     echo ${theArray[@]}
197 }
198
199 # Get a list of directories in which to scan for tests by reading the
200 # specified file line by line.
201 function set_test_directories {
202     local listFileName=$1
203
204     if [ ! -f "$listFileName" ]
205     then
206         echo "Test directories file not found at $listFileName"
207         exit $EXIT_CODE_EXCEPTION
208     fi
209     testDirectories=($(read_array "$listFileName"))
210 }
211
212 # $1 is the name of the platform folder (e.g Unix.AnyCPU.Debug)
213 function run_tests()
214 {
215     for testFolder in $@
216     do
217        start_test $testFolder
218     done
219 }
220
221 # $1 is the path to the test folder
222 function run_test()
223 {
224     local dirName="$1"
225     local testProject=`basename $1`
226     local outputDir="$testsOutputDir/$testProject"
227
228     mkdir -p $outputDir
229
230     local outputFilePath="$outputDir/log.out"
231     local outputXmlPath="$outputDir/testResults.xml"
232
233     if [ ! -d "$dirName" ]; then
234         echo "Nothing to test in $testProject" > $outputFilePath 2>&1
235         return $EXIT_CODE_EXCEPTION
236     fi
237
238     if [ ! -e "$dirName/RunTests.sh" ]; then
239         echo "Cannot find $dirName/RunTests.sh" > $outputFilePath 2>&1
240         return $EXIT_CODE_EXCEPTION
241     fi
242
243     cd $dirName
244
245     ./RunTests.sh "$coreOverlayDir" "$outerloop" "$outputXmlPath" "$tmpDir" > $outputFilePath 2>&1
246     local testScriptExitCode=$?
247
248     return $testScriptExitCode
249 }
250
251 # Register the Ctrl-C handler
252 trap handle_ctrl_c INT
253
254 # Exit code constants
255 readonly EXIT_CODE_SUCCESS=0       # Script ran normally.
256 readonly EXIT_CODE_EXCEPTION=1     # Script exited because something exceptional happened (e.g. bad arguments, Ctrl-C interrupt).
257 readonly EXIT_CODE_TEST_FAILURE=2  # Script completed successfully, but one or more tests failed.
258
259 # Argument variables
260 testRootDir="/opt/usr/corefx-tc/tests"
261 coreOverlayDir="/opt/usr/corefx-tc/coreroot/"
262 doCopyNetcoreToCoreroot=0
263 netcoreDir="/usr/share/dotnet.tizen/netcoreapp"
264 outputDir="/opt/usr/corefx-tc/results"
265 tmpDir="/opt/usr/corefx-tc/tmp"
266
267 for i in "$@"
268 do
269     case $i in
270         -h|--help)
271             print_usage
272             exit $EXIT_CODE_SUCCESS
273             ;;
274         --testRootDir=*)
275             testRootDir=${i#*=}
276             ;;
277         --coreOverlayDir=*)
278             coreOverlayDir=${i#*=}
279             ;;
280         --outerloop=*)
281             outerloop=${i#*=}
282             ;;
283         --netcoreDir=*)
284             netcoreDir=${i#*=}
285             ;;
286         --copy-netcore-to-coreroot)
287             doCopyNetcoreToCoreroot=1
288             ;;
289         --testDir=*)
290             testDirectories[${#testDirectories[@]}]=${i#*=}
291             ;;
292         --testDirFile=*)
293             set_test_directories "${i#*=}"
294             ;;
295         --num-procs=*)
296             ((maxProcesses = ${i#*=}))
297             ;;
298         --outputDir=*)
299             outputDir=${i#*=}
300             ;;
301         --tmpDir=*)
302             tmpDir=${i#*=}
303             ;;
304         *)
305             echo "Unknown switch: $i"
306             print_usage
307             exit $EXIT_CODE_SUCCESS
308             ;;
309     esac
310 done
311
312 if [ -z "$testRootDir" ]; then
313     echo "--testRootDir is required."
314     print_usage
315     exit $EXIT_CODE_EXCEPTION
316 fi
317 if [ ! -d "$testRootDir" ]; then
318     echo "Directory specified by --testRootDir does not exist: $testRootDir"
319     exit $EXIT_CODE_EXCEPTION
320 fi
321
322 if [ -z "$coreOverlayDir" ]; then
323     echo "--coreOverlayDir is required."
324     print_usage
325     exit $EXIT_CODE_EXCEPTION
326 fi
327 if [ ! -d "$coreOverlayDir" ]; then
328     echo "Directory specified by --coreOverlayDir does not exist: $coreOverlayDir"
329     exit $EXIT_CODE_EXCEPTION
330 fi
331
332 if [ -z "$outerloop" ]; then
333     echo "--outerloop is required."
334     print_usage
335     exit $EXIT_CODE_EXCEPTION
336 fi
337
338 export CORE_ROOT="$coreOverlayDir"
339
340 echo "! Make sure CLR/FX are copied to $coreOverlayDir !"
341
342 export PAL_OUTPUTDEBUGSTRING="1"
343
344 if [ "$LANG" == "" ]
345 then
346     export LANG="en_US.UTF-8"
347 fi
348
349 if [ $doCopyNetcoreToCoreroot == 1 ]; then
350     echo "Copying netcore ($netcoreDir) to coreroot ($coreOverlayDir)"
351     cp $netcoreDir/* $coreOverlayDir
352 fi
353
354 echo "Cleanup old ni.dll"
355 for file in `find $testRootDir $coreOverlayDir -name "*.ni.*"`; do
356     rm $file
357 done
358
359 testsOutputDir="$outputDir/tests"
360 mkdir -p $testsOutputDir
361 mkdir -p $tmpDir
362
363 time_start=$(date +"%s")
364 if [ -z "$testDirectories" ]
365 then
366     # No test directories were specified, so run everything
367     testDirectories=( $(ls "$testRootDir/" | grep .Tests) )
368 fi
369
370 for testDir in "${testDirectories[@]}"
371 do
372     run_tests "$testRootDir/$testDir"
373 done
374
375 finish_remaining_tests
376 print_results
377
378 time_end=$(date +"%s")
379 time_diff=$(($time_end-$time_start))
380 echo "$(($time_diff / 60)) minutes and $(($time_diff % 60)) seconds taken to run CoreFX tests."
381
382 if [ "$countErroredDlls" -gt 0 ] || [ "$countErroredTests" -gt 0 ] || [ "$countFailedTests" -gt 0 ]
383 then
384     exit $EXIT_CODE_TEST_FAILURE
385 fi
386
387 exit $EXIT_CODE_SUCCESS