Commit 09c4a16d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mptcp-selftests'



Matthieu Baerts says:

====================
selftests: mptcp: format subtests results in TAP

The current selftests infrastructure formats the results in TAP 13. This
version doesn't support subtests and only the end result of each
selftest is taken into account. It means that a single issue in a
subtest of a selftest containing multiple subtests forces the whole
selftest to be marked as failed. It also means that subtests results are
not tracked by CI executing selftests.

MPTCP selftests run hundreds of various subtests. It is then important
to track each of them and not one result per selftest.

It is particularly interesting to do that when validating stable kernels
with the last version of the test suite: tests might fail because a
feature is not supported but the test didn't skip that part. In this
case, if subtests are not tracked, the whole selftest will be marked as
failed making the other subtests useless because their results are
ignored.

Regarding this patch set:

 - The two first patches modify connect and userspace_pm selftests to
   continue executing other tests if there is an error before the end.
   This is what is done in the other MPTCP selftests.

 - Patches 3-5 are refactoring the code in userspace_pm selftest to
   reduce duplicated code, suppress some shellcheck warnings and prepare
   subtests' support by using new helpers.

 - Patch 6 adds new helpers in mptcp_lib.sh to easily support printing
   the subtests results in the different MPTCP selftests.

 - Patch 7-13 format subtests results in TAP 13 in the different MPTCP
   selftests.
====================

Signed-off-by: default avatarMatthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 47448ff2 f589234e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -65,12 +65,15 @@ __chk_nr()
	if [ $nr != $expected ]; then
		if [ $nr = "$skip" ] && ! mptcp_lib_expect_all_features; then
			echo "[ skip ] Feature probably not supported"
			mptcp_lib_result_skip "${msg}"
		else
			echo "[ fail ] expected $expected found $nr"
			mptcp_lib_result_fail "${msg}"
			ret=$test_cnt
		fi
	else
		echo "[  ok  ]"
		mptcp_lib_result_pass "${msg}"
	fi
	test_cnt=$((test_cnt+1))
}
@@ -111,12 +114,15 @@ wait_msk_nr()
	printf "%-50s" "$msg"
	if [ $i -ge $timeout ]; then
		echo "[ fail ] timeout while expecting $expected max $max last $nr"
		mptcp_lib_result_fail "${msg} # timeout"
		ret=$test_cnt
	elif [ $nr != $expected ]; then
		echo "[ fail ] expected $expected found $nr"
		mptcp_lib_result_fail "${msg} # unexpected result"
		ret=$test_cnt
	else
		echo "[  ok  ]"
		mptcp_lib_result_pass "${msg}"
	fi
	test_cnt=$((test_cnt+1))
}
@@ -276,4 +282,5 @@ flush_pids

chk_msk_inuse 0 "....chk 0 msk in use after flush"

mptcp_lib_result_print_all_tap
exit $ret
+56 −10
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ time_start=$(date +%s)

optstring="S:R:d:e:l:r:h4cm:f:tC"
ret=0
final_ret=0
sin=""
sout=""
cin_disconnect=""
@@ -128,6 +129,7 @@ ns3="ns3-$rndh"
ns4="ns4-$rndh"

TEST_COUNT=0
TEST_GROUP=""

cleanup()
{
@@ -285,6 +287,7 @@ check_mptcp_disabled()
	# net.mptcp.enabled should be enabled by default
	if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then
		echo -e "net.mptcp.enabled sysctl is not 1 by default\t\t[ FAIL ]"
		mptcp_lib_result_fail "net.mptcp.enabled sysctl is not 1 by default"
		ret=1
		return 1
	fi
@@ -297,11 +300,13 @@ check_mptcp_disabled()

	if [ ${err} -eq 0 ]; then
		echo -e "New MPTCP socket cannot be blocked via sysctl\t\t[ FAIL ]"
		mptcp_lib_result_fail "New MPTCP socket cannot be blocked via sysctl"
		ret=1
		return 1
	fi

	echo -e "New MPTCP socket can be blocked via sysctl\t\t[ OK ]"
	mptcp_lib_result_pass "New MPTCP socket can be blocked via sysctl"
	return 0
}

@@ -317,14 +322,16 @@ do_ping()
	local connector_ns="$2"
	local connect_addr="$3"
	local ping_args="-q -c 1"
	local rc=0

	if is_v6 "${connect_addr}"; then
		$ipv6 || return 0
		ping_args="${ping_args} -6"
	fi

	ip netns exec ${connector_ns} ping ${ping_args} $connect_addr >/dev/null
	if [ $? -ne 0 ] ; then
	ip netns exec ${connector_ns} ping ${ping_args} $connect_addr >/dev/null || rc=1

	if [ $rc -ne 0 ] ; then
		echo "$listener_ns -> $connect_addr connectivity [ FAIL ]" 1>&2
		ret=1

