summaryrefslogtreecommitdiffstats
path: root/tests/shell/helpers/test-wrapper.sh
blob: f8b27b1e92913cb187138b0075074062cee4672a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/bin/bash -e

# This wrapper wraps the invocation of the test. It is called by run-tests.sh,
# and already in the unshared namespace.
#
# For some printf debugging, you can also patch this file.

TEST="$1"
TESTBASE="$(basename "$TEST")"
TESTDIR="$(dirname "$TEST")"

START_TIME="$(cut -d ' ' -f1 /proc/uptime)"

export TMPDIR="$NFT_TEST_TESTTMPDIR"

CLEANUP_UMOUNT_RUN_NETNS=n

cleanup() {
	if [ "$CLEANUP_UMOUNT_RUN_NETNS" = y ] ; then
		umount "/var/run/netns" || :
	fi
}

trap cleanup EXIT

printf '%s\n' "$TEST" > "$NFT_TEST_TESTTMPDIR/name"

read tainted_before < /proc/sys/kernel/tainted

if [ "$NFT_TEST_HAS_UNSHARED_MOUNT" = y ] ; then
	# We have a private mount namespace. We will mount /run/netns as a tmpfs,
	# this is useful because `ip netns add` wants to add files there.
	#
	# When running as rootless, this is necessary to get such tests to
	# pass.  When running rootful, it's still useful to not touch the
	# "real" /var/run/netns of the system.
	mkdir -p /var/run/netns
	if mount -t tmpfs --make-private "/var/run/netns" ; then
		CLEANUP_UMOUNT_RUN_NETNS=y
	fi
fi

rc_test=0
"$TEST" &> "$NFT_TEST_TESTTMPDIR/testout.log" || rc_test=$?

$NFT list ruleset > "$NFT_TEST_TESTTMPDIR/ruleset-after"

read tainted_after < /proc/sys/kernel/tainted

DUMPPATH="$TESTDIR/dumps"
DUMPFILE="$DUMPPATH/$TESTBASE.nft"

dump_written=

# The caller can request a re-geneating of the dumps, by setting
# DUMPGEN=y.
#
# This only will happen if the command completed with success.
#
# It also will only happen for tests, that have a "$DUMPPATH" directory. There
# might be tests, that don't want to have dumps created. The existence of the
# directory controls that.
if [ "$rc_test" -eq 0 -a "$DUMPGEN" = y -a -d "$DUMPPATH" ] ; then
	dump_written=y
	cat "$NFT_TEST_TESTTMPDIR/ruleset-after" > "$DUMPFILE"
fi

rc_dump=0
if [ "$rc_test" -ne 77 -a -f "$DUMPFILE" ] ; then
	if [ "$dump_written" != y ] ; then
		if ! $DIFF -u "$DUMPFILE" "$NFT_TEST_TESTTMPDIR/ruleset-after" &> "$NFT_TEST_TESTTMPDIR/ruleset-diff" ; then
			rc_dump=124
			rm -f "$NFT_TEST_TESTTMPDIR/ruleset-diff"
		fi
	fi
fi
if [ "$rc_dump" -ne 0 ] ; then
	echo "$DUMPFILE" > "$NFT_TEST_TESTTMPDIR/rc-failed-dump"
fi

rc_tainted=0
if [ "$tainted_before" != "$tainted_after" ] ; then
	echo "$tainted_after" > "$NFT_TEST_TESTTMPDIR/rc-failed-tainted"
	rc_tainted=123
fi

if [ "$rc_tainted" -ne 0 ] ; then
	rc_exit="$rc_tainted"
elif [ "$rc_test" -ge 118 -a "$rc_test" -le 124 ] ; then
	# Special exit codes are reserved. Coerce them.
	rc_exit="125"
elif [ "$rc_test" -ne 0 ] ; then
	rc_exit="$rc_test"
elif [ "$rc_dump" -ne 0 ] ; then
	rc_exit="$rc_dump"
else
	rc_exit="0"
fi


# We always write the real exit code of the test ($rc_test) to one of the files
# rc-{ok,skipped,failed}, depending on which it is.
#
# Note that there might be other rc-failed-{dump,tainted} files with additional
# errors. Note that if such files exist, the overall state will always be
# failed too (and an "rc-failed" file exists).
#
# On failure, we also write the combined "$rc_exit" code from "test-wrapper.sh"
# to "rc-failed-exit" file.
#
# This means, failed tests will have a "rc-failed" file, and additional
# "rc-failed-*" files exist for further information.
if [ "$rc_exit" -eq 0 ] ; then
	RC_FILENAME="rc-ok"
elif [ "$rc_exit" -eq 77 ] ; then
	RC_FILENAME="rc-skipped"
else
	RC_FILENAME="rc-failed"
	echo "$rc_exit" > "$NFT_TEST_TESTTMPDIR/rc-failed-exit"
fi
echo "$rc_test" > "$NFT_TEST_TESTTMPDIR/$RC_FILENAME"

END_TIME="$(cut -d ' ' -f1 /proc/uptime)"
WALL_TIME="$(awk -v start="$START_TIME" -v end="$END_TIME" "BEGIN { print(end - start) }")"
printf "%s\n" "$WALL_TIME" "$START_TIME" "$END_TIME" > "$NFT_TEST_TESTTMPDIR/times"

exit "$rc_exit"