Skip to content

Commit 795995f

Browse files
committed
lib/testing: Simplify test_runner.sh script
The test_runner.sh script is derived from the test-netns script originally developed for the xdp-tutorial, and still contains a lot of the legacy from there. Specifically, it uses a state directory with file system-based state to support interactive execution, saving state across multiple invocations of the script. However, the way we execute the tests here, we always clean up everything in the same run, so all this state saving complexity is unnecessary. Get rid of it and store most things in global variables, so we save this complexity. This also makes it possible to support creating multiple namespaces at the same time, which will be needed for adding tests for the xdp-forward tool. For now, we just create two namespaces (with matching veth pairs), but only use one of them, but future tests will use both for forwarding tests. Signed-off-by: Toke Høiland-Jørgensen <[email protected]>
1 parent f9d5502 commit 795995f

File tree

1 file changed

+72
-195
lines changed

1 file changed

+72
-195
lines changed

lib/testing/test_runner.sh

Lines changed: 72 additions & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ IP6_FULL_PREFIX_SIZE=48 # Size of IP6_SUBNET
2121
IP4_SUBNET=10.11
2222
IP4_PREFIX_SIZE=24 # Size of assigned prefixes
2323
IP4_FULL_PREFIX_SIZE=16 # Size of IP4_SUBNET
24-
VLAN_IDS=(1 2)
2524
GENERATED_NAME_PREFIX="xdptest"
2625
ALL_TESTS=""
2726
VERBOSE_TESTS=${V:-0}
27+
NUM_NS=2
2828

2929
NEEDED_TOOLS="capinfos ethtool ip ping sed tc tcpdump timeout nc tshark"
30-
MAX_NAMELEN=15
3130

3231
if [ -f "$TEST_CONFIG" ]; then
3332
source "$TEST_CONFIG"
@@ -43,21 +42,11 @@ fi
4342
SKIPPED_TEST=249
4443

4544
# Global state variables that will be set by options etc below
46-
GENERATE_NEW=0
47-
CLEANUP_FUNC=
4845
STATEDIR=
49-
STATEFILE=
5046
CMD=
5147
NS=
52-
LEGACY_IP=1
53-
USE_VLAN=0
54-
RUN_ON_INNER=0
55-
56-
# State variables that are written to and read from statefile
57-
STATEVARS=(IP6_PREFIX IP4_PREFIX
58-
INSIDE_IP6 INSIDE_IP4 INSIDE_MAC
59-
OUTSIDE_IP6 OUTSIDE_IP4 OUTSIDE_MAC
60-
ENABLE_IPV4 ENABLE_VLAN)
48+
NS_NAMES=()
49+
6150
IP6_PREFIX=
6251
IP4_PREFIX=
6352
INSIDE_IP6=
@@ -66,8 +55,8 @@ INSIDE_MAC=
6655
OUTSIDE_IP6=
6756
OUTSIDE_IP4=
6857
OUTSIDE_MAC=
69-
ENABLE_IPV4=0
70-
ENABLE_VLAN=0
58+
ALL_INSIDE_IP6=()
59+
ALL_INSIDE_IP4=()
7160

