summaryrefslogtreecommitdiff
path: root/tests/runtesttilstable.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tests/runtesttilstable.sh')
-rwxr-xr-xtests/runtesttilstable.sh158
1 files changed, 158 insertions, 0 deletions
diff --git a/tests/runtesttilstable.sh b/tests/runtesttilstable.sh
new file mode 100755
index 0000000000..a34774d45c
--- /dev/null
+++ b/tests/runtesttilstable.sh
@@ -0,0 +1,158 @@
+#!/usr/bin/env bash
+
+function print_usage {
+ echo ''
+ echo 'CoreCLR test runner wrapper script.'
+ echo ''
+ echo 'Run tests using runtest.sh, then rerun the failures, if any,'
+ echo 'until the number of failures stabilizes. Thus, when running'
+ echo 'flaky tests, or running tests on a flaky platform, only the'
+ echo 'repeatable, "real", failures are reported.'
+ echo ''
+ echo 'Tests are rerun in sequential mode (passing --sequential to runtest.sh).'
+ echo 'This hopefully avoids resource exhaustion and other parallel run problems.'
+ echo ''
+ echo 'A maximum number of iterations can be specified.'
+ echo ''
+ echo 'Command line:'
+ echo ''
+ echo 'runtesttilstable.sh [options] [arguments for runtest.sh]'
+ echo ''
+ echo 'Any unknown argument is passed directly to runtest.sh.'
+ echo ''
+ echo 'Optional arguments:'
+ echo ' -h|--help : Show usage information.'
+ echo ' --max-iterations=<count> : Specify the maximum number of iterations. Default: 4.'
+ echo ''
+}
+
+function exit_with_error {
+ local errorMessage=$1
+ local printUsage=$2
+
+ if [ -z "$printUsage" ]; then
+ ((printUsage = 0))
+ fi
+
+ echo "$errorMessage"
+ if ((printUsage != 0)); then
+ print_usage
+ fi
+ exit $EXIT_CODE_EXCEPTION
+}
+
+# Handle Ctrl-C. We will stop execution and print the results that
+# we gathered so far.
+function handle_ctrl_c {
+ echo ""
+ echo "*** Stopping... ***"
+ print_results
+ exit_with_error "Test run aborted by Ctrl+C."
+}
+
+# Register the Ctrl-C handler
+trap handle_ctrl_c INT
+
+# Where are we?
+scriptPath=$(dirname $0)
+
+# Exit code constants
+readonly EXIT_CODE_SUCCESS=0 # Script ran normally.
+readonly EXIT_CODE_EXCEPTION=1 # Script exited because something exceptional happened (e.g. bad arguments, Ctrl-C interrupt).
+readonly EXIT_CODE_TEST_FAILURE=2 # Script completed successfully, but one or more tests failed.
+
+# Argument variables
+((maxIterations = 20))
+
+# Handle arguments
+__UnprocessedBuildArgs=
+
+# We need to capture the --testRootDir argument so we know where the test pass/fail/skip files will be placed.
+testRootDir=
+
+# We need to handle the --playlist argument specially. The first run, we pass it through (if passed).
+# After that, we use the --playlist argument ourselves, so we don't pass through the original one.
+playlistArgument=
+
+for i in "$@"
+do
+ case $i in
+ -h|--help)
+ print_usage
+ exit $EXIT_CODE_SUCCESS
+ ;;
+ --max-iterations=*)
+ maxIterations=${i#*=}
+ ;;
+ --playlist=*)
+ playlistArgument=$i
+ ;;
+ --testRootDir=*)
+ testRootDir=${i#*=}
+ # Also pass it on to runtest.sh
+ __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
+ ;;
+ *)
+ __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
+ ;;
+ esac
+done
+
+# Check testRootDir; this check is also done by runtest.sh.
+
+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
+
+# Now start running the tests.
+
+nextcmd="${scriptPath}/runtest.sh ${playlistArgument} ${__UnprocessedBuildArgs}"
+echo "Running: $nextcmd"
+$nextcmd
+exitCode=$?
+if [ $exitCode -eq $EXIT_CODE_TEST_FAILURE ]; then
+ # Now, we loop, rerunning the failed tests up to maxIterations times minus one
+ # (the initial run counts as an iteration).
+ ((totalRerunCount = $maxIterations - 1))
+ for (( i=1; i<=$totalRerunCount; i++ )); do
+ if [ ! -e "$testRootDir/coreclrtests.fail.txt" ]; then
+ exit_with_error "Error: couldn't find $testRootDir/coreclrtests.fail.txt"
+ fi
+
+ num_errors=$(grep -c '' "$testRootDir/coreclrtests.fail.txt")
+ echo "Test run failed with $num_errors errors:"
+ cat "$testRootDir/coreclrtests.fail.txt"
+ echo ''
+
+ echo "Rerunning failures ($i of $totalRerunCount reruns)..."
+
+ # Move the fail file to a different location, so it can be used without getting trashed by the
+ # next run's error file.
+ retryFile="$testRootDir/coreclrtests.retry.txt"
+ if [ -e "$retryFile" ]; then
+ rm -f "$retryFile"
+ if [ -e "$retryFile" ]; then
+ exit_with_error "Error: couldn't delete $retryFile"
+ fi
+ fi
+ mv "$testRootDir/coreclrtests.fail.txt" "$retryFile"
+
+ nextcmd="${scriptPath}/runtest.sh --sequential --playlist=${retryFile} ${__UnprocessedBuildArgs}"
+ echo "Running: $nextcmd"
+ $nextcmd
+ exitCode=$?
+ if [ $exitCode -ne $EXIT_CODE_TEST_FAILURE ]; then
+ # Either success or exceptional failure; we're done. For test failure, we loop,
+ # if we haven't hit the maximum number of allowed iterations.
+ break
+ fi
+ done
+fi
+
+exit $exitCode