Merge branch 'selftests-fixes-for-kernel-ci'
Petr Machata says: ==================== selftests: Fixes for kernel CI As discussed on the bi-weekly call on Jan 30, and in mailing around kernel CI effort, some changes are desirable in the suite of forwarding selftests the better to work with the CI tooling. Namely: - The forwarding selftests use a configuration file where names of interfaces are defined and various variables can be overridden. There is also forwarding.config.sample that users can use as a template to refer to when creating the config file. What happens a fair bit is that users either do not know about this at all, or simply forget, and are confused by cryptic failures about interfaces that cannot be created. In patches #1 - #3 have lib.sh just be the single source of truth with regards to which variables exist. That includes the topology variables which were previously only in the sample file, and any "tweak variables", such as what tools to use, sleep times, etc. forwarding.config.sample then becomes just a placeholder with a couple examples. Unless specific HW should be exercised, or specific tools used, the defaults are usually just fine. - Several net/forwarding/ selftests (and one net/ one) cannot be run on veth pairs, they need an actual HW interface to run on. They are generic in the sense that any capable HW should pass them, which is why they have been put to net/forwarding/ as opposed to drivers/net/, but they do not generalize to veth. The fact that these tests are in net/forwarding/, but still complaining when run, is confusing. In patches #4 - #6 move these tests to a new directory drivers/net/hw. - The following patches extend the codebase to handle well test results other than pass and fail. Patch #7 is preparatory. It converts several log_test_skip to XFAIL, so that tests do not spuriously end up returning non-0 when they are not supposed to. In patches #8 - #10, introduce some missing ksft constants, then support having those constants in RET, and then finally in EXIT_STATUS. - The traffic scheduler tests generate a large amount of network traffic to test the behavior of the scheduler. This demands a relatively high-performance computer. On slow machines, such as with a debugging kernel, the test would spuriously fail. It can still be useful to "go through the motions" though, to possibly catch bugs in setup of the scheduler graph and passing packets around. Thus we still want to run the tests, just with lowered demands. To that end, in patches #11 - #12, introduce an environment variable KSFT_MACHINE_SLOW, with obvious meaning. Tests can then make checks more lenient, such as mark failures as XFAIL. A helper, xfail_on_slow, is provided to mark performance-sensitive parts of the selftest. - In patch #13, use a similar mechanism to mark a NH group stats selftest to XFAIL HW stats tests when run on VETH pairs. - All these changes complicate the hitherto straightforward logging and checking logic, so in patch #14, add a selftest that checks this functionality in lib.sh. v1 (vs. an RFC circulated through linux-kselftest): - Patch #9: - Clarify intended usage by s/set_ret/ret_set_ksft_status/, s/nret/ksft_status/ ==================== Link: https://lore.kernel.org/r/cover.1711464583.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
51cf49f626
25
tools/testing/selftests/drivers/net/hw/Makefile
Normal file
25
tools/testing/selftests/drivers/net/hw/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+ OR MIT
|
||||
|
||||
TEST_PROGS = \
|
||||
devlink_port_split.py \
|
||||
ethtool.sh \
|
||||
ethtool_extended_state.sh \
|
||||
ethtool_mm.sh \
|
||||
ethtool_rmon.sh \
|
||||
hw_stats_l3.sh \
|
||||
hw_stats_l3_gre.sh \
|
||||
loopback.sh \
|
||||
#
|
||||
|
||||
TEST_FILES := \
|
||||
ethtool_lib.sh \
|
||||
#
|
||||
|
||||
TEST_INCLUDES := \
|
||||
../../../net/lib.sh \
|
||||
../../../net/forwarding/lib.sh \
|
||||
../../../net/forwarding/ipip_lib.sh \
|
||||
../../../net/forwarding/tc_common.sh \
|
||||
#
|
||||
|
||||
include ../../../lib.mk
|
@ -10,7 +10,8 @@ ALL_TESTS="
|
||||
different_speeds_autoneg_on
|
||||
"
|
||||
NUM_NETIFS=2
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
source ethtool_lib.sh
|
||||
|
||||
h1_create()
|
||||
@ -286,8 +287,6 @@ different_speeds_autoneg_on()
|
||||
ethtool -s $h1 autoneg on
|
||||
}
|
||||
|
||||
skip_on_veth
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
@ -8,7 +8,8 @@ ALL_TESTS="
|
||||
"
|
||||
|
||||
NUM_NETIFS=2
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
source ethtool_lib.sh
|
||||
|
||||
TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
|
||||
@ -108,8 +109,6 @@ no_cable()
|
||||
ip link set dev $swp3 down
|
||||
}
|
||||
|
||||
skip_on_veth
|
||||
|
||||
setup_prepare
|
||||
|
||||
tests_run
|
@ -14,7 +14,8 @@ ALL_TESTS="
|
||||
NUM_NETIFS=2
|
||||
REQUIRE_MZ=no
|
||||
PREEMPTIBLE_PRIO=0
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
|
||||
traffic_test()
|
||||
{
|
@ -7,7 +7,8 @@ ALL_TESTS="
|
||||
"
|
||||
|
||||
NUM_NETIFS=2
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
|
||||
ETH_FCS_LEN=4
|
||||
ETH_HLEN=$((6+6+2))
|
||||
@ -78,7 +79,7 @@ rmon_histogram()
|
||||
|
||||
for if in $iface $neigh; do
|
||||
if ! ensure_mtu $if ${bucket[0]}; then
|
||||
log_test_skip "$if does not support the required MTU for $step"
|
||||
log_test_xfail "$if does not support the required MTU for $step"
|
||||
return
|
||||
fi
|
||||
done
|
||||
@ -93,7 +94,7 @@ rmon_histogram()
|
||||
jq -r ".[0].rmon[\"${set}-pktsNtoM\"][]|[.low, .high]|@tsv" 2>/dev/null)
|
||||
|
||||
if [ $nbuckets -eq 0 ]; then
|
||||
log_test_skip "$iface does not support $set histogram counters"
|
||||
log_test_xfail "$iface does not support $set histogram counters"
|
||||
return
|
||||
fi
|
||||
}
|
@ -48,7 +48,8 @@ ALL_TESTS="
|
||||
test_double_enable
|
||||
"
|
||||
NUM_NETIFS=4
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
|
||||
h1_create()
|
||||
{
|
||||
@ -324,17 +325,9 @@ setup_wait
|
||||
|
||||
used=$(ip -j stats show dev $rp1.200 group offload subgroup hw_stats_info |
|
||||
jq '.[].info.l3_stats.used')
|
||||
kind=$(ip -j -d link show dev $rp1 |
|
||||
jq -r '.[].linkinfo.info_kind')
|
||||
if [[ $used != true ]]; then
|
||||
if [[ $kind == veth ]]; then
|
||||
log_test_skip "l3_stats not offloaded on veth interface"
|
||||
EXIT_STATUS=$ksft_skip
|
||||
else
|
||||
RET=1 log_test "l3_stats not offloaded"
|
||||
fi
|
||||
else
|
||||
tests_run
|
||||
fi
|
||||
[[ $used = true ]]
|
||||
check_err $? "hw_stats_info.used=$used"
|
||||
log_test "l3_stats offloaded"
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
@ -12,8 +12,9 @@ ALL_TESTS="
|
||||
test_stats_tx
|
||||
"
|
||||
NUM_NETIFS=6
|
||||
source lib.sh
|
||||
source ipip_lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
source "$lib_dir"/../../../net/forwarding/ipip_lib.sh
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
@ -99,8 +100,6 @@ test_stats_rx()
|
||||
test_stats g2a rx
|
||||
}
|
||||
|
||||
skip_on_veth
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
@ -6,8 +6,9 @@ ksft_skip=4
|
||||
|
||||
ALL_TESTS="loopback_test"
|
||||
NUM_NETIFS=2
|
||||
source tc_common.sh
|
||||
source lib.sh
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/../../../net/forwarding/tc_common.sh
|
||||
source "$lib_dir"/../../../net/forwarding/lib.sh
|
||||
|
||||
h1_create()
|
||||
{
|
1
tools/testing/selftests/drivers/net/hw/settings
Normal file
1
tools/testing/selftests/drivers/net/hw/settings
Normal file
@ -0,0 +1 @@
|
||||
timeout=0
|
@ -42,7 +42,7 @@ __mlxsw_only_on_spectrum()
|
||||
local src=$1; shift
|
||||
|
||||
if ! mlxsw_on_spectrum "$rev"; then
|
||||
log_test_skip $src:$caller "(Spectrum-$rev only)"
|
||||
log_test_xfail $src:$caller "(Spectrum-$rev only)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
|
||||
RET=0
|
||||
target=$(${current_test}_get_target "$should_fail")
|
||||
if ((target == 0)); then
|
||||
log_test_skip "'$current_test' should_fail=$should_fail test"
|
||||
continue
|
||||
fi
|
||||
|
||||
|
@ -52,7 +52,6 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
|
||||
RET=0
|
||||
target=$(${current_test}_get_target "$should_fail")
|
||||
if ((target == 0)); then
|
||||
log_test_skip "'$current_test' [$profile] should_fail=$should_fail test"
|
||||
continue
|
||||
fi
|
||||
${current_test}_setup_prepare
|
||||
|
@ -20,7 +20,6 @@ TEST_PROGS += reuseaddr_ports_exhausted.sh
|
||||
TEST_PROGS += txtimestamp.sh
|
||||
TEST_PROGS += vrf-xfrm-tests.sh
|
||||
TEST_PROGS += rxtimestamp.sh
|
||||
TEST_PROGS += devlink_port_split.py
|
||||
TEST_PROGS += drop_monitor_tests.sh
|
||||
TEST_PROGS += vrf_route_leaking.sh
|
||||
TEST_PROGS += bareudp.sh
|
||||
|
@ -15,18 +15,12 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
|
||||
bridge_vlan_unaware.sh \
|
||||
custom_multipath_hash.sh \
|
||||
dual_vxlan_bridge.sh \
|
||||
ethtool_extended_state.sh \
|
||||
ethtool_mm.sh \
|
||||
ethtool_rmon.sh \
|
||||
ethtool.sh \
|
||||
gre_custom_multipath_hash.sh \
|
||||
gre_inner_v4_multipath.sh \
|
||||
gre_inner_v6_multipath.sh \
|
||||
gre_multipath_nh_res.sh \
|
||||
gre_multipath_nh.sh \
|
||||
gre_multipath.sh \
|
||||
hw_stats_l3.sh \
|
||||
hw_stats_l3_gre.sh \
|
||||
ip6_forward_instats_vrf.sh \
|
||||
ip6gre_custom_multipath_hash.sh \
|
||||
ip6gre_flat_key.sh \
|
||||
@ -43,8 +37,8 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
|
||||
ipip_hier_gre_key.sh \
|
||||
ipip_hier_gre_keys.sh \
|
||||
ipip_hier_gre.sh \
|
||||
lib_sh_test.sh \
|
||||
local_termination.sh \
|
||||
loopback.sh \
|
||||
mirror_gre_bound.sh \
|
||||
mirror_gre_bridge_1d.sh \
|
||||
mirror_gre_bridge_1d_vlan.sh \
|
||||
@ -113,7 +107,6 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
|
||||
vxlan_symmetric.sh
|
||||
|
||||
TEST_FILES := devlink_lib.sh \
|
||||
ethtool_lib.sh \
|
||||
fib_offload_lib.sh \
|
||||
forwarding.config.sample \
|
||||
ip6gre_lib.sh \
|
||||
|
@ -56,3 +56,36 @@ o Checks shall be added to lib.sh for any external dependencies.
|
||||
o Code shall be checked using ShellCheck [1] prior to submission.
|
||||
|
||||
1. https://www.shellcheck.net/
|
||||
|
||||
Customization
|
||||
=============
|
||||
|
||||
The forwarding selftests framework uses a number of variables that
|
||||
influence its behavior and tools it invokes, and how it invokes them, in
|
||||
various ways. A number of these variables can be overridden. The way these
|
||||
overridable variables are specified is typically one of the following two
|
||||
syntaxes:
|
||||
|
||||
: "${VARIABLE:=default_value}"
|
||||
VARIABLE=${VARIABLE:=default_value}
|
||||
|
||||
Any of these variables can be overridden. Notably net/forwarding/lib.sh and
|
||||
net/lib.sh contain a number of overridable variables.
|
||||
|
||||
One way of overriding these variables is through the environment:
|
||||
|
||||
PAUSE_ON_FAIL=yes ./some_test.sh
|
||||
|
||||
The variable NETIFS is special. Since it is an array variable, there is no
|
||||
way to pass it through the environment. Its value can instead be given as
|
||||
consecutive arguments to the selftest:
|
||||
|
||||
./some_test.sh swp{1..8}
|
||||
|
||||
A way to customize variables in a persistent fashion is to create a file
|
||||
named forwarding.config in this directory. lib.sh sources the file if
|
||||
present, so it can contain any shell code. Typically it will contain
|
||||
assignments of variables whose value should be overridden.
|
||||
|
||||
forwarding.config.sample is available in the directory as an example of
|
||||
how forwarding.config might look.
|
||||
|
@ -3,51 +3,28 @@
|
||||
|
||||
##############################################################################
|
||||
# Topology description. p1 looped back to p2, p3 to p4 and so on.
|
||||
declare -A NETIFS
|
||||
|
||||
NETIFS[p1]=veth0
|
||||
NETIFS[p2]=veth1
|
||||
NETIFS[p3]=veth2
|
||||
NETIFS[p4]=veth3
|
||||
NETIFS[p5]=veth4
|
||||
NETIFS[p6]=veth5
|
||||
NETIFS[p7]=veth6
|
||||
NETIFS[p8]=veth7
|
||||
NETIFS[p9]=veth8
|
||||
NETIFS[p10]=veth9
|
||||
NETIFS=(
|
||||
[p1]=veth0
|
||||
[p2]=veth1
|
||||
[p3]=veth2
|
||||
[p4]=veth3
|
||||
[p5]=veth4
|
||||
[p6]=veth5
|
||||
[p7]=veth6
|
||||
[p8]=veth7
|
||||
[p9]=veth8
|
||||
[p10]=veth9
|
||||
)
|
||||
|
||||
# Port that does not have a cable connected.
|
||||
NETIF_NO_CABLE=eth8
|
||||
|
||||
##############################################################################
|
||||
# Defines
|
||||
# In addition to the topology-related variables, it is also possible to override
|
||||
# in this file other variables that net/lib.sh, net/forwarding/lib.sh or other
|
||||
# libraries or selftests use. E.g.:
|
||||
|
||||
# IPv4 ping utility name
|
||||
PING=ping
|
||||
# IPv6 ping utility name. Some distributions use 'ping' for IPv6.
|
||||
PING6=ping6
|
||||
# Packet generator. Some distributions use 'mz'.
|
||||
MZ=mausezahn
|
||||
# mausezahn delay between transmissions in microseconds.
|
||||
MZ_DELAY=0
|
||||
# Time to wait after interfaces participating in the test are all UP
|
||||
WAIT_TIME=5
|
||||
# Whether to pause on failure or not.
|
||||
PAUSE_ON_FAIL=no
|
||||
# Whether to pause on cleanup or not.
|
||||
PAUSE_ON_CLEANUP=no
|
||||
# Type of network interface to create
|
||||
NETIF_TYPE=veth
|
||||
# Whether to create virtual interfaces (veth) or not
|
||||
NETIF_CREATE=yes
|
||||
# Timeout (in seconds) before ping exits regardless of how many packets have
|
||||
# been sent or received
|
||||
PING_TIMEOUT=5
|
||||
# Minimum ageing_time (in centiseconds) supported by hardware
|
||||
LOW_AGEING_TIME=1000
|
||||
# Flag for tc match, supposed to be skip_sw/skip_hw which means do not process
|
||||
# filter by software/hardware
|
||||
TC_FLAG=skip_hw
|
||||
# IPv6 traceroute utility name.
|
||||
TROUTE6=traceroute6
|
||||
|
||||
|
@ -141,7 +141,6 @@
|
||||
# | $h2 + |
|
||||
# | 192.0.2.18/28 |
|
||||
# +---------------------------+
|
||||
source lib.sh
|
||||
|
||||
h1_create()
|
||||
{
|
||||
|
@ -1,34 +1,88 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
##############################################################################
|
||||
# Topology description. p1 looped back to p2, p3 to p4 and so on.
|
||||
|
||||
declare -A NETIFS=(
|
||||
[p1]=veth0
|
||||
[p2]=veth1
|
||||
[p3]=veth2
|
||||
[p4]=veth3
|
||||
[p5]=veth4
|
||||
[p6]=veth5
|
||||
[p7]=veth6
|
||||
[p8]=veth7
|
||||
[p9]=veth8
|
||||
[p10]=veth9
|
||||
)
|
||||
|
||||
# Port that does not have a cable connected.
|
||||
: "${NETIF_NO_CABLE:=eth8}"
|
||||
|
||||
##############################################################################
|
||||
# Defines
|
||||
|
||||
# Can be overridden by the configuration file.
|
||||
PING=${PING:=ping}
|
||||
PING6=${PING6:=ping6}
|
||||
MZ=${MZ:=mausezahn}
|
||||
MZ_DELAY=${MZ_DELAY:=0}
|
||||
ARPING=${ARPING:=arping}
|
||||
TEAMD=${TEAMD:=teamd}
|
||||
WAIT_TIME=${WAIT_TIME:=5}
|
||||
PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
|
||||
PAUSE_ON_CLEANUP=${PAUSE_ON_CLEANUP:=no}
|
||||
NETIF_TYPE=${NETIF_TYPE:=veth}
|
||||
NETIF_CREATE=${NETIF_CREATE:=yes}
|
||||
MCD=${MCD:=smcrouted}
|
||||
MC_CLI=${MC_CLI:=smcroutectl}
|
||||
PING_COUNT=${PING_COUNT:=10}
|
||||
PING_TIMEOUT=${PING_TIMEOUT:=5}
|
||||
WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}
|
||||
INTERFACE_TIMEOUT=${INTERFACE_TIMEOUT:=600}
|
||||
LOW_AGEING_TIME=${LOW_AGEING_TIME:=1000}
|
||||
REQUIRE_JQ=${REQUIRE_JQ:=yes}
|
||||
REQUIRE_MZ=${REQUIRE_MZ:=yes}
|
||||
REQUIRE_MTOOLS=${REQUIRE_MTOOLS:=no}
|
||||
STABLE_MAC_ADDRS=${STABLE_MAC_ADDRS:=no}
|
||||
TCPDUMP_EXTRA_FLAGS=${TCPDUMP_EXTRA_FLAGS:=}
|
||||
TROUTE6=${TROUTE6:=traceroute6}
|
||||
# Networking utilities.
|
||||
: "${PING:=ping}"
|
||||
: "${PING6:=ping6}" # Some distros just use ping.
|
||||
: "${ARPING:=arping}"
|
||||
: "${TROUTE6:=traceroute6}"
|
||||
|
||||
# Packet generator.
|
||||
: "${MZ:=mausezahn}" # Some distributions use 'mz'.
|
||||
: "${MZ_DELAY:=0}"
|
||||
|
||||
# Host configuration tools.
|
||||
: "${TEAMD:=teamd}"
|
||||
: "${MCD:=smcrouted}"
|
||||
: "${MC_CLI:=smcroutectl}"
|
||||
|
||||
# Constants for netdevice bring-up:
|
||||
# Default time in seconds to wait for an interface to come up before giving up
|
||||
# and bailing out. Used during initial setup.
|
||||
: "${INTERFACE_TIMEOUT:=600}"
|
||||
# Like INTERFACE_TIMEOUT, but default for ad-hoc waiting in testing scripts.
|
||||
: "${WAIT_TIMEOUT:=20}"
|
||||
# Time to wait after interfaces participating in the test are all UP.
|
||||
: "${WAIT_TIME:=5}"
|
||||
|
||||
# Whether to pause on, respectively, after a failure and before cleanup.
|
||||
: "${PAUSE_ON_FAIL:=no}"
|
||||
: "${PAUSE_ON_CLEANUP:=no}"
|
||||
|
||||
# Whether to create virtual interfaces, and what netdevice type they should be.
|
||||
: "${NETIF_CREATE:=yes}"
|
||||
: "${NETIF_TYPE:=veth}"
|
||||
|
||||
# Constants for ping tests:
|
||||
# How many packets should be sent.
|
||||
: "${PING_COUNT:=10}"
|
||||
# Timeout (in seconds) before ping exits regardless of how many packets have
|
||||
# been sent or received
|
||||
: "${PING_TIMEOUT:=5}"
|
||||
|
||||
# Minimum ageing_time (in centiseconds) supported by hardware
|
||||
: "${LOW_AGEING_TIME:=1000}"
|
||||
|
||||
# Whether to check for availability of certain tools.
|
||||
: "${REQUIRE_JQ:=yes}"
|
||||
: "${REQUIRE_MZ:=yes}"
|
||||
: "${REQUIRE_MTOOLS:=no}"
|
||||
|
||||
# Whether to override MAC addresses on interfaces participating in the test.
|
||||
: "${STABLE_MAC_ADDRS:=no}"
|
||||
|
||||
# Flags for tcpdump
|
||||
: "${TCPDUMP_EXTRA_FLAGS:=}"
|
||||
|
||||
# Flags for TC filters.
|
||||
: "${TC_FLAG:=skip_hw}"
|
||||
|
||||
# Whether the machine is "slow" -- i.e. might be incapable of running tests
|
||||
# involving heavy traffic. This might be the case on a debug kernel, a VM, or
|
||||
# e.g. a low-power board.
|
||||
: "${KSFT_MACHINE_SLOW:=no}"
|
||||
|
||||
net_forwarding_dir=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
|
||||
|
||||
@ -205,17 +259,6 @@ check_port_mab_support()
|
||||
fi
|
||||
}
|
||||
|
||||
skip_on_veth()
|
||||
{
|
||||
local kind=$(ip -j -d link show dev ${NETIFS[p1]} |
|
||||
jq -r '.[].linkinfo.info_kind')
|
||||
|
||||
if [[ $kind == veth ]]; then
|
||||
echo "SKIP: Test cannot be run with veth pairs"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "SKIP: need root privileges"
|
||||
exit $ksft_skip
|
||||
@ -358,14 +401,31 @@ EXIT_STATUS=0
|
||||
# Per-test return value. Clear at the beginning of each test.
|
||||
RET=0
|
||||
|
||||
ret_set_ksft_status()
|
||||
{
|
||||
local ksft_status=$1; shift
|
||||
local msg=$1; shift
|
||||
|
||||
RET=$(ksft_status_merge $RET $ksft_status)
|
||||
if (( $? )); then
|
||||
retmsg=$msg
|
||||
fi
|
||||
}
|
||||
|
||||
# Whether FAILs should be interpreted as XFAILs. Internal.
|
||||
FAIL_TO_XFAIL=
|
||||
|
||||
check_err()
|
||||
{
|
||||
local err=$1
|
||||
local msg=$2
|
||||
|
||||
if [[ $RET -eq 0 && $err -ne 0 ]]; then
|
||||
RET=$err
|
||||
retmsg=$msg
|
||||
if ((err)); then
|
||||
if [[ $FAIL_TO_XFAIL = yes ]]; then
|
||||
ret_set_ksft_status $ksft_xfail "$msg"
|
||||
else
|
||||
ret_set_ksft_status $ksft_fail "$msg"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -374,10 +434,7 @@ check_fail()
|
||||
local err=$1
|
||||
local msg=$2
|
||||
|
||||
if [[ $RET -eq 0 && $err -eq 0 ]]; then
|
||||
RET=1
|
||||
retmsg=$msg
|
||||
fi
|
||||
check_err $((!err)) "$msg"
|
||||
}
|
||||
|
||||
check_err_fail()
|
||||
@ -393,6 +450,85 @@ check_err_fail()
|
||||
fi
|
||||
}
|
||||
|
||||
xfail_on_slow()
|
||||
{
|
||||
if [[ $KSFT_MACHINE_SLOW = yes ]]; then
|
||||
FAIL_TO_XFAIL=yes "$@"
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
xfail_on_veth()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local kind
|
||||
|
||||
kind=$(ip -j -d link show dev $dev |
|
||||
jq -r '.[].linkinfo.info_kind')
|
||||
if [[ $kind = veth ]]; then
|
||||
FAIL_TO_XFAIL=yes "$@"
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
log_test_result()
|
||||
{
|
||||
local test_name=$1; shift
|
||||
local opt_str=$1; shift
|
||||
local result=$1; shift
|
||||
local retmsg=$1; shift
|
||||
|
||||
printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result"
|
||||
if [[ $retmsg ]]; then
|
||||
printf "\t%s\n" "$retmsg"
|
||||
fi
|
||||
}
|
||||
|
||||
pause_on_fail()
|
||||
{
|
||||
if [[ $PAUSE_ON_FAIL == yes ]]; then
|
||||
echo "Hit enter to continue, 'q' to quit"
|
||||
read a
|
||||
[[ $a == q ]] && exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
handle_test_result_pass()
|
||||
{
|
||||
local test_name=$1; shift
|
||||
local opt_str=$1; shift
|
||||
|
||||
log_test_result "$test_name" "$opt_str" " OK "
|
||||
}
|
||||
|
||||
handle_test_result_fail()
|
||||
{
|
||||
local test_name=$1; shift
|
||||
local opt_str=$1; shift
|
||||
|
||||
log_test_result "$test_name" "$opt_str" FAIL "$retmsg"
|
||||
pause_on_fail
|
||||
}
|
||||
|
||||
handle_test_result_xfail()
|
||||
{
|
||||
local test_name=$1; shift
|
||||
local opt_str=$1; shift
|
||||
|
||||
log_test_result "$test_name" "$opt_str" XFAIL "$retmsg"
|
||||
pause_on_fail
|
||||
}
|
||||
|
||||
handle_test_result_skip()
|
||||
{
|
||||
local test_name=$1; shift
|
||||
local opt_str=$1; shift
|
||||
|
||||
log_test_result "$test_name" "$opt_str" SKIP "$retmsg"
|
||||
}
|
||||
|
||||
log_test()
|
||||
{
|
||||
local test_name=$1
|
||||
@ -402,31 +538,28 @@ log_test()
|
||||
opt_str="($opt_str)"
|
||||
fi
|
||||
|
||||
if [[ $RET -ne 0 ]]; then
|
||||
EXIT_STATUS=1
|
||||
printf "TEST: %-60s [FAIL]\n" "$test_name $opt_str"
|
||||
if [[ ! -z "$retmsg" ]]; then
|
||||
printf "\t%s\n" "$retmsg"
|
||||
fi
|
||||
if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
|
||||
echo "Hit enter to continue, 'q' to quit"
|
||||
read a
|
||||
[ "$a" = "q" ] && exit 1
|
||||
fi
|
||||
return 1
|
||||
if ((RET == ksft_pass)); then
|
||||
handle_test_result_pass "$test_name" "$opt_str"
|
||||
elif ((RET == ksft_xfail)); then
|
||||
handle_test_result_xfail "$test_name" "$opt_str"
|
||||
elif ((RET == ksft_skip)); then
|
||||
handle_test_result_skip "$test_name" "$opt_str"
|
||||
else
|
||||
handle_test_result_fail "$test_name" "$opt_str"
|
||||
fi
|
||||
|
||||
printf "TEST: %-60s [ OK ]\n" "$test_name $opt_str"
|
||||
return 0
|
||||
EXIT_STATUS=$(ksft_exit_status_merge $EXIT_STATUS $RET)
|
||||
return $RET
|
||||
}
|
||||
|
||||
log_test_skip()
|
||||
{
|
||||
local test_name=$1
|
||||
local opt_str=$2
|
||||
RET=$ksft_skip retmsg= log_test "$@"
|
||||
}
|
||||
|
||||
printf "TEST: %-60s [SKIP]\n" "$test_name $opt_str"
|
||||
return 0
|
||||
log_test_xfail()
|
||||
{
|
||||
RET=$ksft_xfail retmsg= log_test "$@"
|
||||
}
|
||||
|
||||
log_info()
|
||||
|
208
tools/testing/selftests/net/forwarding/lib_sh_test.sh
Executable file
208
tools/testing/selftests/net/forwarding/lib_sh_test.sh
Executable file
@ -0,0 +1,208 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# This tests the operation of lib.sh itself.
|
||||
|
||||
ALL_TESTS="
|
||||
test_ret
|
||||
test_exit_status
|
||||
"
|
||||
NUM_NETIFS=0
|
||||
source lib.sh
|
||||
|
||||
# Simulated checks.
|
||||
|
||||
do_test()
|
||||
{
|
||||
local msg=$1; shift
|
||||
|
||||
"$@"
|
||||
check_err $? "$msg"
|
||||
}
|
||||
|
||||
tpass()
|
||||
{
|
||||
do_test "tpass" true
|
||||
}
|
||||
|
||||
tfail()
|
||||
{
|
||||
do_test "tfail" false
|
||||
}
|
||||
|
||||
txfail()
|
||||
{
|
||||
FAIL_TO_XFAIL=yes do_test "txfail" false
|
||||
}
|
||||
|
||||
# Simulated tests.
|
||||
|
||||
pass()
|
||||
{
|
||||
RET=0
|
||||
do_test "true" true
|
||||
log_test "true"
|
||||
}
|
||||
|
||||
fail()
|
||||
{
|
||||
RET=0
|
||||
do_test "false" false
|
||||
log_test "false"
|
||||
}
|
||||
|
||||
xfail()
|
||||
{
|
||||
RET=0
|
||||
FAIL_TO_XFAIL=yes do_test "xfalse" false
|
||||
log_test "xfalse"
|
||||
}
|
||||
|
||||
skip()
|
||||
{
|
||||
RET=0
|
||||
log_test_skip "skip"
|
||||
}
|
||||
|
||||
slow_xfail()
|
||||
{
|
||||
RET=0
|
||||
xfail_on_slow do_test "slow_false" false
|
||||
log_test "slow_false"
|
||||
}
|
||||
|
||||
# lib.sh tests.
|
||||
|
||||
ret_tests_run()
|
||||
{
|
||||
local t
|
||||
|
||||
RET=0
|
||||
retmsg=
|
||||
for t in "$@"; do
|
||||
$t
|
||||
done
|
||||
echo "$retmsg"
|
||||
return $RET
|
||||
}
|
||||
|
||||
ret_subtest()
|
||||
{
|
||||
local expect_ret=$1; shift
|
||||
local expect_retmsg=$1; shift
|
||||
local -a tests=( "$@" )
|
||||
|
||||
local status_names=(pass fail xfail xpass skip)
|
||||
local ret
|
||||
local out
|
||||
|
||||
RET=0
|
||||
|
||||
# Run this in a subshell, so that our environment is intact.
|
||||
out=$(ret_tests_run "${tests[@]}")
|
||||
ret=$?
|
||||
|
||||
(( ret == expect_ret ))
|
||||
check_err $? "RET=$ret expected $expect_ret"
|
||||
|
||||
[[ $out == $expect_retmsg ]]
|
||||
check_err $? "retmsg=$out expected $expect_retmsg"
|
||||
|
||||
log_test "RET $(echo ${tests[@]}) -> ${status_names[$ret]}"
|
||||
}
|
||||
|
||||
test_ret()
|
||||
{
|
||||
ret_subtest $ksft_pass ""
|
||||
|
||||
ret_subtest $ksft_pass "" tpass
|
||||
ret_subtest $ksft_fail "tfail" tfail
|
||||
ret_subtest $ksft_xfail "txfail" txfail
|
||||
|
||||
ret_subtest $ksft_pass "" tpass tpass
|
||||
ret_subtest $ksft_fail "tfail" tpass tfail
|
||||
ret_subtest $ksft_xfail "txfail" tpass txfail
|
||||
|
||||
ret_subtest $ksft_fail "tfail" tfail tpass
|
||||
ret_subtest $ksft_xfail "txfail" txfail tpass
|
||||
|
||||
ret_subtest $ksft_fail "tfail" tfail tfail
|
||||
ret_subtest $ksft_fail "tfail" tfail txfail
|
||||
|
||||
ret_subtest $ksft_fail "tfail" txfail tfail
|
||||
|
||||
ret_subtest $ksft_xfail "txfail" txfail txfail
|
||||
}
|
||||
|
||||
exit_status_tests_run()
|
||||
{
|
||||
EXIT_STATUS=0
|
||||
tests_run > /dev/null
|
||||
return $EXIT_STATUS
|
||||
}
|
||||
|
||||
exit_status_subtest()
|
||||
{
|
||||
local expect_exit_status=$1; shift
|
||||
local tests=$1; shift
|
||||
local what=$1; shift
|
||||
|
||||
local status_names=(pass fail xfail xpass skip)
|
||||
local exit_status
|
||||
local out
|
||||
|
||||
RET=0
|
||||
|
||||
# Run this in a subshell, so that our environment is intact.
|
||||
out=$(TESTS="$tests" exit_status_tests_run)
|
||||
exit_status=$?
|
||||
|
||||
(( exit_status == expect_exit_status ))
|
||||
check_err $? "EXIT_STATUS=$exit_status, expected $expect_exit_status"
|
||||
|
||||
log_test "EXIT_STATUS $tests$what -> ${status_names[$exit_status]}"
|
||||
}
|
||||
|
||||
test_exit_status()
|
||||
{
|
||||
exit_status_subtest $ksft_pass ":"
|
||||
|
||||
exit_status_subtest $ksft_pass "pass"
|
||||
exit_status_subtest $ksft_fail "fail"
|
||||
exit_status_subtest $ksft_pass "xfail"
|
||||
exit_status_subtest $ksft_skip "skip"
|
||||
|
||||
exit_status_subtest $ksft_pass "pass pass"
|
||||
exit_status_subtest $ksft_fail "pass fail"
|
||||
exit_status_subtest $ksft_pass "pass xfail"
|
||||
exit_status_subtest $ksft_skip "pass skip"
|
||||
|
||||
exit_status_subtest $ksft_fail "fail pass"
|
||||
exit_status_subtest $ksft_pass "xfail pass"
|
||||
exit_status_subtest $ksft_skip "skip pass"
|
||||
|
||||
exit_status_subtest $ksft_fail "fail fail"
|
||||
exit_status_subtest $ksft_fail "fail xfail"
|
||||
exit_status_subtest $ksft_fail "fail skip"
|
||||
|
||||
exit_status_subtest $ksft_fail "xfail fail"
|
||||
exit_status_subtest $ksft_fail "skip fail"
|
||||
|
||||
exit_status_subtest $ksft_pass "xfail xfail"
|
||||
exit_status_subtest $ksft_skip "xfail skip"
|
||||
exit_status_subtest $ksft_skip "skip xfail"
|
||||
|
||||
exit_status_subtest $ksft_skip "skip skip"
|
||||
|
||||
KSFT_MACHINE_SLOW=yes \
|
||||
exit_status_subtest $ksft_pass "slow_xfail" ": slow"
|
||||
|
||||
KSFT_MACHINE_SLOW=no \
|
||||
exit_status_subtest $ksft_fail "slow_xfail" ": fast"
|
||||
}
|
||||
|
||||
trap pre_cleanup EXIT
|
||||
|
||||
tests_run
|
||||
|
||||
exit $EXIT_STATUS
|
@ -56,21 +56,12 @@ nh_stats_test_dispatch_swhw()
|
||||
local group_id=$1; shift
|
||||
local mz="$@"
|
||||
|
||||
local used
|
||||
|
||||
nh_stats_do_test "$what" "$nh1_id" "$nh2_id" "$group_id" \
|
||||
nh_stats_get "${mz[@]}"
|
||||
|
||||
used=$(ip -s -j -d nexthop show id $group_id |
|
||||
jq '.[].hw_stats.used')
|
||||
kind=$(ip -j -d link show dev $rp11 |
|
||||
jq -r '.[].linkinfo.info_kind')
|
||||
if [[ $used == true ]]; then
|
||||
xfail_on_veth $rp11 \
|
||||
nh_stats_do_test "HW $what" "$nh1_id" "$nh2_id" "$group_id" \
|
||||
nh_stats_get_hw "${mz[@]}"
|
||||
elif [[ $kind == veth ]]; then
|
||||
log_test_skip "HW stats not offloaded on veth topology"
|
||||
fi
|
||||
}
|
||||
|
||||
nh_stats_test_dispatch()
|
||||
@ -83,7 +74,6 @@ nh_stats_test_dispatch()
|
||||
local mz="$@"
|
||||
|
||||
local enabled
|
||||
local kind
|
||||
|
||||
if ! ip nexthop help 2>&1 | grep -q hw_stats; then
|
||||
log_test_skip "NH stats test: ip doesn't support HW stats"
|
||||
|
@ -199,25 +199,28 @@ ets_set_dwrr_two_bands()
|
||||
ets_test_strict()
|
||||
{
|
||||
ets_set_strict
|
||||
ets_dwrr_test_01
|
||||
ets_dwrr_test_12
|
||||
xfail_on_slow ets_dwrr_test_01
|
||||
xfail_on_slow ets_dwrr_test_12
|
||||
}
|
||||
|
||||
ets_test_mixed()
|
||||
{
|
||||
ets_set_mixed
|
||||
ets_dwrr_test_01
|
||||
ets_dwrr_test_12
|
||||
xfail_on_slow ets_dwrr_test_01
|
||||
xfail_on_slow ets_dwrr_test_12
|
||||
}
|
||||
|
||||
ets_test_dwrr()
|
||||
{
|
||||
ets_set_dwrr_uniform
|
||||
ets_dwrr_test_012
|
||||
xfail_on_slow ets_dwrr_test_012
|
||||
|
||||
ets_set_dwrr_varying
|
||||
ets_dwrr_test_012
|
||||
xfail_on_slow ets_dwrr_test_012
|
||||
|
||||
ets_change_quantum
|
||||
ets_dwrr_test_012
|
||||
xfail_on_slow ets_dwrr_test_012
|
||||
|
||||
ets_set_dwrr_two_bands
|
||||
ets_dwrr_test_01
|
||||
xfail_on_slow ets_dwrr_test_01
|
||||
}
|
||||
|
@ -451,35 +451,35 @@ uninstall_qdisc()
|
||||
ecn_test()
|
||||
{
|
||||
install_qdisc ecn
|
||||
do_ecn_test $BACKLOG
|
||||
xfail_on_slow do_ecn_test $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
ecn_nodrop_test()
|
||||
{
|
||||
install_qdisc ecn nodrop
|
||||
do_ecn_nodrop_test $BACKLOG
|
||||
xfail_on_slow do_ecn_nodrop_test $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
red_test()
|
||||
{
|
||||
install_qdisc
|
||||
do_red_test $BACKLOG
|
||||
xfail_on_slow do_red_test $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
red_qevent_test()
|
||||
{
|
||||
install_qdisc qevent early_drop block 10
|
||||
do_red_qevent_test $BACKLOG
|
||||
xfail_on_slow do_red_qevent_test $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
ecn_qevent_test()
|
||||
{
|
||||
install_qdisc ecn qevent mark block 10
|
||||
do_ecn_qevent_test $BACKLOG
|
||||
xfail_on_slow do_ecn_qevent_test $BACKLOG
|
||||
uninstall_qdisc
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ do_tbf_test()
|
||||
local nr=$(rate $t2 $t3 10)
|
||||
local nr_pct=$((100 * (nr - er) / er))
|
||||
((-5 <= nr_pct && nr_pct <= 5))
|
||||
check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-5%."
|
||||
xfail_on_slow check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-5%."
|
||||
|
||||
log_test "TC $((vlan - 10)): TBF rate ${mbit}Mbit"
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
CHECK_TC="yes"
|
||||
|
||||
# Can be overridden by the configuration file. See lib.sh
|
||||
TC_HIT_TIMEOUT=${TC_HIT_TIMEOUT:=1000} # ms
|
||||
: "${TC_HIT_TIMEOUT:=1000}" # ms
|
||||
|
||||
tc_check_packets()
|
||||
{
|
||||
|
@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
ALL_TESTS="tunnel_key_nofrag_test"
|
||||
|
||||
|
@ -4,16 +4,60 @@
|
||||
##############################################################################
|
||||
# Defines
|
||||
|
||||
WAIT_TIMEOUT=${WAIT_TIMEOUT:=20}
|
||||
: "${WAIT_TIMEOUT:=20}"
|
||||
|
||||
BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
# Kselftest framework constants.
|
||||
ksft_pass=0
|
||||
ksft_fail=1
|
||||
ksft_xfail=2
|
||||
ksft_skip=4
|
||||
|
||||
# namespace list created by setup_ns
|
||||
NS_LIST=""
|
||||
|
||||
##############################################################################
|
||||
# Helpers
|
||||
|
||||
__ksft_status_merge()
|
||||
{
|
||||
local a=$1; shift
|
||||
local b=$1; shift
|
||||
local -A weights
|
||||
local weight=0
|
||||
|
||||
for i in "$@"; do
|
||||
weights[$i]=$((weight++))
|
||||
done
|
||||
|
||||
if [[ ${weights[$a]} > ${weights[$b]} ]]; then
|
||||
echo "$a"
|
||||
return 0
|
||||
else
|
||||
echo "$b"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
ksft_status_merge()
|
||||
{
|
||||
local a=$1; shift
|
||||
local b=$1; shift
|
||||
|
||||
__ksft_status_merge "$a" "$b" \
|
||||
$ksft_pass $ksft_xfail $ksft_skip $ksft_fail
|
||||
}
|
||||
|
||||
ksft_exit_status_merge()
|
||||
{
|
||||
local a=$1; shift
|
||||
local b=$1; shift
|
||||
|
||||
__ksft_status_merge "$a" "$b" \
|
||||
$ksft_xfail $ksft_pass $ksft_skip $ksft_fail
|
||||
}
|
||||
|
||||
busywait()
|
||||
{
|
||||
local timeout=$1; shift
|
||||
|
Loading…
x
Reference in New Issue
Block a user