@@ -403,7 +410,9 @@ do_transfer()

	local addr_port
	addr_port=$(printf "%s:%d" ${connect_addr} ${port})
	printf "%.3s %-5s -> %.3s (%-20s) %-5s\t" ${connector_ns} ${cl_proto} ${listener_ns} ${addr_port} ${srv_proto}
	local result_msg
	result_msg="$(printf "%.3s %-5s -> %.3s (%-20s) %-5s" ${connector_ns} ${cl_proto} ${listener_ns} ${addr_port} ${srv_proto})"
	printf "%s\t" "${result_msg}"

	if $capture; then
		local capuser
@@ -478,6 +487,7 @@ do_transfer()

	local duration
	duration=$((stop-start))
	result_msg+=" # time=${duration}ms"
	printf "(duration %05sms) " "${duration}"
	if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
		echo "[ FAIL ] client exit code $retc, server $rets" 1>&2
@@ -490,6 +500,7 @@ do_transfer()

		echo
		cat "$capout"
		mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}"
		return 1
	fi

@@ -549,6 +560,9 @@ do_transfer()

	if [ $retc -eq 0 ] && [ $rets -eq 0 ]; then
		printf "[ OK ]"
		mptcp_lib_result_pass "${TEST_GROUP}: ${result_msg}"
	else
		mptcp_lib_result_fail "${TEST_GROUP}: ${result_msg}"
	fi

	if [ $cookies -eq 2 ];then
@@ -691,6 +705,8 @@ run_test_transparent()
	local lret=0
	local r6flag=""

	TEST_GROUP="${msg}"

	# skip if we don't want v6
	if ! $ipv6 && is_v6 "${connect_addr}"; then
		return 0
