Skip to content

Commit 3ade6ce

Browse files
vegarddavem330
authored andcommitted
selftests: rds: add testing infrastructure
This adds some basic self-testing infrastructure for RDS-TCP. Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Allison Henderson <allison.henderson@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent bc75dcc commit 3ade6ce

File tree

8 files changed

+605
-0
lines changed

8 files changed

+605
-0
lines changed

Documentation/dev-tools/gcov.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ Only files which are linked to the main kernel image or are compiled as
7575
kernel modules are supported by this mechanism.
7676

7777

78+
Module specific configs
79+
-----------------------
80+
81+
Gcov kernel configs for specific modules are described below:
82+
83+
CONFIG_GCOV_PROFILE_RDS:
84+
Enables GCOV profiling on RDS for checking which functions or
85+
lines are executed. This config is used by the rds selftest to
86+
generate coverage reports. If left unset the report is omitted.
87+
88+
7889
Files
7990
-----
8091

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19197,6 +19197,7 @@ S: Supported
1919719197
W: https://oss.oracle.com/projects/rds/
1919819198
F: Documentation/networking/rds.rst
1919919199
F: net/rds/
19200+
F: tools/testing/selftests/net/rds/
1920019201

1920119202
RDT - RESOURCE ALLOCATION
1920219203
M: Fenghua Yu <fenghua.yu@intel.com>