7261
is_trace_attach_supported()
7362
{
@@ -207,8 +196,6 @@ start_background_no_stderr()
207196

208197
start_background_ns_devnull()
209198
{
210-
get_nsname && ensure_nsname "$NS"
211-
212199
local TMP_FILE="${STATEDIR}/tmp_proc_$$_$RANDOM"
213200
setsid ip netns exec "$NS" env TESTENV_NAME="$NS" "$SETUP_SCRIPT" bash -c "$*" 1>/dev/null 2>${TMP_FILE} &
214201
local PID=$!
@@ -257,93 +244,17 @@ check_prereq()
257244
fi
258245
}
259246

260-
get_nsname()
261-
{
262-
local GENERATE=${1:-1}
263-
264-
if [ -z "$NS" ]; then
265-
[ -f "$STATEDIR/current" ] && NS=$(< "$STATEDIR/current")
266-
267-
if [ "$GENERATE" -eq "1" ] && [ -z "$NS" ] || [ "$GENERATE_NEW" -eq "1" ]; then
268-
NS="$GENERATED_NAME_PREFIX"
269-
while [ -e "$STATEDIR/${NS}.state" ]; do
270-
NS=$(printf "%s-%04x" "$GENERATED_NAME_PREFIX" $RANDOM)
271-
done
272-
fi
273-
fi
274-
275-
if [ "${#NS}" -gt "$MAX_NAMELEN" ]; then
276-
die "Environment name '$NS' is too long (max $MAX_NAMELEN)"
277-
fi
278-
279-
STATEFILE="$STATEDIR/${NS}.state"
280-
}
281-
282-
ensure_nsname()
283-
{
284-
[ -z "$NS" ] && die "No environment selected; use --name to select one or 'setup' to create one"
285-
[ -e "$STATEFILE" ] || die "Environment for $NS doesn't seem to exist"
286-
287-
echo "$NS" > "$STATEDIR/current"
288-
289-
read_statefile
290-
}
291-
292-
get_num()
293-
{
294-
local num=1
295-
if [ -f "$STATEDIR/highest_num" ]; then
296-
num=$(( 1 + $(< "$STATEDIR/highest_num" )))
297-
fi
298-
299-
echo $num > "$STATEDIR/highest_num"
300-
printf "%x" $num
301-
}
302-
303-
write_statefile()
304-
{
305-
[ -z "$STATEFILE" ] && return 1
306-
echo > "$STATEFILE"
307-
for var in "${STATEVARS[@]}"; do
308-
echo "${var}='$(eval echo '$'$var)'" >> "$STATEFILE"
309-
done
310-
}
311-
312-
read_statefile()
313-
{
314-
local value
315-
for var in "${STATEVARS[@]}"; do
316-
value=$(source "$STATEFILE"; eval echo '$'$var)
317-
eval "$var=\"$value\""
318-
done
319-
}
320-
321-
cleanup_setup()
322-
{
323-
echo "Error during setup, removing partially-configured environment '$NS'" >&2
324-
set +o errexit
325-
ip netns del "$NS" 2>/dev/null
326-
ip link del dev "$NS" 2>/dev/null
327-
rm -f "$STATEFILE"
328-
}
329-
330-
cleanup_teardown()
331-
{
332-
echo "Warning: Errors during teardown, partial environment may be left" >&2
333-
}
334-
335-
336-
cleanup()
247+
gen_nsname()
337248
{
338-
[ -n "$CLEANUP_FUNC" ] && $CLEANUP_FUNC
249+
local nsname
339250

340-
local statefiles=("$STATEDIR"/*.state)
251+
while
252+
nsname=$(printf "%s-%04x" "$GENERATED_NAME_PREFIX" $RANDOM)
253+
[ -e "$STATEDIR/${nsname}.ns" ]
254+
do true; done
341255

342-
if [ "${#statefiles[*]}" -eq 1 ] && [ ! -e "${statefiles[0]}" ]; then
343-
rm -f "${STATEDIR}/highest_num" "${STATEDIR}/current" \
344-
"${STATEDIR}/trace_attach_support"
345-
rmdir "$STATEDIR"
346-
fi
256+
touch "$STATEDIR/${nsname}.ns"
257+
echo $nsname
347258
}
348259

349260
iface_macaddr()
@@ -369,119 +280,90 @@ set_sysctls()
369280
done
370281
}
371282

372-
get_vlan_prefix()
373-
{
374-
# Split the IPv6 prefix, and add the VLAN ID to the upper byte of the fourth
375-
# element in the prefix. This will break if the global prefix config doesn't
376-
# have exactly three elements in it.
377-
local prefix="$1"
378-
local vid="$2"
379-
(IFS=:; set -- $prefix; printf "%s:%s:%s:%x::" "$1" "$2" "$3" $(($4 + $vid * 4096)))
380-
}
381-
382-
setup()
283+
init_ns()
383284
{
384-
get_nsname 1
285+
local nsname=$1
286+
local num=$2
287+
local peername="testl-ve-$num"
385288

386-
[ -e "$STATEFILE" ] && die "Environment for '$NS' already exists"
387-
388-
local NUM=$(get_num "$NS")
389-
local PEERNAME="testl-ve-$NUM"
390-
[ -z "$IP6_PREFIX" ] && IP6_PREFIX="${IP6_SUBNET}:${NUM}::"
391-
[ -z "$IP4_PREFIX" ] && IP4_PREFIX="${IP4_SUBNET}.$((0x$NUM))."
289+
IP6_PREFIX="${IP6_SUBNET}:${num}::"
290+
IP4_PREFIX="${IP4_SUBNET}.$((0x$num))."
392291

393292
INSIDE_IP6="${IP6_PREFIX}2"
394293
INSIDE_IP4="${IP4_PREFIX}2"
395294
OUTSIDE_IP6="${IP6_PREFIX}1"
396295
OUTSIDE_IP4="${IP4_PREFIX}1"
397296

398-
CLEANUP_FUNC=cleanup_setup
399-
400297
if ! mount | grep -q /sys/fs/bpf; then
401298
mount -t bpf bpf /sys/fs/bpf/
402299
fi
403300

404-
ip netns add "$NS"
405-
ip link add dev "$NS" type veth peer name "$PEERNAME"
406-
OUTSIDE_MAC=$(iface_macaddr "$NS")
407-
INSIDE_MAC=$(iface_macaddr "$PEERNAME")
408-
set_sysctls $NS
301+
ip netns add "$nsname"
302+
ip link add dev "$nsname" type veth peer name "$peername"
303+
set_sysctls $nsname
409304

410-
ethtool -K "$NS" rxvlan off txvlan off
411-
ethtool -K "$PEERNAME" rxvlan off txvlan off
412-
ip link set dev "$PEERNAME" netns "$NS"
413-
ip link set dev "$NS" up
414-
ip addr add dev "$NS" "${OUTSIDE_IP6}/${IP6_PREFIX_SIZE}"
305+
ethtool -K "$nsname" rxvlan off txvlan off
306+
ethtool -K "$peername" rxvlan off txvlan off
415307

416-
ip -n "$NS" link set dev "$PEERNAME" name veth0
417-
ip -n "$NS" link set dev lo up
418-
ip -n "$NS" link set dev veth0 up
419-
set_sysctls veth0 "$NS"
420-
ip -n "$NS" addr add dev veth0 "${INSIDE_IP6}/${IP6_PREFIX_SIZE}"
308+
OUTSIDE_MAC=$(iface_macaddr "$nsname")
309+
INSIDE_MAC=$(iface_macaddr "$peername")
310+
ip link set dev "$peername" netns "$nsname"
311+
ip link set dev "$nsname" up
312+
ip addr add dev "$nsname" "${OUTSIDE_IP6}/${IP6_PREFIX_SIZE}"
313+
314+
ip -n "$nsname" link set dev "$peername" name veth0
315+
ip -n "$nsname" link set dev lo up
316+
ip -n "$nsname" link set dev veth0 up
317+
set_sysctls veth0 "$nsname"
318+
ip -n "$nsname" addr add dev veth0 "${INSIDE_IP6}/${IP6_PREFIX_SIZE}"
421319

422320
# Prevent neighbour queries on the link
423-
ip neigh add "$INSIDE_IP6" lladdr "$INSIDE_MAC" dev "$NS" nud permanent
424-
ip -n "$NS" neigh add "$OUTSIDE_IP6" lladdr "$OUTSIDE_MAC" dev veth0 nud permanent
425-
426-
# Add route for whole test subnet, to make it easier to communicate between
427-
# namespaces
428-
ip -n "$NS" route add "${IP6_SUBNET}::/$IP6_FULL_PREFIX_SIZE" via "$OUTSIDE_IP6" dev veth0
429-
430-
if [ "$LEGACY_IP" -eq "1" ]; then
431-
ip addr add dev "$NS" "${OUTSIDE_IP4}/${IP4_PREFIX_SIZE}"
432-
ip -n "$NS" addr add dev veth0 "${INSIDE_IP4}/${IP4_PREFIX_SIZE}"
433-
ip neigh add "$INSIDE_IP4" lladdr "$INSIDE_MAC" dev "$NS" nud permanent
434-
ip -n "$NS" neigh add "$OUTSIDE_IP4" lladdr "$OUTSIDE_MAC" dev veth0 nud permanent
435-
ip -n "$NS" route add "${IP4_SUBNET}/${IP4_FULL_PREFIX_SIZE}" via "$OUTSIDE_IP4" dev veth0
436-
ENABLE_IPV4=1
437-
else
438-
ENABLE_IPV4=0
439-
fi
321+
ip neigh add "$INSIDE_IP6" lladdr "$INSIDE_MAC" dev "$nsname" nud permanent
322+
ip -n "$nsname" neigh add "$OUTSIDE_IP6" lladdr "$OUTSIDE_MAC" dev veth0 nud permanent
440323

441-
if [ "$USE_VLAN" -eq "1" ]; then
442-
ENABLE_VLAN=1
443-
for vid in "${VLAN_IDS[@]}"; do
444-
local vlpx="$(get_vlan_prefix "$IP6_PREFIX" "$vid")"
445-
local inside_ip="${vlpx}2"
446-
local outside_ip="${vlpx}1"
447-
ip link add dev "${NS}.$vid" link "$NS" type vlan id "$vid"
448-
ip link set dev "${NS}.$vid" up
449-
ip addr add dev "${NS}.$vid" "${outside_ip}/${IP6_PREFIX_SIZE}"
450-
ip neigh add "$inside_ip" lladdr "$INSIDE_MAC" dev "${NS}.$vid" nud permanent
451-
set_sysctls "${NS}/$vid"
452-
453-
ip -n "$NS" link add dev "veth0.$vid" link "veth0" type vlan id "$vid"
454-
ip -n "$NS" link set dev "veth0.$vid" up
455-
ip -n "$NS" addr add dev "veth0.$vid" "${inside_ip}/${IP6_PREFIX_SIZE}"
456-
ip -n "$NS" neigh add "$outside_ip" lladdr "$OUTSIDE_MAC" dev "veth0.$vid" nud permanent
457-
set_sysctls "veth0/$vid" "$NS"
458-
done
459-
else
460-
ENABLE_VLAN=0
461-
fi
324+
ip addr add dev "$nsname" "${OUTSIDE_IP4}/${IP4_PREFIX_SIZE}"
325+
ip -n "$nsname" addr add dev veth0 "${INSIDE_IP4}/${IP4_PREFIX_SIZE}"
326+
ip neigh add "$INSIDE_IP4" lladdr "$INSIDE_MAC" dev "$nsname" nud permanent
327+
ip -n "$nsname" neigh add "$OUTSIDE_IP4" lladdr "$OUTSIDE_MAC" dev veth0 nud permanent
328+
329+
# Add default routes inside the ns
330+
ip -n "$nsname" route add default dev veth0
331+
ip -n "$nsname" -6 route add default dev veth0
332+
333+
ALL_INSIDE_IP4+=($INSIDE_IP4)
334+
ALL_INSIDE_IP6+=($INSIDE_IP6)
335+
}
462336

463-
write_statefile
337+
setup()
338+
{
339+
local nsname
464340

465-
CLEANUP_FUNC=
341+
check_prereq
342+
343+
for i in $(seq $NUM_NS); do
344+
nsname=$(gen_nsname)
345+
init_ns $nsname $i
346+
NS_NAMES+=($nsname)
347+
done
466348

467-
echo "$NS" > "$STATEDIR/current"
349+
NS=$nsname
468350
}
469351

470-
teardown()
352+
teardown_ns()
471353
{
472-
get_nsname && ensure_nsname "$NS"
354+
local nsname=$1
473355

474-
CLEANUP_FUNC=cleanup_teardown
356+
ip link del dev "$nsname"
357+
ip netns del "$nsname"
358+
[ -d "/sys/fs/bpf/$nsname" ] && rmdir "/sys/fs/bpf/$nsname" || true
475359

476-
ip link del dev "$NS"
477-
ip netns del "$NS"
478-
rm -f "$STATEFILE"
479-
[ -d "/sys/fs/bpf/$NS" ] && rmdir "/sys/fs/bpf/$NS" || true
360+
}
480361

481-
if [ -f "$STATEDIR/current" ]; then
482-
local CUR=$(< "$STATEDIR/current" )
483-
[[ "$CUR" == "$NS" ]] && rm -f "$STATEDIR/current"
484-
fi
362+
teardown()
363+
{
364+
for ns in "${NS_NAMES[@]}"; do
365+
teardown_ns $ns
366+
done
485367

486368
for f in ${STATEDIR}/proc/*; do
487369
if [ -f "$f" ]; then
@@ -491,14 +373,10 @@ teardown()
491373
done
492374

493375
rm -rf "$STATEDIR"
494-
495-
CLEANUP_FUNC=
496376
}
497377

498378
ns_exec()
499379
{
500-
get_nsname && ensure_nsname "$NS"
501-
502380
ip netns exec "$NS" env TESTENV_NAME="$NS" "$SETUP_SCRIPT" "$@"
503381
}
504382

@@ -554,7 +432,6 @@ run_tests()
554432
local TESTS="$*"
555433
local ret=0
556434
[ -z "$TESTS" ] && TESTS="$ALL_TESTS"
557-
setup || return 1
558435

559436
echo " Running tests from $TEST_DEFINITIONS"
560437

@@ -602,5 +479,5 @@ TOOL_TESTS_DIR="$(dirname "$TEST_DEFINITIONS")"
602479

603480
shift
604481
trap teardown EXIT
605-
check_prereq
482+
setup
606483
run_tests "$@"

0 commit comments

Comments
 (0)