@@ -702,6 +718,7 @@ run_test_transparent()
	# checking for a specific kernel version.
	if ! mptcp_lib_kallsyms_has "T __ip_sock_set_tos$"; then
		echo "INFO: ${msg} not supported by the kernel: SKIP"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -719,6 +736,7 @@ EOF
	if [ $? -ne 0 ]; then
		echo "SKIP: $msg, could not load nft ruleset"
		mptcp_lib_fail_if_expected_feature "nft rules"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -735,6 +753,7 @@ EOF
		ip netns exec "$listener_ns" nft flush ruleset
		echo "SKIP: $msg, ip $r6flag rule failed"
		mptcp_lib_fail_if_expected_feature "ip rule"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -744,6 +763,7 @@ EOF
		ip -net "$listener_ns" $r6flag rule del fwmark 1 lookup 100
		echo "SKIP: $msg, ip route add local $local_addr failed"
		mptcp_lib_fail_if_expected_feature "ip route"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -773,6 +793,7 @@ run_tests_peekmode()
{
	local peekmode="$1"

	TEST_GROUP="peek mode: ${peekmode}"
	echo "INFO: with peek mode: ${peekmode}"
	run_tests_lo "$ns1" "$ns1" 10.0.1.1 1 "-P ${peekmode}"
	run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1 "-P ${peekmode}"
@@ -780,8 +801,11 @@ run_tests_peekmode()

run_tests_mptfo()
{
	TEST_GROUP="MPTFO"

	if ! mptcp_lib_kallsyms_has "mptcp_fastopen_"; then
		echo "INFO: TFO not supported by the kernel: SKIP"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -805,8 +829,11 @@ run_tests_disconnect()
	local old_cin=$cin
	local old_sin=$sin

	TEST_GROUP="full disconnect"

	if ! mptcp_lib_kallsyms_has "mptcp_pm_data_reset$"; then
		echo "INFO: Full disconnect not supported: SKIP"
		mptcp_lib_result_skip "${TEST_GROUP}"
		return
	fi

@@ -837,14 +864,26 @@ display_time()
	echo "Time: ${time_run} seconds"
}

stop_if_error()
log_if_error()
{
	local msg="$1"

	if [ ${ret} -ne 0 ]; then
		echo "FAIL: ${msg}" 1>&2

		final_ret=${ret}
		ret=0

		return ${final_ret}
	fi
}

stop_if_error()
{
	if ! log_if_error "${@}"; then
		display_time
		exit ${ret}
		mptcp_lib_result_print_all_tap
		exit ${final_ret}
	fi
}

@@ -874,6 +913,8 @@ for sender in "$ns1" "$ns2" "$ns3" "$ns4";do
	do_ping "$ns4" $sender dead:beef:3::1
done

mptcp_lib_result_code "${ret}" "ping tests"

stop_if_error "Could not even run ping tests"

[ -n "$tc_loss" ] && tc -net "$ns2" qdisc add dev ns2eth3 root netem loss random $tc_loss delay ${tc_delay}ms
@@ -903,12 +944,15 @@ echo "on ns3eth4"

tc -net "$ns3" qdisc add dev ns3eth4 root netem delay ${reorder_delay}ms $tc_reorder

TEST_GROUP="loopback v4"
run_tests_lo "$ns1" "$ns1" 10.0.1.1 1
stop_if_error "Could not even run loopback test"

TEST_GROUP="loopback v6"
run_tests_lo "$ns1" "$ns1" dead:beef:1::1 1
stop_if_error "Could not even run loopback v6 test"

TEST_GROUP="multihosts"
for sender in $ns1 $ns2 $ns3 $ns4;do
	# ns1<->ns2 is not subject to reordering/tc delays. Use it to test
	# mptcp syncookie support.
@@ -934,23 +978,25 @@ for sender in $ns1 $ns2 $ns3 $ns4;do
	run_tests "$ns4" $sender 10.0.3.1
	run_tests "$ns4" $sender dead:beef:3::1

	stop_if_error "Tests with $sender as a sender have failed"
	log_if_error "Tests with $sender as a sender have failed"
done

run_tests_peekmode "saveWithPeek"
run_tests_peekmode "saveAfterPeek"
stop_if_error "Tests with peek mode have failed"
log_if_error "Tests with peek mode have failed"

# MPTFO (MultiPath TCP Fatopen tests)
run_tests_mptfo
stop_if_error "Tests with MPTFO have failed"
log_if_error "Tests with MPTFO have failed"

# connect to ns4 ip address, ns2 should intercept/proxy
run_test_transparent 10.0.3.1 "tproxy ipv4"
run_test_transparent dead:beef:3::1 "tproxy ipv6"
stop_if_error "Tests with tproxy have failed"
log_if_error "Tests with tproxy have failed"

run_tests_disconnect
log_if_error "Tests of the full disconnection have failed"

display_time
exit $ret
mptcp_lib_result_print_all_tap
exit ${final_ret}
+32 −5
Original line number Diff line number Diff line
@@ -39,7 +39,9 @@ evts_ns1=""
evts_ns2=""
evts_ns1_pid=0
evts_ns2_pid=0
stats_dumped=0
last_test_failed=0
last_test_skipped=0
last_test_ignored=1

declare -A all_tests
declare -a only_tests_ids
@@ -101,7 +103,6 @@ init_partial()
		fi
	done

	stats_dumped=0
	check_invert=0
	validate_checksum=$checksum

@@ -216,6 +217,8 @@ mark_as_skipped()

	print_title "[ skip ] ${msg}"
	printf "\n"

	last_test_skipped=1
}

# $@: condition
@@ -248,14 +251,32 @@ skip_test()
	return 0
}

append_prev_results()
{
	if [ ${last_test_failed} -eq 1 ]; then
		mptcp_lib_result_fail "${TEST_NAME}"
	elif [ ${last_test_skipped} -eq 1 ]; then
		mptcp_lib_result_skip "${TEST_NAME}"
	elif [ ${last_test_ignored} -ne 1 ]; then
		mptcp_lib_result_pass "${TEST_NAME}"
	fi

	last_test_failed=0
	last_test_skipped=0
	last_test_ignored=0
}

# $1: test name
reset()
{
	append_prev_results

	TEST_NAME="${1}"

	TEST_COUNT=$((TEST_COUNT+1))

	if skip_test; then
		last_test_ignored=1
		return 1
	fi

@@ -442,10 +463,13 @@ reset_with_tcp_filter()
fail_test()
{
	ret=1
	failed_tests[${TEST_COUNT}]="${TEST_NAME}"

	[ "${stats_dumped}" = 0 ] && dump_stats
	stats_dumped=1
	# just in case a test is marked twice as failed
	if [ ${last_test_failed} -eq 0 ]; then
		failed_tests[${TEST_COUNT}]="${TEST_NAME}"
		dump_stats
		last_test_failed=1
	fi
}

get_failed_tests_ids()
@@ -3599,4 +3623,7 @@ if [ ${ret} -ne 0 ]; then
	echo
fi

append_prev_results
mptcp_lib_result_print_all_tap

exit $ret
+66 −0
Original line number Diff line number Diff line
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0

readonly KSFT_PASS=0
readonly KSFT_FAIL=1
readonly KSFT_SKIP=4
readonly KSFT_TEST=$(basename "${0}" | sed 's/\.sh$//g')

MPTCP_LIB_SUBTESTS=()

# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all
# features using the last version of the kernel and the selftests to make sure
@@ -102,3 +106,65 @@ mptcp_lib_kversion_ge() {

	mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}"
}

