| #! /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" |