-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Vegard Nossum
authored and
David S. Miller
committed
Aug 9, 2024
1 parent
bc75dcc
commit 3ade6ce
Showing
8 changed files
with
605 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
all: | ||
@echo mk_build_dir="$(shell pwd)" > include.sh | ||
|
||
TEST_PROGS := run.sh \ | ||
include.sh \ | ||
test.py | ||
|
||
EXTRA_CLEAN := /tmp/rds_logs | ||
|
||
include ../../lib.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
RDS self-tests | ||
============== | ||
|
||
These scripts provide a coverage test for RDS-TCP by creating two | ||
network namespaces and running rds packets between them. A loopback | ||
network is provisioned with optional probability of packet loss or | ||
corruption. A workload of 50000 hashes, each 64 characters in size, | ||
are passed over an RDS socket on this test network. A passing test means | ||
the RDS-TCP stack was able to recover properly. The provided config.sh | ||
can be used to compile the kernel with the necessary gcov options. The | ||
kernel may optionally be configured to omit the coverage report as well. | ||
|
||
USAGE: | ||
run.sh [-d logdir] [-l packet_loss] [-c packet_corruption] | ||
[-u packet_duplcate] | ||
|
||
OPTIONS: | ||
-d Log directory. Defaults to tools/testing/selftests/net/rds/rds_logs | ||
|
||
-l Simulates a percentage of packet loss | ||
|
||
-c Simulates a percentage of packet corruption | ||
|
||
-u Simulates a percentage of packet duplication. | ||
|
||
EXAMPLE: | ||
|
||
# Create a suitable gcov enabled .config | ||
tools/testing/selftests/net/rds/config.sh -g | ||
|
||
# Alternatly create a gcov disabled .config | ||
tools/testing/selftests/net/rds/config.sh | ||
|
||
# build the kernel | ||
vng --build --config tools/testing/selftests/net/config | ||
|
||
# launch the tests in a VM | ||
vng -v --rwdir ./ --run . --user root --cpus 4 -- \ | ||
"export PYTHONPATH=tools/testing/selftests/net/; tools/testing/selftests/net/rds/run.sh" | ||
|
||
An HTML coverage report will be output in tools/testing/selftests/net/rds/rds_logs/coverage/. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#! /bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
set -e | ||
set -u | ||
set -x | ||
|
||
unset KBUILD_OUTPUT | ||
|
||
GENERATE_GCOV_REPORT=0 | ||
while getopts "g" opt; do | ||
case ${opt} in | ||
g) | ||
GENERATE_GCOV_REPORT=1 | ||
;; | ||
:) | ||
echo "USAGE: config.sh [-g]" | ||
exit 1 | ||
;; | ||
?) | ||
echo "Invalid option: -${OPTARG}." | ||
exit 1 | ||
;; | ||
esac | ||
done | ||
|
||
CONF_FILE="tools/testing/selftests/net/config" | ||
|
||
# no modules | ||
scripts/config --file "$CONF_FILE" --disable CONFIG_MODULES | ||
|
||
# enable RDS | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_RDS | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_RDS_TCP | ||
|
||
if [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then | ||
# instrument RDS and only RDS | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_GCOV_KERNEL | ||
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_ALL | ||
scripts/config --file "$CONF_FILE" --enable GCOV_PROFILE_RDS | ||
else | ||
scripts/config --file "$CONF_FILE" --disable CONFIG_GCOV_KERNEL | ||
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_ALL | ||
scripts/config --file "$CONF_FILE" --disable GCOV_PROFILE_RDS | ||
fi | ||
|
||
# need network namespaces to run tests with veth network interfaces | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_NET_NS | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_VETH | ||
|
||
# simulate packet loss | ||
scripts/config --file "$CONF_FILE" --enable CONFIG_NET_SCH_NETEM | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
#! /bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
|
||
set -e | ||
set -u | ||
|
||
unset KBUILD_OUTPUT | ||
|
||
current_dir="$(realpath "$(dirname "$0")")" | ||
build_dir="$current_dir" | ||
|
||
build_include="$current_dir/include.sh" | ||
if test -f "$build_include"; then | ||
# this include will define "$mk_build_dir" as the location the test was | ||
# built. We will need this if the tests are installed in a location | ||
# other than the kernel source | ||
|
||
source "$build_include" | ||
build_dir="$mk_build_dir" | ||
fi | ||
|
||
# This test requires kernel source and the *.gcda data therein | ||
# Locate the top level of the kernel source, and the net/rds | ||
# subfolder with the appropriate *.gcno object files | ||
ksrc_dir="$(realpath "$build_dir"/../../../../../)" | ||
kconfig="$ksrc_dir/.config" | ||
obj_dir="$ksrc_dir/net/rds" | ||
|
||
GCOV_CMD=gcov | ||
|
||
#check to see if the host has the required packages to generate a gcov report | ||
check_gcov_env() | ||
{ | ||
if ! which "$GCOV_CMD" > /dev/null 2>&1; then | ||
echo "Warning: Could not find gcov. " | ||
GENERATE_GCOV_REPORT=0 | ||
return | ||
fi | ||
|
||
# the gcov version must match the gcc version | ||
GCC_VER=$(gcc -dumpfullversion) | ||
GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| awk 'BEGIN {FS="-"}{print $1}') | ||
if [ "$GCOV_VER" != "$GCC_VER" ]; then | ||
#attempt to find a matching gcov version | ||
GCOV_CMD=gcov-$(gcc -dumpversion) | ||
|
||
if ! which "$GCOV_CMD" > /dev/null 2>&1; then | ||
echo "Warning: Could not find an appropriate gcov installation. \ | ||
gcov version must match gcc version" | ||
GENERATE_GCOV_REPORT=0 | ||
return | ||
fi | ||
|
||
#recheck version number of found gcov executable | ||
GCOV_VER=$($GCOV_CMD -v | grep gcov | awk '{print $3}'| \ | ||
awk 'BEGIN {FS="-"}{print $1}') | ||
if [ "$GCOV_VER" != "$GCC_VER" ]; then | ||
echo "Warning: Could not find an appropriate gcov installation. \ | ||
gcov version must match gcc version" | ||
GENERATE_GCOV_REPORT=0 | ||
else | ||
echo "Warning: Mismatched gcc and gcov detected. Using $GCOV_CMD" | ||
fi | ||
fi | ||
} | ||
|
||
# Check to see if the kconfig has the required configs to generate a coverage report | ||
check_gcov_conf() | ||
{ | ||
if ! grep -x "CONFIG_GCOV_PROFILE_RDS=y" "$kconfig" > /dev/null 2>&1; then | ||
echo "INFO: CONFIG_GCOV_PROFILE_RDS should be enabled for coverage reports" | ||
GENERATE_GCOV_REPORT=0 | ||
fi | ||
if ! grep -x "CONFIG_GCOV_KERNEL=y" "$kconfig" > /dev/null 2>&1; then | ||
echo "INFO: CONFIG_GCOV_KERNEL should be enabled for coverage reports" | ||
GENERATE_GCOV_REPORT=0 | ||
fi | ||
if grep -x "CONFIG_GCOV_PROFILE_ALL=y" "$kconfig" > /dev/null 2>&1; then | ||
echo "INFO: CONFIG_GCOV_PROFILE_ALL should be disabled for coverage reports" | ||
GENERATE_GCOV_REPORT=0 | ||
fi | ||
|
||
if [ "$GENERATE_GCOV_REPORT" -eq 0 ]; then | ||
echo "To enable gcov reports, please run "\ | ||
"\"tools/testing/selftests/net/rds/config.sh -g\" and rebuild the kernel" | ||
else | ||
# if we have the required kernel configs, proceed to check the environment to | ||
# ensure we have the required gcov packages | ||
check_gcov_env | ||
fi | ||
} | ||
|
||
# Kselftest framework requirement - SKIP code is 4. | ||
check_conf_enabled() { | ||
if ! grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then | ||
echo "selftests: [SKIP] This test requires $1 enabled" | ||
echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel" | ||
exit 4 | ||
fi | ||
} | ||
check_conf_disabled() { | ||
if grep -x "$1=y" "$kconfig" > /dev/null 2>&1; then | ||
echo "selftests: [SKIP] This test requires $1 disabled" | ||
echo "Please run tools/testing/selftests/net/rds/config.sh and rebuild the kernel" | ||
exit 4 | ||
fi | ||
} | ||
check_conf() { | ||
check_conf_enabled CONFIG_NET_SCH_NETEM | ||
check_conf_enabled CONFIG_VETH | ||
check_conf_enabled CONFIG_NET_NS | ||
check_conf_enabled CONFIG_RDS_TCP | ||
check_conf_enabled CONFIG_RDS | ||
check_conf_disabled CONFIG_MODULES | ||
} | ||
|
||
check_env() | ||
{ | ||
if ! test -d "$obj_dir"; then | ||
echo "selftests: [SKIP] This test requires a kernel source tree" | ||
exit 4 | ||
fi | ||
if ! test -e "$kconfig"; then | ||
echo "selftests: [SKIP] This test requires a configured kernel source tree" | ||
exit 4 | ||
fi | ||
if ! which strace > /dev/null 2>&1; then | ||
echo "selftests: [SKIP] Could not run test without strace" | ||
exit 4 | ||
fi | ||
if ! which tcpdump > /dev/null 2>&1; then | ||
echo "selftests: [SKIP] Could not run test without tcpdump" | ||
exit 4 | ||
fi | ||
|
||
if ! which python3 > /dev/null 2>&1; then | ||
echo "selftests: [SKIP] Could not run test without python3" | ||
exit 4 | ||
fi | ||
|
||
python_major=$(python3 -c "import sys; print(sys.version_info[0])") | ||
python_minor=$(python3 -c "import sys; print(sys.version_info[1])") | ||
if [[ python_major -lt 3 || ( python_major -eq 3 && python_minor -lt 9 ) ]] ; then | ||
echo "selftests: [SKIP] Could not run test without at least python3.9" | ||
python3 -V | ||
exit 4 | ||
fi | ||
} | ||
|
||
LOG_DIR="$current_dir"/rds_logs | ||
PLOSS=0 | ||
PCORRUPT=0 | ||
PDUP=0 | ||
GENERATE_GCOV_REPORT=1 | ||
while getopts "d:l:c:u:" opt; do | ||
case ${opt} in | ||
d) | ||
LOG_DIR=${OPTARG} | ||
;; | ||
l) | ||
PLOSS=${OPTARG} | ||
;; | ||
c) | ||
PCORRUPT=${OPTARG} | ||
;; | ||
u) | ||
PDUP=${OPTARG} | ||
;; | ||
:) | ||
echo "USAGE: run.sh [-d logdir] [-l packet_loss] [-c packet_corruption]" \ | ||
"[-u packet_duplcate] [-g]" | ||
exit 1 | ||
;; | ||
?) | ||
echo "Invalid option: -${OPTARG}." | ||
exit 1 | ||
;; | ||
esac | ||
done | ||
|
||
|
||
check_env | ||
check_conf | ||
check_gcov_conf | ||
|
||
|
||
rm -fr "$LOG_DIR" | ||
TRACE_FILE="${LOG_DIR}/rds-strace.txt" | ||
COVR_DIR="${LOG_DIR}/coverage/" | ||
mkdir -p "$LOG_DIR" | ||
mkdir -p "$COVR_DIR" | ||
|
||
set +e | ||
echo running RDS tests... | ||
echo Traces will be logged to "$TRACE_FILE" | ||
rm -f "$TRACE_FILE" | ||
strace -T -tt -o "$TRACE_FILE" python3 "$(dirname "$0")/test.py" --timeout 400 -d "$LOG_DIR" \ | ||
-l "$PLOSS" -c "$PCORRUPT" -u "$PDUP" | ||
|
||
test_rc=$? | ||
dmesg > "${LOG_DIR}/dmesg.out" | ||
|
||
if [ "$GENERATE_GCOV_REPORT" -eq 1 ]; then | ||
echo saving coverage data... | ||
(set +x; cd /sys/kernel/debug/gcov; find ./* -name '*.gcda' | \ | ||
while read -r f | ||
do | ||
cat < "/sys/kernel/debug/gcov/$f" > "/$f" | ||
done) | ||
|
||
echo running gcovr... | ||
gcovr -s --html-details --gcov-executable "$GCOV_CMD" --gcov-ignore-parse-errors \ | ||
-o "${COVR_DIR}/gcovr" "${ksrc_dir}/net/rds/" | ||
else | ||
echo "Coverage report will be skipped" | ||
fi | ||
|
||
if [ "$test_rc" -eq 0 ]; then | ||
echo "PASS: Test completed successfully" | ||
else | ||
echo "FAIL: Test failed" | ||
fi | ||
|
||
exit "$test_rc" |
Oops, something went wrong.