__mptcp_lib_result_add() {
	local result="${1}"
	shift

	local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1))

	MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}")
}

# $1: test name
mptcp_lib_result_pass() {
	__mptcp_lib_result_add "ok" "${1}"
}

# $1: test name
mptcp_lib_result_fail() {
	__mptcp_lib_result_add "not ok" "${1}"
}

# $1: test name
mptcp_lib_result_skip() {
	__mptcp_lib_result_add "ok" "${1} # SKIP"
}

# $1: result code ; $2: test name
mptcp_lib_result_code() {
	local ret="${1}"
	local name="${2}"

	case "${ret}" in
		"${KSFT_PASS}")
			mptcp_lib_result_pass "${name}"
			;;
		"${KSFT_FAIL}")
			mptcp_lib_result_fail "${name}"
			;;
		"${KSFT_SKIP}")
			mptcp_lib_result_skip "${name}"
			;;
		*)
			echo "ERROR: wrong result code: ${ret}"
			exit ${KSFT_FAIL}
			;;
	esac
}

mptcp_lib_result_print_all_tap() {
	local subtest

	if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] ||
	   [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then
		return
	fi

	printf "\nTAP version 13\n"
	printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}"

	for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do
		printf "%s\n" "${subtest}"
	done
}
+18 −2
Original line number Diff line number Diff line
@@ -183,11 +183,13 @@ do_transfer()

	local mptcp_connect="./mptcp_connect -r 20"

	local local_addr
	local local_addr ip
	if is_v6 "${connect_addr}"; then
		local_addr="::"
		ip=ipv6
	else
		local_addr="0.0.0.0"
		ip=ipv4
	fi

	cmsg="TIMESTAMPNS"
@@ -223,6 +225,8 @@ do_transfer()
		echo -e "\nnetns ${connector_ns} socket stat for ${port}:" 1>&2
		ip netns exec ${connector_ns} ss -Menita 1>&2 -o "dport = :$port"

		mptcp_lib_result_fail "transfer ${ip}"

		ret=1
		return 1
	fi
@@ -236,9 +240,11 @@ do_transfer()
	fi

	check_transfer $cin $sout "file received by server"

	rets=$?

	mptcp_lib_result_code "${retc}" "mark ${ip}"
	mptcp_lib_result_code "${rets}" "transfer ${ip}"

	if [ $retc -eq 0 ] && [ $rets -eq 0 ];then
		return 0
	fi
@@ -264,6 +270,7 @@ do_mptcp_sockopt_tests()

	if ! mptcp_lib_kallsyms_has "mptcp_diag_fill_info$"; then
		echo "INFO: MPTCP sockopt not supported: SKIP"
		mptcp_lib_result_skip "sockopt"
		return
	fi

@@ -272,18 +279,22 @@ do_mptcp_sockopt_tests()

	if [ $lret -ne 0 ]; then
		echo "FAIL: SOL_MPTCP getsockopt" 1>&2
		mptcp_lib_result_fail "sockopt v4"
		ret=$lret
		return
	fi
	mptcp_lib_result_pass "sockopt v4"

	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
	lret=$?

	if [ $lret -ne 0 ]; then
		echo "FAIL: SOL_MPTCP getsockopt (ipv6)" 1>&2
		mptcp_lib_result_fail "sockopt v6"
		ret=$lret
		return
	fi
	mptcp_lib_result_pass "sockopt v6"
}

run_tests()
@@ -310,10 +321,12 @@ do_tcpinq_test()
	if [ $lret -ne 0 ];then
		ret=$lret
		echo "FAIL: mptcp_inq $@" 1>&2
		mptcp_lib_result_fail "TCP_INQ: $*"
		return $lret
	fi

	echo "PASS: TCP_INQ cmsg/ioctl $@"
	mptcp_lib_result_pass "TCP_INQ: $*"
	return $lret
}

@@ -323,6 +336,7 @@ do_tcpinq_tests()

	if ! mptcp_lib_kallsyms_has "mptcp_ioctl$"; then
		echo "INFO: TCP_INQ not supported: SKIP"
		mptcp_lib_result_skip "TCP_INQ"
		return
	fi

@@ -367,4 +381,6 @@ if [ $ret -eq 0 ];then
fi

do_tcpinq_tests

mptcp_lib_result_print_all_tap
exit $ret
Loading