tools/testing/selftests/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ TARGETS += net/mptcp
6868
TARGETS += net/openvswitch
6969
TARGETS += net/tcp_ao
7070
TARGETS += net/netfilter
71+
TARGETS += net/rds
7172
TARGETS += nsfs
7273
TARGETS += perf_events
7374
TARGETS += pidfd
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
all:
4+
@echo mk_build_dir="$(shell pwd)" > include.sh
5+
6+
TEST_PROGS := run.sh \
7+
include.sh \
8+
test.py
9+
10+
EXTRA_CLEAN := /tmp/rds_logs
11+
12+
include ../../lib.mk
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
RDS self-tests
2+
==============
3+
4+
These scripts provide a coverage test for RDS-TCP by creating two
5+
network namespaces and running rds packets between them. A loopback
6+
network is provisioned with optional probability of packet loss or
7+
corruption. A workload of 50000 hashes, each 64 characters in size,
8+
are passed over an RDS socket on this test network. A passing test means
9+
the RDS-TCP stack was able to recover properly. The provided config.sh
10+
can be used to compile the kernel with the necessary gcov options. The
11+
kernel may optionally be configured to omit the coverage report as well.
12+
13+
USAGE:
14+
run.sh [-d logdir] [-l packet_loss] [-c packet_corruption]
15+
[-u packet_duplcate]
16+
17+
OPTIONS:
18+
-d Log directory. Defaults to tools/testing/selftests/net/rds/rds_logs
19+
20+
-l Simulates a percentage of packet loss
21+
22+
-c Simulates a percentage of packet corruption
23+
24+
-u Simulates a percentage of packet duplication.
25+
26+
EXAMPLE:
27+
28+
# Create a suitable gcov enabled .config
29+
tools/testing/selftests/net/rds/config.sh -g
30+
31+
# Alternatly create a gcov disabled .config
32+
tools/testing/selftests/net/rds/config.sh
33+
34+
# build the kernel
35+
vng --build --config tools/testing/selftests/net/config
36+
37+
# launch the tests in a VM
38+
vng -v --rwdir ./ --run . --user root --cpus 4 -- \
39+
"export PYTHONPATH=tools/testing/selftests/net/; tools/testing/selftests/net/rds/run.sh"
40+
41+
An HTML coverage report will be output in tools/testing/selftests/net/rds/rds_logs/coverage/.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#! /bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
set -e
5+
set -u
6+
set -x
7+
8+
unset KBUILD_OUTPUT
9+
10+
GENERATE_GCOV_REPORT=0
11+
while getopts "g" opt; do
12+
case ${opt} in
13+
g)
14+
GENERATE_GCOV_REPORT=1
15+
;;
16+
:)
17+
echo "USAGE: config.sh [-g]"
18+
exit 1
19+
;;
20+
?)
21+
echo "Invalid option: -${OPTARG}."
22+
exit 1
23+
;;
24+
esac
25+
done
26+
27+
CONF_FILE="tools/testing/selftests/net/config"
28+
29+
# no modules
30+
scripts/config --file "$CONF_FILE" --disable CONFIG_MODULES
31+
32+
# enable RDS
33+
scripts/config --file "$CONF_FILE" --enable CONFIG_RDS
34+
scripts/config --file "$CONF_FILE" --enable CONFIG_RDS_TCP
35+
36+
if [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then
37+
# instrument RDS and only RDS
38+
scripts/config --file "$CONF_FILE" --enable CONFIG_GCOV_KERNEL
39+
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_ALL
40+
scripts/config --file "$CONF_FILE" --enable GCOV_PROFILE_RDS
41+
else
42+
scripts/config --file "$CONF_FILE" --disable CONFIG_GCOV_KERNEL
43+
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_ALL
44+
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_RDS
45+
fi
46+
47+
# need network namespaces to run tests with veth network interfaces
48+
scripts/config --file "$CONF_FILE" --enable CONFIG_NET_NS
49+
scripts/config --file "$CONF_FILE" --enable CONFIG_VETH
50+
51+
# simulate packet loss
52+
scripts/config --file "$CONF_FILE" --enable CONFIG_NET_SCH_NETEM
53+
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#! /bin/bash
2+
# SPDX-License-Identifier: GPL-2.0
3+
4+
set -e
5+
set -u
6+
7+
unset KBUILD_OUTPUT
8+
9+
current_dir="$(realpath "$(dirname "$0")")"
10+
build_dir="$current_dir"
11+
12+
build_include="$current_dir/include.sh"
13+
if test -f "$build_include"; then
14+
# this include will define "$mk_build_dir" as the location the test was
15+
# built. We will need this if the tests are installed in a location
16+
# other than the kernel source
17+
18+
source "$build_include"
19+
build_dir="$mk_build_dir"
20+
fi
21+
22+
# This test requires kernel source and the *.gcda data therein
23+
# Locate the top level of the kernel source, and the net/rds
24+
# subfolder with the appropriate *.gcno object files
25+
ksrc_dir="$(realpath "$build_dir"/../../../../../)"
26+
kconfig="$ksrc_dir/.config"
27+
obj_dir="$ksrc_dir/net/rds"
28+
29+
GCOV_CMD=gcov
30+
31+
#check to see if the host has the required packages to generate a gcov report
32+
check_gcov_env()
33+
{
34+
if ! which "$GCOV_CMD" > /dev/null 2>&1; then
35+
echo "Warning: Could not find gcov. "
36+
GENERATE_GCOV_REPORT=0
37+
return
38+
fi
39+
40+
# the gcov version must match the gcc version
41+
GCC_VER=$(gcc -dumpfullversion)
42+
GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| awk 'BEGIN {FS="-"}{print $1}')
43+
if [ "$GCOV_VER" != "$GCC_VER" ]; then
44+
#attempt to find a matching gcov version
45+
GCOV_CMD=gcov-$(gcc -dumpversion)
46+
47+
if ! which "$GCOV_CMD" > /dev/null 2>&1; then
48+
echo "Warning: Could not find an appropriate gcov installation. \
49+
gcov version must match gcc version"
50+
GENERATE_GCOV_REPORT=0
51+
return
52+
fi
53+
54+
#recheck version number of found gcov executable
55+
GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| \
56+
awk 'BEGIN {FS="-"}{print $1}')
57+
if [ "$GCOV_VER" != "$GCC_VER" ]; then
58+
echo "Warning: Could not find an appropriate gcov installation. \
59+
gcov version must match gcc version"
60+
GENERATE_GCOV_REPORT=0
61+
else
62+
echo "Warning: Mismatched gcc and gcov detected. Using $GCOV_CMD"
63+
fi
64+
fi
65+
}
66+
67+
# Check to see if the kconfig has the required configs to generate a coverage report
68+
check_gcov_conf()
69+
{
70+
if ! grep -x "CONFIG_GCOV_PROFILE_RDS=y" "$kconfig" > /dev/null 2>&1; then
71+
echo "INFO: CONFIG_GCOV_PROFILE_RDS should be enabled for coverage reports"
72+
GENERATE_GCOV_REPORT=0
73+
fi
74+
if ! grep -x "CONFIG_GCOV_KERNEL=y" "$kconfig" > /dev/null 2>&1; then
75+
echo "INFO: CONFIG_GCOV_KERNEL should be enabled for coverage reports"
76+
GENERATE_GCOV_REPORT=0
77+
fi
78+
if grep -x "CONFIG_GCOV_PROFILE_ALL=y" "$kconfig" > /dev/null 2>&1; then
79+
echo "INFO: CONFIG_GCOV_PROFILE_ALL should be disabled for coverage reports"
80+
GENERATE_GCOV_REPORT=0
81+
fi
82+
83+
if [ "$GENERATE_GCOV_REPORT" -eq 0 ]; then
84+
echo "To enable gcov reports, please run "\
85+
"\"tools/testing/selftests/net/rds/config.sh -g\" and rebuild the kernel"
86+
else
87+
# if we have the required kernel configs, proceed to check the environment to
88+
# ensure we have the required gcov packages
89+
check_gcov_env
90+
fi
91+
}
92+
93+
# Kselftest framework requirement - SKIP code is 4.
94+
check_conf_enabled() {
95+
if ! grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then
96+
echo "selftests: [SKIP] This test requires $1 enabled"
97+
echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel"
98+
exit 4
99+
fi
100+
}
101+
check_conf_disabled() {
102+
if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then
103+
echo "selftests: [SKIP] This test requires $1 disabled"
104+
echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel"
105+
exit 4
106+
fi
107+
}
108+
check_conf() {
109+
check_conf_enabled CONFIG_NET_SCH_NETEM
110+
check_conf_enabled CONFIG_VETH
111+
check_conf_enabled CONFIG_NET_NS
112+
check_conf_enabled CONFIG_RDS_TCP
113+
check_conf_enabled CONFIG_RDS
114+
check_conf_disabled CONFIG_MODULES
115+
}
116+
117+
check_env()
118+
{
119+
if ! test -d "$obj_dir"; then
120+
echo "selftests: [SKIP] This test requires a kernel source tree"
121+
exit 4
122+
fi
123+
if ! test -e "$kconfig"; then
124+
echo "selftests: [SKIP] This test requires a configured kernel source tree"
125+
exit 4
126+
fi
127+
if ! which strace > /dev/null 2>&1; then
128+
echo "selftests: [SKIP] Could not run test without strace"
129+
exit 4
130+
fi
131+
if ! which tcpdump > /dev/null 2>&1; then
132+
echo "selftests: [SKIP] Could not run test without tcpdump"
133+
exit 4
134+
fi
135+
136+
if ! which python3 > /dev/null 2>&1; then
137+
echo "selftests: [SKIP] Could not run test without python3"
138+
exit 4
139+
fi
140+
141+
python_major=$(python3 -c "import sys; print(sys.version_info[0])")
142+
python_minor=$(python3 -c "import sys; print(sys.version_info[1])")
143+
if [[ python_major -lt 3 || ( python_major -eq 3 && python_minor -lt 9 ) ]] ; then
144+
echo "selftests: [SKIP] Could not run test without at least python3.9"
145+
python3 -V
146+
exit 4
147+
fi
148+
}
149+
150+
LOG_DIR="$current_dir"/rds_logs
151+
PLOSS=0
152+
PCORRUPT=0
153+
PDUP=0
154+
GENERATE_GCOV_REPORT=1
155+
while getopts "d:l:c:u:" opt; do
156+
case ${opt} in
157+
d)
158+
LOG_DIR=${OPTARG}
159+
;;
160+
l)
161+
PLOSS=${OPTARG}
162+
;;
163+
c)
164+
PCORRUPT=${OPTARG}
165+
;;
166+
u)
167+
PDUP=${OPTARG}
168+
;;
169+
:)
170+
echo "USAGE: run.sh [-d logdir] [-l packet_loss] [-c packet_corruption]" \
171+
"[-u packet_duplcate] [-g]"
172+
exit 1
173+
;;
174+
?)
175+
echo "Invalid option: -${OPTARG}."
176+
exit 1
177+
;;
178+
esac
179+
done
180+
181+
182+
check_env
183+
check_conf
184+
check_gcov_conf
185+
186+
187+
rm -fr "$LOG_DIR"
188+
TRACE_FILE="${LOG_DIR}/rds-strace.txt"
189+
COVR_DIR="${LOG_DIR}/coverage/"
190+
mkdir -p "$LOG_DIR"
191+
mkdir -p "$COVR_DIR"
192+
193+
set +e
194+
echo running RDS tests...
195+
echo Traces will be logged to "$TRACE_FILE"
196+
rm -f "$TRACE_FILE"
197+
strace -T -tt -o "$TRACE_FILE" python3 "$(dirname "$0")/test.py" --timeout 400 -d "$LOG_DIR" \
198+
-l "$PLOSS" -c "$PCORRUPT" -u "$PDUP"
199+
200+
test_rc=$?
201+
dmesg > "${LOG_DIR}/dmesg.out"
202+
203+
if [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then
204+
echo saving coverage data...
205+
(set +x; cd /sys/kernel/debug/gcov; find ./* -name '*.gcda' | \
206+
while read -r f
207+
do
208+
cat < "/sys/kernel/debug/gcov/$f" > "/$f"
209+
done)
210+
211+
echo running gcovr...
212+
gcovr -s --html-details --gcov-executable "$GCOV_CMD" --gcov-ignore-parse-errors \
213+
-o "${COVR_DIR}/gcovr" "${ksrc_dir}/net/rds/"
214+
else
215+
echo "Coverage report will be skipped"
216+
fi
217+
218+
if [ "$test_rc" -eq 0 ]; then
219+
echo "PASS: Test completed successfully"
220+
else
221+
echo "FAIL: Test failed"
222+
fi
223+
224+
exit "$test_rc"

0 commit comments

Comments
 (0)