drm/bridge: adv7511: Switch to atomic operations
[drm/drm-misc.git] / tools / testing / selftests / net / lib.sh
blob8994fec1c38f6e0bfb769b85f5a6e29b11e414a3
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
4 net_dir=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
5 source "$net_dir/lib/sh/defer.sh"
7 ##############################################################################
8 # Defines
10 : "${WAIT_TIMEOUT:=20}"
12 # Whether to pause on after a failure.
13 : "${PAUSE_ON_FAIL:=no}"
15 BUSYWAIT_TIMEOUT=$((WAIT_TIMEOUT * 1000)) # ms
17 # Kselftest framework constants.
18 ksft_pass=0
19 ksft_fail=1
20 ksft_xfail=2
21 ksft_skip=4
23 # namespace list created by setup_ns
24 NS_LIST=()
26 # Exit status to return at the end. Set in case one of the tests fails.
27 EXIT_STATUS=0
28 # Per-test return value. Clear at the beginning of each test.
29 RET=0
31 ##############################################################################
32 # Helpers
34 __ksft_status_merge()
36 local a=$1; shift
37 local b=$1; shift
38 local -A weights
39 local weight=0
41 local i
42 for i in "$@"; do
43 weights[$i]=$((weight++))
44 done
46 if [[ ${weights[$a]} > ${weights[$b]} ]]; then
47 echo "$a"
48 return 0
49 else
50 echo "$b"
51 return 1
55 ksft_status_merge()
57 local a=$1; shift
58 local b=$1; shift
60 __ksft_status_merge "$a" "$b" \
61 $ksft_pass $ksft_xfail $ksft_skip $ksft_fail
64 ksft_exit_status_merge()
66 local a=$1; shift
67 local b=$1; shift
69 __ksft_status_merge "$a" "$b" \
70 $ksft_xfail $ksft_pass $ksft_skip $ksft_fail
73 loopy_wait()
75 local sleep_cmd=$1; shift
76 local timeout_ms=$1; shift
78 local start_time="$(date -u +%s%3N)"
79 while true
81 local out
82 if out=$("$@"); then
83 echo -n "$out"
84 return 0
87 local current_time="$(date -u +%s%3N)"
88 if ((current_time - start_time > timeout_ms)); then
89 echo -n "$out"
90 return 1
93 $sleep_cmd
94 done
97 busywait()
99 local timeout_ms=$1; shift
101 loopy_wait : "$timeout_ms" "$@"
104 # timeout in seconds
105 slowwait()
107 local timeout_sec=$1; shift
109 loopy_wait "sleep 0.1" "$((timeout_sec * 1000))" "$@"
112 until_counter_is()
114 local expr=$1; shift
115 local current=$("$@")
117 echo $((current))
118 ((current $expr))
121 busywait_for_counter()
123 local timeout=$1; shift
124 local delta=$1; shift
126 local base=$("$@")
127 busywait "$timeout" until_counter_is ">= $((base + delta))" "$@"
130 slowwait_for_counter()
132 local timeout=$1; shift
133 local delta=$1; shift
135 local base=$("$@")
136 slowwait "$timeout" until_counter_is ">= $((base + delta))" "$@"
139 # Check for existence of tools which are built as part of selftests
140 # but may also already exist in $PATH
141 check_gen_prog()
143 local prog_name=$1; shift
145 if ! which $prog_name >/dev/null 2>/dev/null; then
146 PATH=$PWD:$PATH
147 if ! which $prog_name >/dev/null; then
148 echo "'$prog_name' command not found; skipping tests"
149 exit $ksft_skip
154 remove_ns_list()
156 local item=$1
157 local ns
158 local ns_list=("${NS_LIST[@]}")
159 NS_LIST=()
161 for ns in "${ns_list[@]}"; do
162 if [ "${ns}" != "${item}" ]; then
163 NS_LIST+=("${ns}")
165 done
168 cleanup_ns()
170 local ns=""
171 local ret=0
173 for ns in "$@"; do
174 [ -z "${ns}" ] && continue
175 ip netns pids "${ns}" 2> /dev/null | xargs -r kill || true
176 ip netns delete "${ns}" &> /dev/null || true
177 if ! busywait $BUSYWAIT_TIMEOUT ip netns list \| grep -vq "^$ns$" &> /dev/null; then
178 echo "Warn: Failed to remove namespace $ns"
179 ret=1
180 else
181 remove_ns_list "${ns}"
183 done
185 return $ret
188 cleanup_all_ns()
190 cleanup_ns "${NS_LIST[@]}"
193 # setup netns with given names as prefix. e.g
194 # setup_ns local remote
195 setup_ns()
197 local ns_name=""
198 local ns_list=()
199 for ns_name in "$@"; do
200 # avoid conflicts with local var: internal error
201 if [ "${ns_name}" = "ns_name" ]; then
202 echo "Failed to setup namespace '${ns_name}': invalid name"
203 cleanup_ns "${ns_list[@]}"
204 exit $ksft_fail
207 # Some test may setup/remove same netns multi times
208 if [ -z "${!ns_name}" ]; then
209 eval "${ns_name}=${ns_name,,}-$(mktemp -u XXXXXX)"
210 else
211 cleanup_ns "${!ns_name}"
214 if ! ip netns add "${!ns_name}"; then
215 echo "Failed to create namespace $ns_name"
216 cleanup_ns "${ns_list[@]}"
217 return $ksft_skip
219 ip -n "${!ns_name}" link set lo up
220 ns_list+=("${!ns_name}")
221 done
222 NS_LIST+=("${ns_list[@]}")
225 tc_rule_stats_get()
227 local dev=$1; shift
228 local pref=$1; shift
229 local dir=${1:-ingress}; shift
230 local selector=${1:-.packets}; shift
232 tc -j -s filter show dev $dev $dir pref $pref \
233 | jq ".[1].options.actions[].stats$selector"
236 tc_rule_handle_stats_get()
238 local id=$1; shift
239 local handle=$1; shift
240 local selector=${1:-.packets}; shift
241 local netns=${1:-""}; shift
243 tc $netns -j -s filter show $id \
244 | jq ".[] | select(.options.handle == $handle) | \
245 .options.actions[0].stats$selector"
248 ret_set_ksft_status()
250 local ksft_status=$1; shift
251 local msg=$1; shift
253 RET=$(ksft_status_merge $RET $ksft_status)
254 if (( $? )); then
255 retmsg=$msg
259 log_test_result()
261 local test_name=$1; shift
262 local opt_str=$1; shift
263 local result=$1; shift
264 local retmsg=$1; shift
266 printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result"
267 if [[ $retmsg ]]; then
268 printf "\t%s\n" "$retmsg"
272 pause_on_fail()
274 if [[ $PAUSE_ON_FAIL == yes ]]; then
275 echo "Hit enter to continue, 'q' to quit"
276 read a
277 [[ $a == q ]] && exit 1
281 handle_test_result_pass()
283 local test_name=$1; shift
284 local opt_str=$1; shift
286 log_test_result "$test_name" "$opt_str" " OK "
289 handle_test_result_fail()
291 local test_name=$1; shift
292 local opt_str=$1; shift
294 log_test_result "$test_name" "$opt_str" FAIL "$retmsg"
295 pause_on_fail
298 handle_test_result_xfail()
300 local test_name=$1; shift
301 local opt_str=$1; shift
303 log_test_result "$test_name" "$opt_str" XFAIL "$retmsg"
304 pause_on_fail
307 handle_test_result_skip()
309 local test_name=$1; shift
310 local opt_str=$1; shift
312 log_test_result "$test_name" "$opt_str" SKIP "$retmsg"
315 log_test()
317 local test_name=$1
318 local opt_str=$2
320 if [[ $# -eq 2 ]]; then
321 opt_str="($opt_str)"
324 if ((RET == ksft_pass)); then
325 handle_test_result_pass "$test_name" "$opt_str"
326 elif ((RET == ksft_xfail)); then
327 handle_test_result_xfail "$test_name" "$opt_str"
328 elif ((RET == ksft_skip)); then
329 handle_test_result_skip "$test_name" "$opt_str"
330 else
331 handle_test_result_fail "$test_name" "$opt_str"
334 EXIT_STATUS=$(ksft_exit_status_merge $EXIT_STATUS $RET)
335 return $RET
338 log_test_skip()
340 RET=$ksft_skip retmsg= log_test "$@"
343 log_test_xfail()
345 RET=$ksft_xfail retmsg= log_test "$@"
348 log_info()
350 local msg=$1
352 echo "INFO: $msg"
355 tests_run()
357 local current_test
359 for current_test in ${TESTS:-$ALL_TESTS}; do
360 in_defer_scope \
361 $current_test
362 done
365 # Whether FAILs should be interpreted as XFAILs. Internal.
366 FAIL_TO_XFAIL=
368 check_err()
370 local err=$1
371 local msg=$2
373 if ((err)); then
374 if [[ $FAIL_TO_XFAIL = yes ]]; then
375 ret_set_ksft_status $ksft_xfail "$msg"
376 else
377 ret_set_ksft_status $ksft_fail "$msg"
382 check_fail()
384 local err=$1
385 local msg=$2
387 check_err $((!err)) "$msg"
390 check_err_fail()
392 local should_fail=$1; shift
393 local err=$1; shift
394 local what=$1; shift
396 if ((should_fail)); then
397 check_fail $err "$what succeeded, but should have failed"
398 else
399 check_err $err "$what failed"
403 xfail()
405 FAIL_TO_XFAIL=yes "$@"
408 xfail_on_slow()
410 if [[ $KSFT_MACHINE_SLOW = yes ]]; then
411 FAIL_TO_XFAIL=yes "$@"
412 else
413 "$@"
417 omit_on_slow()
419 if [[ $KSFT_MACHINE_SLOW != yes ]]; then
420 "$@"
424 xfail_on_veth()
426 local dev=$1; shift
427 local kind
429 kind=$(ip -j -d link show dev $dev |
430 jq -r '.[].linkinfo.info_kind')
431 if [[ $kind = veth ]]; then
432 FAIL_TO_XFAIL=yes "$@"
433 else
434 "$@"
438 kill_process()
440 local pid=$1; shift
442 # Suppress noise from killing the process.
443 { kill $pid && wait $pid; } 2>/dev/null
446 ip_link_add()
448 local name=$1; shift
450 ip link add name "$name" "$@"
451 defer ip link del dev "$name"
454 ip_link_master()
456 local member=$1; shift
457 local master=$1; shift
459 ip link set dev "$member" master "$master"
460 defer ip link set dev "$member" nomaster