1#! /bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4readonly KSFT_PASS=0 5readonly KSFT_FAIL=1 6readonly KSFT_SKIP=4 7 8# shellcheck disable=SC2155 # declare and assign separately 9readonly KSFT_TEST=$(basename "${0}" | sed 's/\.sh$//g') 10 11MPTCP_LIB_SUBTESTS=() 12 13# only if supported (or forced) and not disabled, see no-color.org 14if { [ -t 1 ] || [ "${SELFTESTS_MPTCP_LIB_COLOR_FORCE:-}" = "1" ]; } && 15 [ "${NO_COLOR:-}" != "1" ]; then 16 readonly MPTCP_LIB_COLOR_RED="\E[1;31m" 17 readonly MPTCP_LIB_COLOR_GREEN="\E[1;32m" 18 readonly MPTCP_LIB_COLOR_YELLOW="\E[1;33m" 19 readonly MPTCP_LIB_COLOR_BLUE="\E[1;34m" 20 readonly MPTCP_LIB_COLOR_RESET="\E[0m" 21else 22 readonly MPTCP_LIB_COLOR_RED= 23 readonly MPTCP_LIB_COLOR_GREEN= 24 readonly MPTCP_LIB_COLOR_YELLOW= 25 readonly MPTCP_LIB_COLOR_BLUE= 26 readonly MPTCP_LIB_COLOR_RESET= 27fi 28 29# $1: color, $2: text 30mptcp_lib_print_color() { 31 echo -e "${MPTCP_LIB_START_PRINT:-}${*}${MPTCP_LIB_COLOR_RESET}" 32} 33 34mptcp_lib_print_ok() { 35 mptcp_lib_print_color "${MPTCP_LIB_COLOR_GREEN}${*}" 36} 37 38mptcp_lib_print_warn() { 39 mptcp_lib_print_color "${MPTCP_LIB_COLOR_YELLOW}${*}" 40} 41 42mptcp_lib_print_info() { 43 mptcp_lib_print_color "${MPTCP_LIB_COLOR_BLUE}${*}" 44} 45 46mptcp_lib_print_err() { 47 mptcp_lib_print_color "${MPTCP_LIB_COLOR_RED}${*}" 48} 49 50# SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES env var can be set when validating all 51# features using the last version of the kernel and the selftests to make sure 52# a test is not being skipped by mistake. 53mptcp_lib_expect_all_features() { 54 [ "${SELFTESTS_MPTCP_LIB_EXPECT_ALL_FEATURES:-}" = "1" ] 55} 56 57# $1: msg 58mptcp_lib_fail_if_expected_feature() { 59 if mptcp_lib_expect_all_features; then 60 echo "ERROR: missing feature: ${*}" 61 exit ${KSFT_FAIL} 62 fi 63 64 return 1 65} 66 67# $1: file 68mptcp_lib_has_file() { 69 local f="${1}" 70 71 if [ -f "${f}" ]; then 72 return 0 73 fi 74 75 mptcp_lib_fail_if_expected_feature "${f} file not found" 76} 77 78mptcp_lib_check_mptcp() { 79 if ! mptcp_lib_has_file "/proc/sys/net/mptcp/enabled"; then 80 echo "SKIP: MPTCP support is not available" 81 exit ${KSFT_SKIP} 82 fi 83} 84 85mptcp_lib_check_kallsyms() { 86 if ! mptcp_lib_has_file "/proc/kallsyms"; then 87 echo "SKIP: CONFIG_KALLSYMS is missing" 88 exit ${KSFT_SKIP} 89 fi 90} 91 92# Internal: use mptcp_lib_kallsyms_has() instead 93__mptcp_lib_kallsyms_has() { 94 local sym="${1}" 95 96 mptcp_lib_check_kallsyms 97 98 grep -q " ${sym}" /proc/kallsyms 99} 100 101# $1: part of a symbol to look at, add '$' at the end for full name 102mptcp_lib_kallsyms_has() { 103 local sym="${1}" 104 105 if __mptcp_lib_kallsyms_has "${sym}"; then 106 return 0 107 fi 108 109 mptcp_lib_fail_if_expected_feature "${sym} symbol not found" 110} 111 112# $1: part of a symbol to look at, add '$' at the end for full name 113mptcp_lib_kallsyms_doesnt_have() { 114 local sym="${1}" 115 116 if ! __mptcp_lib_kallsyms_has "${sym}"; then 117 return 0 118 fi 119 120 mptcp_lib_fail_if_expected_feature "${sym} symbol has been found" 121} 122 123# !!!AVOID USING THIS!!! 124# Features might not land in the expected version and features can be backported 125# 126# $1: kernel version, e.g. 6.3 127mptcp_lib_kversion_ge() { 128 local exp_maj="${1%.*}" 129 local exp_min="${1#*.}" 130 local v maj min 131 132 # If the kernel has backported features, set this env var to 1: 133 if [ "${SELFTESTS_MPTCP_LIB_NO_KVERSION_CHECK:-}" = "1" ]; then 134 return 0 135 fi 136 137 v=$(uname -r | cut -d'.' -f1,2) 138 maj=${v%.*} 139 min=${v#*.} 140 141 if [ "${maj}" -gt "${exp_maj}" ] || 142 { [ "${maj}" -eq "${exp_maj}" ] && [ "${min}" -ge "${exp_min}" ]; }; then 143 return 0 144 fi 145 146 mptcp_lib_fail_if_expected_feature "kernel version ${1} lower than ${v}" 147} 148 149__mptcp_lib_result_add() { 150 local result="${1}" 151 shift 152 153 local id=$((${#MPTCP_LIB_SUBTESTS[@]} + 1)) 154 155 MPTCP_LIB_SUBTESTS+=("${result} ${id} - ${KSFT_TEST}: ${*}") 156} 157 158# $1: test name 159mptcp_lib_result_pass() { 160 __mptcp_lib_result_add "ok" "${1}" 161} 162 163# $1: test name 164mptcp_lib_result_fail() { 165 __mptcp_lib_result_add "not ok" "${1}" 166} 167 168# $1: test name 169mptcp_lib_result_skip() { 170 __mptcp_lib_result_add "ok" "${1} # SKIP" 171} 172 173# $1: result code ; $2: test name 174mptcp_lib_result_code() { 175 local ret="${1}" 176 local name="${2}" 177 178 case "${ret}" in 179 "${KSFT_PASS}") 180 mptcp_lib_result_pass "${name}" 181 ;; 182 "${KSFT_FAIL}") 183 mptcp_lib_result_fail "${name}" 184 ;; 185 "${KSFT_SKIP}") 186 mptcp_lib_result_skip "${name}" 187 ;; 188 *) 189 echo "ERROR: wrong result code: ${ret}" 190 exit ${KSFT_FAIL} 191 ;; 192 esac 193} 194 195mptcp_lib_result_print_all_tap() { 196 local subtest 197 198 if [ ${#MPTCP_LIB_SUBTESTS[@]} -eq 0 ] || 199 [ "${SELFTESTS_MPTCP_LIB_NO_TAP:-}" = "1" ]; then 200 return 201 fi 202 203 printf "\nTAP version 13\n" 204 printf "1..%d\n" "${#MPTCP_LIB_SUBTESTS[@]}" 205 206 for subtest in "${MPTCP_LIB_SUBTESTS[@]}"; do 207 printf "%s\n" "${subtest}" 208 done 209} 210