1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3test_begin() { 4 # Count tests to allow the test harness to double-check if all were 5 # included correctly. 6 ctr=0 7 [ -z "$RV" ] && RV="../rv/rv" 8 [ -z "$RVGEN" ] && RVGEN="python3 ../rvgen" 9 [ -z "$GOLDEN_DIR" ] && GOLDEN_DIR="tests/golden" 10 [ -n "$TEST_COUNT" ] && echo "1..$TEST_COUNT" 11} 12 13failure() { 14 fail=1 15 if [ $# -gt 0 ]; then 16 failbuf+="$1" 17 failbuf+=$'\n' 18 fi 19} 20 21report() { 22 local desc="$1" 23 24 if [ "$fail" -eq 0 ]; then 25 echo "ok $ctr - $desc" 26 else 27 # Add output and exit code as comments in case of failure 28 echo "not ok $ctr - $desc" 29 echo -n "$failbuf" 30 echo "$result" | col -b | while read -r line; do echo "# $line"; done 31 printf "#\n# exit code %s\n" "$exitcode" 32 fi 33} 34 35_check() { 36 local command=$2 37 local expected_exitcode=${3:-0} 38 local expected_output=$4 39 local unexpected_output=$5 40 local all_lines_pattern=$6 41 local patterns="$expected_output $unexpected_output $all_lines_pattern" 42 local bgpid pid 43 44 eval "$TIMEOUT" "$command" &> check_output.$$ & 45 bgpid=$! 46 47 if grep -q "\$pid" <<< "$patterns"; then 48 for _ in {1..30}; do 49 pid=$(pgrep -f "${command%%[|;&>]*}" | tail -n1) 50 [ -n "$pid" ] && break 51 sleep 0.1 52 done 53 fi 54 55 wait $bgpid 56 exitcode=$? 57 result=$(tr -d '\0' < check_output.$$) 58 rm -f check_output.$$ 59 60 failbuf='' 61 fail=0 62 63 # Suppress any other error if a needed pid is empty 64 if [ -z "$pid" ] && grep -q "\$pid" <<< "$patterns"; then 65 result='' 66 failure "# Empty pid for $command" 67 return 1 68 fi 69 70 expected_output="${expected_output//\$pid/$pid}" 71 unexpected_output="${unexpected_output//\$pid/$pid}" 72 all_lines_pattern="${all_lines_pattern//\$pid/$pid}" 73 74 # Test if the results matches if requested 75 if [ -n "$expected_output" ] && ! grep -qe "$expected_output" <<< "$result"; then 76 failure "# Output match failed: \"$expected_output\"" 77 fi 78 79 if [ -n "$unexpected_output" ] && grep -qe "$unexpected_output" <<< "$result"; then 80 failure "# Output non-match failed: \"$unexpected_output\"" 81 fi 82 83 if [ -n "$all_lines_pattern" ] && grep -vqe "$all_lines_pattern" <<< "$result"; then 84 failure "# All-lines pattern failed: \"$all_lines_pattern\"" 85 fi 86 87 if [ $exitcode -ne "$expected_exitcode" ]; then 88 failure "# Expected exit code $expected_exitcode" 89 fi 90} 91 92check() { 93 # Simple check: run the command with given arguments and test exit code. 94 # If TEST_COUNT is set, run the test. Otherwise, just count. 95 ctr=$((ctr + 1)) 96 if [ -n "$TEST_COUNT" ]; then 97 _check "$@" 98 report "$1" 99 fi 100} 101 102check_if_exists() { 103 # Conditional check that skips if a file or folder doesn't exist 104 local desc=$1 105 local command=$2 106 local file=$3 107 local expected_output=$4 108 local unexpected_output=$5 109 local all_lines_pattern=$6 110 111 ctr=$((ctr + 1)) 112 if [ -n "$TEST_COUNT" ]; then 113 if [ ! -e "$file" ]; then 114 echo "ok $ctr - $desc # SKIP file not found: $file" 115 else 116 _check "$desc" "$command" 0 "$expected_output" \ 117 "$unexpected_output" "$all_lines_pattern" 118 report "$desc" 119 fi 120 fi 121} 122 123check_and_compare_folder() { 124 # Run command, compare generated folder to golden, and cleanup 125 local desc=$1 126 local command=$2 127 local generated_dir=$3 128 local expected_output=$4 129 local unexpected_output=$5 130 local golden_dir="$GOLDEN_DIR/$generated_dir" 131 132 ctr=$((ctr + 1)) 133 if [ -n "$TEST_COUNT" ]; then 134 rm -rf "$generated_dir" 135 _check "$desc" "$command" 0 "$expected_output" "$unexpected_output" 136 137 if [ "$fail" -eq 0 ] && [ ! -d "$generated_dir" ]; then 138 failure "# Generated directory not found: $generated_dir" 139 fi 140 141 if [ "$fail" -ne 0 ]; then 142 : 143 elif ! diff -r "$generated_dir" "$golden_dir" &> /dev/null; then 144 failure "# Directories differ:" 145 failbuf+=$(diff -r "$generated_dir" "$golden_dir" 2>&1 | sed 's/^/# /') 146 failbuf+=$'\n' 147 fi 148 149 report "$1" 150 151 rm -rf "$generated_dir" 152 fi 153} 154 155set_timeout() { 156 TIMEOUT="timeout -v -k 30s $1" 157} 158 159set_expected_timeout() { 160 TIMEOUT="timeout --preserve-status -k 30s $1" 161} 162 163unset_timeout() { 164 unset TIMEOUT 165} 166 167test_end() { 168 # If running without TEST_COUNT, tests are not actually run, just 169 # counted. In that case, re-run the test with the correct count. 170 [ -z "$TEST_COUNT" ] && TEST_COUNT=$ctr exec bash "$0" || true 171} 172 173# Avoid any environmental discrepancies 174export LC_ALL=C 175unset_timeout 176