diff options
Diffstat (limited to 'tools/verification/tests/engine.sh')
| -rw-r--r-- | tools/verification/tests/engine.sh | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/tools/verification/tests/engine.sh b/tools/verification/tests/engine.sh new file mode 100644 index 000000000000..cfdf2180aad8 --- /dev/null +++ b/tools/verification/tests/engine.sh @@ -0,0 +1,175 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +test_begin() { + # Count tests to allow the test harness to double-check if all were + # included correctly. + ctr=0 + [ -z "$RV" ] && RV="../rv/rv" + [ -z "$RVGEN" ] && RVGEN="python3 ../rvgen" + [ -z "$GOLDEN_DIR" ] && GOLDEN_DIR="tests/golden" + [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" +} + +failure() { + fail=1 + if [ $# -gt 0 ]; then + failbuf+="$1" + failbuf+=$'\n' + fi +} + +report() { + local desc="$1" + + if [ "$fail" -eq 0 ]; then + echo "ok $ctr - $desc" + else + # Add output and exit code as comments in case of failure + echo "not ok $ctr - $desc" + echo -n "$failbuf" + echo "$result" | col -b | while read -r line; do echo "# $line"; done + printf "#\n# exit code %s\n" "$exitcode" + fi +} + +_check() { + local command=$2 + local expected_exitcode=${3:-0} + local expected_output=$4 + local unexpected_output=$5 + local all_lines_pattern=$6 + local patterns="$expected_output $unexpected_output $all_lines_pattern" + local bgpid pid + + eval "$TIMEOUT" "$command" &> check_output.$$ & + bgpid=$! + + if grep -q "\$pid" <<< "$patterns"; then + for _ in {1..30}; do + pid=$(pgrep -f "${command%%[|;&>]*}" | tail -n1) + [ -n "$pid" ] && break + sleep 0.1 + done + fi + + wait $bgpid + exitcode=$? + result=$(tr -d '\0' < check_output.$$) + rm -f check_output.$$ + + failbuf='' + fail=0 + + # Suppress any other error if a needed pid is empty + if [ -z "$pid" ] && grep -q "\$pid" <<< "$patterns"; then + result='' + failure "# Empty pid for $command" + return 1 + fi + + expected_output="${expected_output//\$pid/$pid}" + unexpected_output="${unexpected_output//\$pid/$pid}" + all_lines_pattern="${all_lines_pattern//\$pid/$pid}" + + # Test if the results matches if requested + if [ -n "$expected_output" ] && ! grep -qe "$expected_output" <<< "$result"; then + failure "# Output match failed: \"$expected_output\"" + fi + + if [ -n "$unexpected_output" ] && grep -qe "$unexpected_output" <<< "$result"; then + failure "# Output non-match failed: \"$unexpected_output\"" + fi + + if [ -n "$all_lines_pattern" ] && grep -vqe "$all_lines_pattern" <<< "$result"; then + failure "# All-lines pattern failed: \"$all_lines_pattern\"" + fi + + if [ $exitcode -ne "$expected_exitcode" ]; then + failure "# Expected exit code $expected_exitcode" + fi +} + +check() { + # Simple check: run the command with given arguments and test exit code. + # If TEST_COUNT is set, run the test. Otherwise, just count. + ctr=$((ctr + 1)) + if [ -n "$TEST_COUNT" ]; then + _check "$@" + report "$1" + fi +} + +check_if_exists() { + # Conditional check that skips if a file or folder doesn't exist + local desc=$1 + local command=$2 + local file=$3 + local expected_output=$4 + local unexpected_output=$5 + local all_lines_pattern=$6 + + ctr=$((ctr + 1)) + if [ -n "$TEST_COUNT" ]; then + if [ ! -e "$file" ]; then + echo "ok $ctr - $desc # SKIP file not found: $file" + else + _check "$desc" "$command" 0 "$expected_output" \ + "$unexpected_output" "$all_lines_pattern" + report "$desc" + fi + fi +} + +check_and_compare_folder() { + # Run command, compare generated folder to golden, and cleanup + local desc=$1 + local command=$2 + local generated_dir=$3 + local expected_output=$4 + local unexpected_output=$5 + local golden_dir="$GOLDEN_DIR/$generated_dir" + + ctr=$((ctr + 1)) + if [ -n "$TEST_COUNT" ]; then + rm -rf "$generated_dir" + _check "$desc" "$command" 0 "$expected_output" "$unexpected_output" + + if [ "$fail" -eq 0 ] && [ ! -d "$generated_dir" ]; then + failure "# Generated directory not found: $generated_dir" + fi + + if [ "$fail" -ne 0 ]; then + : + elif ! diff -r "$generated_dir" "$golden_dir" &> /dev/null; then + failure "# Directories differ:" + failbuf+=$(diff -r "$generated_dir" "$golden_dir" 2>&1 | sed 's/^/# /') + failbuf+=$'\n' + fi + + report "$1" + + rm -rf "$generated_dir" + fi +} + +set_timeout() { + TIMEOUT="timeout -v -k 30s $1" +} + +set_expected_timeout() { + TIMEOUT="timeout --preserve-status -k 30s $1" +} + +unset_timeout() { + unset TIMEOUT +} + +test_end() { + # If running without TEST_COUNT, tests are not actually run, just + # counted. In that case, re-run the test with the correct count. + [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash "$0" || true +} + +# Avoid any environmental discrepancies +export LC_ALL=C +unset_timeout |
