projects/linux·blob master · refs

175 lines · 4.1 KiB

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