blob: 74efc11a160a3080402d69a461de2fd068a5edd1 [file] [edit]
#!/usr/bin/env bash
# arg variable init
output_dir=
run_stress=
# Avoids a race condition in test_object_interface
# since a PSO might be held alive a little too long in the disk thread.
# It's very flaky and best to just avoid it.
export VKD3D_SHADER_CACHE_PATH=0
args=()
# by default run one job per cpu thread
nr_cpus=$(grep -w processor /proc/cpuinfo|wc -l)
while [[ $# -gt 0 ]]; do
case $1 in
-o|--output-dir)
# this outputs the logs for each test to a separate file
output_dir="$2"
shift
shift
;;
-s|--run-stress-tests)
# stress tests take a long time to run and are disabled by default
run_stress=1
shift
;;
-j|--jobs)
# override the default job count
nr_cpus=$2
shift
shift
;;
-h|--help)
echo "./test-runner.sh [-o|--output-dir logfile_dir] [-s|--run-stress-tests] [-j|--jobs N] path/to/tests/d3d12"
exit 1
;;
-*|--*)
echo "unknown arg $1"
;;
*)
args+=("$1")
shift
;;
esac
done
set -- "${args[@]}"
d3d12_bin="$1"
if [[ -z $d3d12_bin || ! -f "$d3d12_bin" ]] ; then
echo "Must specify path to valid d3d12 test exe!"
exit 1
fi
mapfile -t tests < <("$d3d12_bin" --list-tests)
if [[ -z $run_stress ]] ; then
compacted=()
for t in "${tests[@]}" ; do
if [[ "$t" != *stress* ]] ; then
compacted+=($t)
fi
done
tests=(${compacted[@]})
fi
# runtime variable init
nr_tests=${#tests[@]}
if [ $nr_tests -lt 1 ] ; then
echo "No tests detected! Is $d3d12_bin a valid test exe?"
exit 1
fi
pids=()
# the counter for the number of tests running
counter=0
# the index for the next test to run
test_idx=0
if [[ -n $output_dir ]] ; then
mkdir -p "$output_dir"
fi
# start test processes until $nr_cpus test processes are running
run_tests() {
while (($counter < $nr_cpus)) ; do
# output to /dev/null by default
if [[ -z "$output_dir" ]] ; then
VKD3D_TEST_MATCH=${tests[$test_idx]} "$d3d12_bin" &>/dev/null &
else
VKD3D_TEST_MATCH=${tests[$test_idx]} "$d3d12_bin" &> "$output_dir/${tests[$test_idx]}.log" &
fi
# capture pid of subprocess
pids[$test_idx]=${!}
#increment running test counter and test index
counter=$((counter+1))
test_idx=$((test_idx+1))
done
}
echo "Running $nr_tests vkd3d-proton D3D12 tests..."
r=0
fails=()
last_notify=$(date +%s)
while (($r<$nr_tests)) ; do
# run tests if there are more tests to run
if [ $test_idx -lt $nr_tests ] ; then
run_tests
fi
# tests are active: wait for one to finish, store pid to $finished
wait -n -p finished &>/dev/null
retval=$?
pid_count=${#pids[@]}
# iterate $pids array to find the index matching $finished
for ((c=0; c < $pid_count; c++)) ; do
if [[ ${pids[$c]} == $finished ]] ; then
# failed/crashed tests have $retval!=0
if [[ $retval != 0 ]] ; then
# print failure immediately and store for summary
fails+=(${tests[$c]})
echo "FAILED ${tests[$c]}"
fi
# increment the "done" counter
r=$((r+1))
# decrement the "running" counter
counter=$((counter-1))
break
fi
done
cur_time=$(date +%s)
# only notify every 5s
if [ $((last_notify+5)) -lt $cur_time ] ; then
echo "$r / $nr_tests complete (${#fails[@]} failures)..."
last_notify=$cur_time
fi
done
# nice summary output at the end
echo "***********************"
echo "Finished in ${SECONDS}s!"
if [[ "${#fails[@]}" != 0 ]] ; then
echo "${#fails[@]} FAILURES: (run with 'VKD3D_TEST_MATCH=<name> $d3d12_bin')"
for fail in "${fails[@]}" ; do
echo "$fail"
done
else
echo "ALL PASSED!"
fi