summaryrefslogtreecommitdiffstats
path: root/iptables/tests/shell/run-tests.sh
blob: 7878760fdcc4d9ef65c65e0c30b5adbb88ab9fc1 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/bin/bash

#configuration
TESTDIR="./$(dirname $0)/"
RETURNCODE_SEPARATOR="_"

usage() {
	cat <<EOF
Usage: $(basename $0) [-v|--verbose] [-H|--host] [-V|--valgrind]
		      [[-l|--legacy]|[-n|--nft]] [testscript ...]

-v | --verbose		Enable verbose mode (do not drop testscript output).
-H | --host		Run tests against installed binaries in \$PATH,
			not those built in this source tree.
-V | --valgrind		Enable leak checking via valgrind.
-l | --legacy		Test legacy variant only. Conflicts with --nft.
-n | --nft		Test nft variant only. Conflicts with --legacy.
testscript		Run only specific test(s). Implies --verbose.
EOF
}

msg_error() {
        echo "E: $1 ..." >&2
        exit 1
}

msg_warn() {
        echo "W: $1" >&2
}

msg_info() {
        echo "I: $1"
}

if [ "$(id -u)" != "0" ] ; then
        msg_error "this requires root!"
fi

if [ ! -d "$TESTDIR" ] ; then
        msg_error "missing testdir $TESTDIR"
fi

# support matching repeated pattern in SINGLE check below
shopt -s extglob

while [ -n "$1" ]; do
	case "$1" in
	-v|--verbose)
		VERBOSE=y
		shift
		;;
	-H|--host)
		HOST=y
		shift
		;;
	-l|--legacy)
		LEGACY_ONLY=y
		shift
		;;
	-n|--nft)
		NFT_ONLY=y
		shift
		;;
	-V|--valgrind)
		VALGRIND=y
		shift
		;;
	-h|--help)
		usage
		exit 0
		;;
	*${RETURNCODE_SEPARATOR}+([0-9]))
		SINGLE+=" $1"
		VERBOSE=y
		shift
		;;
	*)
		msg_error "unknown parameter '$1'"
		;;
	esac
done

if [ "$HOST" != "y" ]; then
	XTABLES_NFT_MULTI="$(dirname $0)/../../xtables-nft-multi"
	XTABLES_LEGACY_MULTI="$(dirname $0)/../../xtables-legacy-multi"

	export XTABLES_LIBDIR=${TESTDIR}/../../../extensions
else
	XTABLES_NFT_MULTI="xtables-nft-multi"
	XTABLES_LEGACY_MULTI="xtables-legacy-multi"
fi

printscript() { # (cmd, tmpd)
	cat <<EOF
#!/bin/bash

CMD="$1"

# note: valgrind man page warns about --log-file with --trace-children, the
# last child executed overwrites previous reports unless %p or %q is used.
# Since libtool wrapper calls exec but none of the iptables tools do, this is
# perfect for us as it effectively hides bash-related errors

valgrind --log-file=$2/valgrind.log --trace-children=yes \
	 --leak-check=full --show-leak-kinds=all \$CMD "\$@"
RC=\$?

# don't keep uninteresting logs
if grep -q 'no leaks are possible' $2/valgrind.log; then
	rm $2/valgrind.log
else
	mv $2/valgrind.log $2/valgrind_\$\$.log
fi

# drop logs for failing commands for now
[ \$RC -eq 0 ] || rm $2/valgrind_\$\$.log

exit \$RC
EOF
}

if [ "$VALGRIND" == "y" ]; then
	tmpd=$(mktemp -d)
	msg_info "writing valgrind logs to $tmpd"
	chmod a+rx $tmpd
	printscript "$XTABLES_NFT_MULTI" "$tmpd" >${tmpd}/xtables-nft-multi
	printscript "$XTABLES_LEGACY_MULTI" "$tmpd" >${tmpd}/xtables-legacy-multi
	trap "rm ${tmpd}/xtables-*-multi" EXIT
	chmod a+x ${tmpd}/xtables-nft-multi ${tmpd}/xtables-legacy-multi

	XTABLES_NFT_MULTI="${tmpd}/xtables-nft-multi"
	XTABLES_LEGACY_MULTI="${tmpd}/xtables-legacy-multi"

fi

find_tests() {
        if [ ! -z "$SINGLE" ] ; then
                echo $SINGLE
                return
        fi
        find ${TESTDIR} -executable -regex \
                .*${RETURNCODE_SEPARATOR}[0-9]+ | sort
}

ok=0
failed=0

do_test() {
	testfile="$1"
	xtables_multi="$2"

	rc_spec=`echo $(basename ${testfile}) | cut -d _ -f2-`

	msg_info "[EXECUTING]   $testfile"

	if [ "$VERBOSE" = "y" ]; then
		XT_MULTI=$xtables_multi unshare -n ${testfile}
		rc_got=$?
	else
		XT_MULTI=$xtables_multi unshare -n ${testfile} > /dev/null 2>&1
		rc_got=$?
		echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line
	fi

	if [ "$rc_got" == "$rc_spec" ] ; then
		msg_info "[OK]          $testfile"
		((ok++))
	else
		((failed++))
		msg_warn "[FAILED]      $testfile: expected $rc_spec but got $rc_got"
	fi
}

echo ""
if [ "$NFT_ONLY" != "y" ]; then
	for testfile in $(find_tests);do
		do_test "$testfile" "$XTABLES_LEGACY_MULTI"
	done
	msg_info "legacy results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"

fi
legacy_ok=$ok
legacy_fail=$failed
ok=0
failed=0
if [ "$LEGACY_ONLY" != "y" ]; then
	for testfile in $(find_tests);do
		do_test "$testfile" "$XTABLES_NFT_MULTI"
	done
	msg_info "nft results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"
fi

ok=$((legacy_ok+ok))
failed=$((legacy_fail+failed))

msg_info "combined results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))"

exit -$failed