diff options
author | Steve MacLean <sdmaclea@qti.qualcomm.com> | 2017-02-13 15:14:17 -0500 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-02-13 12:14:17 -0800 |
commit | 3d5d12d7e897d7c2d90ab83aa4eb95b410cb98f5 (patch) | |
tree | a98d5f54f23ae4c8b1b0091a98d3bba0052ca3a6 /tests/runparallel.sh | |
parent | 6185a8801d3d4402b3afb728856aa62b86dadb4a (diff) | |
download | coreclr-3d5d12d7e897d7c2d90ab83aa4eb95b410cb98f5.tar.gz coreclr-3d5d12d7e897d7c2d90ab83aa4eb95b410cb98f5.tar.bz2 coreclr-3d5d12d7e897d7c2d90ab83aa4eb95b410cb98f5.zip |
[Unix] Add runparallel.sh (#9557)
Initial draft of a run script capable of keeping
high core count Arm64 servers saturated
Uses xargs to submit and schedule jobs
Diffstat (limited to 'tests/runparallel.sh')
-rwxr-xr-x | tests/runparallel.sh | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/tests/runparallel.sh b/tests/runparallel.sh new file mode 100755 index 0000000000..697d3a0019 --- /dev/null +++ b/tests/runparallel.sh @@ -0,0 +1,213 @@ +#!/usr/bin/env bash + +function print_usage { + echo '' + echo 'CoreCLR parallel test runner script.' + echo '' + echo 'Required arguments:' + echo ' --testRootDir=<path> : Root directory of the test build (e.g. coreclr/bin/tests/Windows_NT.x64.Debug).' + echo ' --coreOverlayDir=<path> : Directory containing core binaries and test dependencies. If not specified, the' + echo ' default is testRootDir/Tests/coreoverlay. This switch overrides --coreClrBinDir,' + echo ' --mscorlibDir, --coreFxBinDir, and --coreFxNativeBinDir.' + echo ' --playlist=<path> : Run only the tests that are specified in the file at <path>, in the same format as' + echo '' + echo 'Optional arguments:' + echo ' -h|--help : Show usage information.' + echo ' --test-env : Script to set environment variables for tests' + echo '' +} + +function print_results { + echo -e \ + "Results @ $(date +%r)\n\t"\ + "Pass:$countPassedTests\t"\ + "Fail:$countFailedTests\n\t"\ + "Finish:$countFinishedTests\t"\ + "Incomplete: $countIncompleteTests\n\t"\ + "Total: $countTotalTests" +} + +function update_results { + # Initialize counters for bookkeeping. + countTotalTests=$(wc -l < $playlistFile) + + countFinishedTests=$(cd results.int; grep -r 'RUN_TEST_EXIT_CODE' . | wc -l) + countPassedTests=$(cd results.int; grep -r 'RUN_TEST_EXIT_CODE=0' . | wc -l) + countFailedTests=$((countFinishedTests - countPassedTests)) + countIncompleteTests=$((countTotalTests - countFinishedTests)) + + print_results +} + +function print_elapsed_time { + time_end=$(date +"%s") + time_diff=$(($time_end-$time_start)) + echo "$(($time_diff / 60)) minutes and $(($time_diff % 60)) seconds taken to run CoreCLR tests." +} + + + +# Handle Ctrl-C. We will stop execution and print the results that +# we gathered so far. +function handle_ctrl_c { + local errorSource='handle_ctrl_c' + + echo "" + echo "*** Stopping... ***" + + update_results + echo "$errorSource" "Test run aborted by Ctrl+C." + + print_elapsed_time + + exit 1 +} + +function cleanup +{ + kill -TERM % >/dev/null + mv results.int results.$(date +%F_%I%M%p) +} + + +prep_test() { + # This function runs in a background process. It should not echo anything, and should not use global variables. + + #remove any NI + rm -f $(dirname "$1")/*.ni.* +} + +run_test() { + # This function runs in a background process. It should not echo anything, and should not use global variables. + + local scriptFilePath=$1 + + local scriptFileName=$(basename "$scriptFilePath") + local outputFileName=$PWD/results.int/${scriptFilePath////.} + + nice "$scriptFilePath" -debug=$(which time) >"$outputFileName" 2>&1 + + echo RUN_TEST_EXIT_CODE="$?" >>"$outputFileName" +} + +# Argument variables +testRootDir= +coreOverlayDir= +testEnv= +playlistFile= + +for i in "$@" +do + case $i in + -h|--help) + print_usage + exit $EXIT_CODE_SUCCESS + ;; + --coreOverlayDir=*)# Exit code constants + coreOverlayDir=${i#*=} + ;; + --playlist=*) + playlistFile=${i#*=} + ;; + --testRootDir=*) + testRootDir=${i#*=} + ;; + --test-env=*) + testEnv=${i#*=} + ;; + *) + echo "Unknown switch: $i" + print_usage + exit $EXIT_CODE_SUCCESS + ;; + esac +done + +if [ -z "$coreOverlayDir" ]; then + echo "--coreOverlayDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi + +if [ ! -d "$coreOverlayDir" ]; then + echo "Directory specified by --coreOverlayDir does not exist: $coreOverlayDir" + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$playlistFile" ]; then + echo "--playlist is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi + +if [ ! -e "$playlistFile" ]; then + echo "File specified by --playlist does not exist: $playlistFile" + exit $EXIT_CODE_EXCEPTION +fi + +if [ -z "$testRootDir" ]; then + echo "--testRootDir is required." + print_usage + exit $EXIT_CODE_EXCEPTION +fi + +if [ ! -d "$testRootDir" ]; then + echo "Directory specified by --testRootDir does not exist: $testRootDir" + exit $EXIT_CODE_EXCEPTION +fi + +if [ ! -z "$testEnv" ] && [ ! -e "$testEnv" ]; then + echo "File specified by --playlist does not exist: $testEnv" + exit $EXIT_CODE_EXCEPTION +fi + +export CORE_ROOT="$coreOverlayDir" +export __TestEnv=$testEnv + + +# Variables for running tests in the background +if [ `uname` = "NetBSD" ]; then + NumProc=$(getconf NPROCESSORS_ONLN) +else + NumProc=$(getconf _NPROCESSORS_ONLN) +fi + +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"/>' + +export -f prep_test +export -f run_test + +cd $testRootDir +time_start=$(date +"%s") + +rm -rf results.int/* results.int + +echo "Prepping tests $(date +%r)" +xargs -d "\n" -P $NumProc -I{} bash -c prep_test {} < $playlistFile + + +trap cleanup EXIT +mkdir results.int +echo $$ > results.int/pid +cp $testEnv results.int + +trap handle_ctrl_c INT TERM + +xargs -d "\n" -P $NumProc -I{} bash -c 'run_test "{}" >/dev/null 2>&1' < $playlistFile & + +while true +do + update_results + sleep 20 & + wait -n % + if (( $(jobs %xargs 2>/dev/null | wc -l) == 0 )) ; + then + break + fi + + jobs -p > /dev/null +done + +update_results + +print_elapsed_time |