192f0ce55SGabriele Monaco#!/bin/bash 292f0ce55SGabriele Monaco# SPDX-License-Identifier: GPL-2.0 392f0ce55SGabriele Monacotest_begin() { 492f0ce55SGabriele Monaco # Count tests to allow the test harness to double-check if all were 592f0ce55SGabriele Monaco # included correctly. 692f0ce55SGabriele Monaco ctr=0 792f0ce55SGabriele Monaco [ -z "$RV" ] && RV="../rv/rv" 8*36c1af42SGabriele Monaco [ -z "$RVGEN" ] && RVGEN="python3 ../rvgen" 9*36c1af42SGabriele Monaco [ -z "$GOLDEN_DIR" ] && GOLDEN_DIR="tests/golden" 1092f0ce55SGabriele Monaco [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" 1192f0ce55SGabriele Monaco} 1292f0ce55SGabriele Monaco 1392f0ce55SGabriele Monacofailure() { 1492f0ce55SGabriele Monaco fail=1 1592f0ce55SGabriele Monaco if [ $# -gt 0 ]; then 1692f0ce55SGabriele Monaco failbuf+="$1" 1792f0ce55SGabriele Monaco failbuf+=$'\n' 1892f0ce55SGabriele Monaco fi 1992f0ce55SGabriele Monaco} 2092f0ce55SGabriele Monaco 2192f0ce55SGabriele Monacoreport() { 2292f0ce55SGabriele Monaco local desc="$1" 2392f0ce55SGabriele Monaco 2492f0ce55SGabriele Monaco if [ "$fail" -eq 0 ]; then 2592f0ce55SGabriele Monaco echo "ok $ctr - $desc" 2692f0ce55SGabriele Monaco else 2792f0ce55SGabriele Monaco # Add output and exit code as comments in case of failure 2892f0ce55SGabriele Monaco echo "not ok $ctr - $desc" 2992f0ce55SGabriele Monaco echo -n "$failbuf" 3092f0ce55SGabriele Monaco echo "$result" | col -b | while read -r line; do echo "# $line"; done 3192f0ce55SGabriele Monaco printf "#\n# exit code %s\n" "$exitcode" 3292f0ce55SGabriele Monaco fi 3392f0ce55SGabriele Monaco} 3492f0ce55SGabriele Monaco 3592f0ce55SGabriele Monaco_check() { 3692f0ce55SGabriele Monaco local command=$2 3792f0ce55SGabriele Monaco local expected_exitcode=${3:-0} 3892f0ce55SGabriele Monaco local expected_output=$4 3992f0ce55SGabriele Monaco local unexpected_output=$5 4092f0ce55SGabriele Monaco local all_lines_pattern=$6 4192f0ce55SGabriele Monaco local patterns="$expected_output $unexpected_output $all_lines_pattern" 4292f0ce55SGabriele Monaco local bgpid pid 4392f0ce55SGabriele Monaco 4492f0ce55SGabriele Monaco eval "$TIMEOUT" "$command" &> check_output.$$ & 4592f0ce55SGabriele Monaco bgpid=$! 4692f0ce55SGabriele Monaco 4792f0ce55SGabriele Monaco if grep -q "\$pid" <<< "$patterns"; then 4892f0ce55SGabriele Monaco for _ in {1..30}; do 4992f0ce55SGabriele Monaco pid=$(pgrep -f "${command%%[|;&>]*}" | tail -n1) 5092f0ce55SGabriele Monaco [ -n "$pid" ] && break 5192f0ce55SGabriele Monaco sleep 0.1 5292f0ce55SGabriele Monaco done 5392f0ce55SGabriele Monaco fi 5492f0ce55SGabriele Monaco 5592f0ce55SGabriele Monaco wait $bgpid 5692f0ce55SGabriele Monaco exitcode=$? 5792f0ce55SGabriele Monaco result=$(tr -d '\0' < check_output.$$) 5892f0ce55SGabriele Monaco rm -f check_output.$$ 5992f0ce55SGabriele Monaco 6092f0ce55SGabriele Monaco failbuf='' 6192f0ce55SGabriele Monaco fail=0 6292f0ce55SGabriele Monaco 6392f0ce55SGabriele Monaco # Suppress any other error if a needed pid is empty 6492f0ce55SGabriele Monaco if [ -z "$pid" ] && grep -q "\$pid" <<< "$patterns"; then 6592f0ce55SGabriele Monaco result='' 6692f0ce55SGabriele Monaco failure "# Empty pid for $command" 6792f0ce55SGabriele Monaco return 1 6892f0ce55SGabriele Monaco fi 6992f0ce55SGabriele Monaco 7092f0ce55SGabriele Monaco expected_output="${expected_output//\$pid/$pid}" 7192f0ce55SGabriele Monaco unexpected_output="${unexpected_output//\$pid/$pid}" 7292f0ce55SGabriele Monaco all_lines_pattern="${all_lines_pattern//\$pid/$pid}" 7392f0ce55SGabriele Monaco 7492f0ce55SGabriele Monaco # Test if the results matches if requested 7592f0ce55SGabriele Monaco if [ -n "$expected_output" ] && ! grep -qe "$expected_output" <<< "$result"; then 7692f0ce55SGabriele Monaco failure "# Output match failed: \"$expected_output\"" 7792f0ce55SGabriele Monaco fi 7892f0ce55SGabriele Monaco 7992f0ce55SGabriele Monaco if [ -n "$unexpected_output" ] && grep -qe "$unexpected_output" <<< "$result"; then 8092f0ce55SGabriele Monaco failure "# Output non-match failed: \"$unexpected_output\"" 8192f0ce55SGabriele Monaco fi 8292f0ce55SGabriele Monaco 8392f0ce55SGabriele Monaco if [ -n "$all_lines_pattern" ] && grep -vqe "$all_lines_pattern" <<< "$result"; then 8492f0ce55SGabriele Monaco failure "# All-lines pattern failed: \"$all_lines_pattern\"" 8592f0ce55SGabriele Monaco fi 8692f0ce55SGabriele Monaco 8792f0ce55SGabriele Monaco if [ $exitcode -ne "$expected_exitcode" ]; then 8892f0ce55SGabriele Monaco failure "# Expected exit code $expected_exitcode" 8992f0ce55SGabriele Monaco fi 9092f0ce55SGabriele Monaco} 9192f0ce55SGabriele Monaco 9292f0ce55SGabriele Monacocheck() { 9392f0ce55SGabriele Monaco # Simple check: run the command with given arguments and test exit code. 9492f0ce55SGabriele Monaco # If TEST_COUNT is set, run the test. Otherwise, just count. 9592f0ce55SGabriele Monaco ctr=$((ctr + 1)) 9692f0ce55SGabriele Monaco if [ -n "$TEST_COUNT" ]; then 9792f0ce55SGabriele Monaco _check "$@" 9892f0ce55SGabriele Monaco report "$1" 9992f0ce55SGabriele Monaco fi 10092f0ce55SGabriele Monaco} 10192f0ce55SGabriele Monaco 10292f0ce55SGabriele Monacocheck_if_exists() { 10392f0ce55SGabriele Monaco # Conditional check that skips if a file or folder doesn't exist 10492f0ce55SGabriele Monaco local desc=$1 10592f0ce55SGabriele Monaco local command=$2 10692f0ce55SGabriele Monaco local file=$3 10792f0ce55SGabriele Monaco local expected_output=$4 10892f0ce55SGabriele Monaco local unexpected_output=$5 10992f0ce55SGabriele Monaco local all_lines_pattern=$6 11092f0ce55SGabriele Monaco 11192f0ce55SGabriele Monaco ctr=$((ctr + 1)) 11292f0ce55SGabriele Monaco if [ -n "$TEST_COUNT" ]; then 11392f0ce55SGabriele Monaco if [ ! -e "$file" ]; then 11492f0ce55SGabriele Monaco echo "ok $ctr - $desc # SKIP file not found: $file" 11592f0ce55SGabriele Monaco else 11692f0ce55SGabriele Monaco _check "$desc" "$command" 0 "$expected_output" \ 11792f0ce55SGabriele Monaco "$unexpected_output" "$all_lines_pattern" 11892f0ce55SGabriele Monaco report "$desc" 11992f0ce55SGabriele Monaco fi 12092f0ce55SGabriele Monaco fi 12192f0ce55SGabriele Monaco} 12292f0ce55SGabriele Monaco 123*36c1af42SGabriele Monacocheck_and_compare_folder() { 124*36c1af42SGabriele Monaco # Run command, compare generated folder to golden, and cleanup 125*36c1af42SGabriele Monaco local desc=$1 126*36c1af42SGabriele Monaco local command=$2 127*36c1af42SGabriele Monaco local generated_dir=$3 128*36c1af42SGabriele Monaco local expected_output=$4 129*36c1af42SGabriele Monaco local unexpected_output=$5 130*36c1af42SGabriele Monaco local golden_dir="$GOLDEN_DIR/$generated_dir" 131*36c1af42SGabriele Monaco 132*36c1af42SGabriele Monaco ctr=$((ctr + 1)) 133*36c1af42SGabriele Monaco if [ -n "$TEST_COUNT" ]; then 134*36c1af42SGabriele Monaco rm -rf "$generated_dir" 135*36c1af42SGabriele Monaco _check "$desc" "$command" 0 "$expected_output" "$unexpected_output" 136*36c1af42SGabriele Monaco 137*36c1af42SGabriele Monaco if [ "$fail" -eq 0 ] && [ ! -d "$generated_dir" ]; then 138*36c1af42SGabriele Monaco failure "# Generated directory not found: $generated_dir" 139*36c1af42SGabriele Monaco fi 140*36c1af42SGabriele Monaco 141*36c1af42SGabriele Monaco if [ "$fail" -ne 0 ]; then 142*36c1af42SGabriele Monaco : 143*36c1af42SGabriele Monaco elif ! diff -r "$generated_dir" "$golden_dir" &> /dev/null; then 144*36c1af42SGabriele Monaco failure "# Directories differ:" 145*36c1af42SGabriele Monaco failbuf+=$(diff -r "$generated_dir" "$golden_dir" 2>&1 | sed 's/^/# /') 146*36c1af42SGabriele Monaco failbuf+=$'\n' 147*36c1af42SGabriele Monaco fi 148*36c1af42SGabriele Monaco 149*36c1af42SGabriele Monaco report "$1" 150*36c1af42SGabriele Monaco 151*36c1af42SGabriele Monaco rm -rf "$generated_dir" 152*36c1af42SGabriele Monaco fi 153*36c1af42SGabriele Monaco} 154*36c1af42SGabriele Monaco 15592f0ce55SGabriele Monacoset_timeout() { 15692f0ce55SGabriele Monaco TIMEOUT="timeout -v -k 30s $1" 15792f0ce55SGabriele Monaco} 15892f0ce55SGabriele Monaco 15992f0ce55SGabriele Monacoset_expected_timeout() { 16092f0ce55SGabriele Monaco TIMEOUT="timeout --preserve-status -k 30s $1" 16192f0ce55SGabriele Monaco} 16292f0ce55SGabriele Monaco 16392f0ce55SGabriele Monacounset_timeout() { 16492f0ce55SGabriele Monaco unset TIMEOUT 16592f0ce55SGabriele Monaco} 16692f0ce55SGabriele Monaco 16792f0ce55SGabriele Monacotest_end() { 16892f0ce55SGabriele Monaco # If running without TEST_COUNT, tests are not actually run, just 16992f0ce55SGabriele Monaco # counted. In that case, re-run the test with the correct count. 17092f0ce55SGabriele Monaco [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash "$0" || true 17192f0ce55SGabriele Monaco} 17292f0ce55SGabriele Monaco 17392f0ce55SGabriele Monaco# Avoid any environmental discrepancies 17492f0ce55SGabriele Monacoexport LC_ALL=C 17592f0ce55SGabriele Monacounset_timeout 176