@@ -1640,6 +1640,32 @@ that can sleep for defined amount of seconds, milliseconds or microseconds.
tst_sleep 100ms
-------------------------------------------------------------------------------
+Retry a function in limited time
+++++++++++++++++++++++++++++++++
+
+Sometimes LTP test needs retrying a function for many times to get success.
+This achievement makes that possible via keeping it retrying if the return
+value of the function is NOT as we expected. After exceeding a limited time,
+test will break from the retries immediately.
+
+[source,c]
+-------------------------------------------------------------------------------
+# retry function in 1 second
+TST_RETRY_FUNC(FUNC, EXPECTED_RET)
+
+# retry function in N second
+TST_RETRY_FN_EXP_BACKOFF(FUNC, EXPECTED_RET, N)
+-------------------------------------------------------------------------------
+
+[source,sh]
+-------------------------------------------------------------------------------
+# retry function in 1 second
+TST_RETRY_FUNC "FUNC arg1 arg2 ..." "EXPECTED_RET"
+
+# retry function in N second
+TST_RETRY_FN_EXP_BACKOFF "FUNC arg1 arg2 ..." "EXPECTED_RET" "N"
+-------------------------------------------------------------------------------
+
Checking for integers
+++++++++++++++++++++
@@ -154,6 +154,48 @@ EXPECT_FAIL()
fi
}
+TST_RETRY_FN_EXP_BACKOFF()
+{
+ local tst_fun=$1
+ local tst_exp=$2
+ local tst_sec=$(expr $3 \* 1000000)
+ local tst_delay=1
+
+ if [ $# -ne 3 ]; then
+ tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF expects 3 parameters"
+ fi
+
+ if ! tst_is_int "$tst_sec"; then
+ tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF: tst_sec must be integer ('$tst_sec')"
+ fi
+
+ while true; do
+ $tst_fun
+ if [ "$?" = "$tst_exp" ]; then
+ break
+ fi
+
+ if [ $tst_delay -lt $tst_sec ]; then
+ tst_sleep ${tst_delay}us
+ tst_delay=$((tst_delay*2))
+ else
+ tst_brk TBROK "\"$tst_fun\" timed out"
+ fi
+ done
+
+ return $tst_exp
+}
+
+TST_RETRY_FUNC()
+{
+ if [ $# -ne 2 ]; then
+ tst_brk TBROK "TST_RETRY_FN_EXP_BACKOFF expects 2 parameters"
+ fi
+
+ TST_RETRY_FN_EXP_BACKOFF "$1" "$2" 1
+ return $2
+}
+
tst_umount()
{
local device="$1"
@@ -255,6 +297,7 @@ tst_run()
OPTS|USAGE|PARSE_ARGS|POS_ARGS);;
NEEDS_ROOT|NEEDS_TMPDIR|NEEDS_DEVICE|DEVICE);;
NEEDS_CMDS|NEEDS_MODULE|MODPATH|DATAROOT);;
+ RETRY_FUNC|RETRY_FN_EXP_BACKOFF);;
IPV6);;
*) tst_res TWARN "Reserved variable TST_$tst_i used!";;
esac