xref: /aosp_15_r20/external/ltp/doc/old/Shell-Test-API.asciidoc (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1LTP Shell Test API
2==================
3
4NOTE: See also
5      https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines],
6      https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API].
7
81 Writing a testcase in shell
9-----------------------------
10
11LTP supports testcases to be written in a portable shell too.
12
13There is a shell library modeled closely to the C interface at
14'testcases/lib/tst_test.sh'.
15
16WARNING: All identifiers starting with 'TST_' or 'tst_' are reserved for the
17         test library.
18
191.1 Basic test interface
20~~~~~~~~~~~~~~~~~~~~~~~~
21
22[source,sh]
23-------------------------------------------------------------------------------
24#!/bin/sh
25# SPDX-License-Identifier: GPL-2.0-or-later
26# This is a basic test for true shell builtin
27
28TST_TESTFUNC=do_test
29
30do_test()
31{
32	true
33	ret=$?
34
35	if [ $ret -eq 0 ]; then
36		tst_res TPASS "true returned 0"
37	else
38		tst_res TFAIL "true returned $ret"
39	fi
40}
41
42. tst_test.sh
43tst_run
44-------------------------------------------------------------------------------
45
46TIP: To execute this test the 'tst_test.sh' library must be in '$PATH'. If you
47     are executing the test from a git checkout you can run it as
48     'PATH="$PATH:../../lib" ./foo01.sh'
49
50The shell library expects test setup, cleanup and the test function executing
51the test in the '$TST_SETUP', '$TST_CLEANUP' and '$TST_TESTFUNC' variables.
52
53Both '$TST_SETUP' and '$TST_CLEANUP' are optional.
54
55The '$TST_TESTFUNC' may be called several times if more than one test
56iteration was requested by passing right command line options to the test.
57
58The '$TST_CLEANUP' may be called even in the middle of the setup and must be
59able to clean up correctly even in this situation. The easiest solution for
60this is to keep track of what was initialized and act accordingly in the
61cleanup.
62
63WARNING: Similar to the C library, calling 'tst_brk' in the $TST_CLEANUP does
64         not exit the test and 'TBROK' is converted to 'TWARN'.
65
66Notice also the 'tst_run' shell API function called at the end of the test that
67actually starts the test.
68
69WARNING: cleanup function is called only after 'tst_run' has been started.
70Calling 'tst_brk' in shell libraries, e.g. 'tst_test.sh' or 'tst_net.sh' does
71not trigger calling it.
72
73[source,sh]
74-------------------------------------------------------------------------------
75#!/bin/sh
76# SPDX-License-Identifier: GPL-2.0-or-later
77# Example test with tests in separate functions
78
79TST_TESTFUNC=test
80TST_CNT=2
81
82test1()
83{
84	tst_res TPASS "Test $1 passed"
85}
86
87test2()
88{
89	tst_res TPASS "Test $1 passed"
90}
91
92. tst_test.sh
93tst_run
94# output:
95# foo 1 TPASS: Test 1 passed
96# foo 2 TPASS: Test 2 passed
97-------------------------------------------------------------------------------
98
99If '$TST_CNT' is set, the test library looks if there are functions named
100'$\{TST_TESTFUNC\}1', ..., '$\{TST_TESTFUNC\}$\{TST_CNT\}' and if these are
101found they are executed one by one. The test number is passed to it in the '$1'.
102
103[source,sh]
104-------------------------------------------------------------------------------
105#!/bin/sh
106# SPDX-License-Identifier: GPL-2.0-or-later
107# Example test with tests in a single function
108
109TST_TESTFUNC=do_test
110TST_CNT=2
111
112do_test()
113{
114	case $1 in
115	1) tst_res TPASS "Test $1 passed";;
116	2) tst_res TPASS "Test $1 passed";;
117	esac
118}
119
120. tst_test.sh
121tst_run
122# output:
123# foo 1 TPASS: Test 1 passed
124# foo 2 TPASS: Test 2 passed
125-------------------------------------------------------------------------------
126
127Otherwise, if '$TST_CNT' is set but there is no '$\{TST_TESTFUNC\}1', etc.,
128the '$TST_TESTFUNC' is executed '$TST_CNT' times and the test number is passed
129to it in the '$1'.
130
131[source,sh]
132-------------------------------------------------------------------------------
133#!/bin/sh
134# SPDX-License-Identifier: GPL-2.0-or-later
135# Example test with tests in a single function, using $TST_TEST_DATA and
136# $TST_TEST_DATA_IFS
137
138TST_TESTFUNC=do_test
139TST_TEST_DATA="foo:bar:d dd"
140TST_TEST_DATA_IFS=":"
141
142do_test()
143{
144	tst_res TPASS "Test $1 passed with data '$2'"
145}
146
147. tst_test.sh
148tst_run
149# output:
150# foo 1 TPASS: Test 1 passed with data 'foo'
151# foo 2 TPASS: Test 1 passed with data 'bar'
152# foo 3 TPASS: Test 1 passed with data 'd dd'
153-------------------------------------------------------------------------------
154
155It's possible to pass data for function with '$TST_TEST_DATA'. Optional
156'$TST_TEST_DATA_IFS' is used for splitting, default value is space.
157
158[source,sh]
159-------------------------------------------------------------------------------
160#!/bin/sh
161# SPDX-License-Identifier: GPL-2.0-or-later
162# Example test with tests in a single function, using $TST_TEST_DATA and $TST_CNT
163
164TST_TESTFUNC=do_test
165TST_CNT=2
166TST_TEST_DATA="foo bar"
167
168do_test()
169{
170	case $1 in
171	1) tst_res TPASS "Test $1 passed with data '$2'";;
172	2) tst_res TPASS "Test $1 passed with data '$2'";;
173	esac
174}
175
176. tst_test.sh
177tst_run
178# output:
179# foo 1 TPASS: Test 1 passed with data 'foo'
180# foo 2 TPASS: Test 2 passed with data 'foo'
181# foo 3 TPASS: Test 1 passed with data 'bar'
182# foo 4 TPASS: Test 2 passed with data 'bar'
183-------------------------------------------------------------------------------
184
185'$TST_TEST_DATA' can be used with '$TST_CNT'. If '$TST_TEST_DATA_IFS' not specified,
186space as default value is used. Of course, it's possible to use separate functions.
187
1881.2 Library environment variables and functions for shell
189~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190
191Similarily to the C library various checks and preparations can be requested
192simply by setting right '$TST_FOO'.
193
194[options="header"]
195|=============================================================================
196| Variable name            | Action done
197| 'TST_ALL_FILESYSTEMS'    | Testing on all available filesystems
198                             ('tst_test.all_filesystems' equivalent).
199                             When 'TST_SKIP_FILESYSTEMS' any listed filesystem is not
200                             included in the resulting list of supported filesystems.
201| 'TST_DEV_EXTRA_OPTS'     | Pass extra 'mkfs' options _after_ device name,
202                             to 'tst_mkfs', use with 'TST_FORMAT_DEVICE=1'.
203| 'TST_DEV_FS_OPTS'        | Pass 'mkfs' options _before_ the device name,
204                             to 'tst_mkfs', use with 'TST_FORMAT_DEVICE=1'.
205| 'TST_FORMAT_DEVICE'      | Format a block device with a filesystem, see
206                             https://github.com/linux-test-project/ltp/wiki/Shell-Test-API#formatting-device-with-a-filesystem[Formatting device with a filesystem].
207                             See also 'TST_DEV_EXTRA_OPTS', 'TST_DEV_FS_OPTS', 'TST_FS_TYPE'.
208                             Implies 'TST_NEEDS_DEVICE=1' (no need to set it).
209| 'TST_DEVICE'             | Block device name for 'tst_mount' and 'tst_mkfs', see
210                             https://github.com/linux-test-project/ltp/wiki/Shell-Test-API#formatting-device-with-a-filesystem[Formatting device with a filesystem].
211| 'TST_FS_TYPE'            | Override the default filesystem to be used. Also
212                             contains currently used filesystem during looping
213                             filesystems in 'TST_ALL_FILESYSTEMS=1'
214                             ('tst_device->fs_type' equivalent).
215| 'TST_MNTPOINT'           | Holds path to mountpoint used in 'tst_mount', see
216                             https://github.com/linux-test-project/ltp/wiki/Shell-Test-API#formatting-device-with-a-filesystem[Formatting device with a filesystem].
217| 'TST_MNT_PARAMS'         | Extra mount params for 'tst_mount', see
218                             https://github.com/linux-test-project/ltp/wiki/Shell-Test-API#formatting-device-with-a-filesystem[Formatting device with a filesystem].
219| 'TST_MOUNT_DEVICE'       | Mount device, see
220                             https://github.com/linux-test-project/ltp/wiki/Shell-Test-API#mounting-and-unmounting-filesystems[Mounting and unmounting filesystems].
221| 'TST_NEEDS_ROOT'         | Exit the test with 'TCONF' unless executed under root.
222                             Alternatively the 'tst_require_root' command can be used.
223| 'TST_NEEDS_TMPDIR'       | Create test temporary directory and cd into it.
224| 'TST_NEEDS_DEVICE'       | Prepare test temporary device, the path to testing
225                             device is stored in '$TST_DEVICE' variable.
226                             The option implies 'TST_NEEDS_TMPDIR'.
227| 'TST_NEEDS_CMDS'         | String with command names that has to be present for
228                             the test (see below).
229| 'TST_NEEDS_MODULE'       | Test module name needed for the test (see below).
230| 'TST_NEEDS_DRIVERS'      | Checks kernel drivers support for the test.
231| 'TST_NEEDS_KCONFIGS'     | Checks kernel kconfigs support for the test (see below).
232| 'TST_NEEDS_KCONFIGS_IFS' | Used for splitting '$TST_NEEDS_KCONFIGS' variable,
233                             default value is comma, it only supports single character.
234| 'TST_SKIP_FILESYSTEMS'   | Comma separated list of filesystems on which test will be skipped
235                             (tst_test.skip_filesystems equivalent).
236| 'TST_TIMEOUT'            | Maximum timeout set for the test in sec. Must be int >= 1,
237                             or -1 (special value to disable timeout), default is 300.
238                             Variable is meant be set in tests, not by user.
239                             It's an equivalent of `tst_test.timeout` in C, can be set
240                             via 'tst_set_timeout(timeout)' after test has started.
241|=============================================================================
242
243[options="header"]
244|=============================================================================
245| Function name              | Action done
246| 'tst_set_timeout(timeout)' | Maximum timeout set for the test in sec.
247                               See 'TST_TIMEOUT' variable.
248|=============================================================================
249
250NOTE: Network tests (see testcases/network/README.md) use additional variables
251and functions in 'tst_net.sh'.
252
253Checking for presence of commands
254+++++++++++++++++++++++++++++++++
255
256[source,sh]
257-------------------------------------------------------------------------------
258#!/bin/sh
259
260...
261
262TST_NEEDS_CMDS="modinfo modprobe"
263. tst_test.sh
264
265...
266
267-------------------------------------------------------------------------------
268
269Setting '$TST_NEEDS_CMDS' to a string listing required commands will check for
270existence each of them and exits the test with 'TCONF' on first missing.
271
272Alternatively the 'tst_require_cmds()' function can be used to do the same on
273runtime, since sometimes we need to the check at runtime too.
274
275'tst_check_cmds()' can be used for requirements just for a particular test
276as it doesn't exit (it issues 'tst_res TCONF'). Expected usage is:
277
278[source,sh]
279-------------------------------------------------------------------------------
280#!/bin/sh
281
282TST_TESTFUNC=do_test
283
284do_test()
285{
286	tst_check_cmds cmd || return
287	cmd --foo
288	...
289}
290
291. tst_test.sh
292tst_run
293-------------------------------------------------------------------------------
294
295Locating kernel modules
296+++++++++++++++++++++++
297
298The LTP build system can build kernel modules as well, setting
299'$TST_NEEDS_MODULE' to module name will cause the library to look for the
300module in a few possible paths.
301
302If module was found the path to it will be stored into '$TST_MODPATH'
303variable, if module wasn't found the test will exit with 'TCONF'.
304
305Alternatively the 'tst_require_module()' function can be used to do the same
306at runtime.
307
3081.3 Optional command line parameters
309~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310
311[source,sh]
312-------------------------------------------------------------------------------
313#!/bin/sh
314# SPDX-License-Identifier: GPL-2.0-or-later
315# Optional test command line parameters
316
317TST_OPTS="af:"
318TST_USAGE=usage
319TST_PARSE_ARGS=parse_args
320TST_TESTFUNC=do_test
321
322ALTERNATIVE=0
323MODE="foo"
324
325usage()
326{
327	cat << EOF
328usage: $0 [-a] [-f <foo|bar>]
329
330OPTIONS
331-a     Enable support for alternative foo
332-f     Specify foo or bar mode
333EOF
334}
335
336parse_args()
337{
338	case $1 in
339	a) ALTERNATIVE=1;;
340	f) MODE="$2";;
341	esac
342}
343
344do_test()
345{
346	...
347}
348
349. tst_test.sh
350tst_run
351-------------------------------------------------------------------------------
352
353The 'getopts' string for optional parameters is passed in the '$TST_OPTS'
354variable. There are a few default parameters that cannot be used by a test,
355these can be listed with passing help '-h' option to any test.
356
357The function that prints the usage is passed in '$TST_USAGE', the help for
358the options implemented in the library is appended when usage is printed.
359
360Lastly the function '$PARSE_ARGS' is called with the option name in the '$1'
361and, if option has argument, its value in the '$2'.
362
363[source,sh]
364-------------------------------------------------------------------------------
365#!/bin/sh
366# SPDX-License-Identifier: GPL-2.0-or-later
367# Optional test positional parameters
368
369TST_POS_ARGS=3
370TST_USAGE=usage
371TST_TESTFUNC=do_test
372
373usage()
374{
375	cat << EOF
376usage: $0 [min] [max] [size]
377
378EOF
379}
380
381min="$1"
382max="$2"
383size="$3"
384
385do_test()
386{
387	...
388}
389
390. tst_test.sh
391tst_run
392-------------------------------------------------------------------------------
393
394You can also request a number of positional parameters by setting the
395'$TST_POS_ARGS' variable. If you do, these will be available as they were
396passed directly to the script in '$1', '$2', ..., '$n'.
397
3981.4 Useful library functions
399~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
400
401Retrieving configuration variables
402++++++++++++++++++++++++++++++++++
403
404You may need to retrieve configuration values such as PAGESIZE, there is
405'getconf' but as some system may not have it, you are advised to use
406'tst_getconf' instead. Note that it implements subset of 'getconf'
407system variables used by the testcases only.
408
409[source,sh]
410-------------------------------------------------------------------------------
411# retrieve PAGESIZE
412pagesize=`tst_getconf PAGESIZE`
413-------------------------------------------------------------------------------
414
415Sleeping for subsecond intervals
416++++++++++++++++++++++++++++++++
417
418Albeit there is a sleep command available basically everywhere not all
419implementations can support sleeping for less than one second. And most of the
420time sleeping for a second is too much. Therefore LTP includes 'tst_sleep'
421that can sleep for defined amount of seconds, milliseconds or microseconds.
422
423[source,sh]
424-------------------------------------------------------------------------------
425# sleep for 100 milliseconds
426tst_sleep 100ms
427-------------------------------------------------------------------------------
428
429Retry a function call multiple times
430++++++++++++++++++++++++++++++++++++
431
432Sometimes an LTP test needs to retry a function call multiple times because
433the system is not ready to process it successfully on the first try. The LTP
434library has useful tools to handle the call retry automatically.
435'TST_RETRY_FUNC()' will keep retrying for up to 1 second. If you want a custom
436time limit use 'TST_RETRY_FN_EXP_BACKOFF()'. Both methods return the value
437returned by the last 'FUNC' call.
438
439The delay between retries starts at 1 microsecond and doubles after each call.
440The retry loop ends when the function call succeeds or when the next delay
441exceeds the specified time (1 second for 'TST_RETRY_FUNC()'). The maximum
442delay is multiplied by TST_TIMEOUT_MUL. The total cumulative delay may be up
443to twice as long as the adjusted maximum delay.
444
445The C version of 'TST_RETRY_FUNC()' is a macro which takes two arguments:
446
447* 'FUNC' is the complete function call with arguments which should be retried
448  multiple times.
449* 'SUCCESS_CHECK' is a macro or function which will validate 'FUNC' return
450  value. 'FUNC' call was successful if 'SUCCESS_CHECK(ret)' evaluates to
451  non-zero.
452
453Both retry methods clear 'errno' before every 'FUNC' call so your
454'SUCCESS_CHECK' can look for specific error codes as well. The LTP library
455also includes predefined 'SUCCESS_CHECK' macros for the most common call
456conventions:
457
458* 'TST_RETVAL_EQ0()' - The call was successful if 'FUNC' returned 0 or NULL
459* 'TST_RETVAL_NOTNULL()' - The call was successful if 'FUNC' returned any
460  value other than 0 or NULL.
461* 'TST_RETVAL_GE0()' - The call was successful if 'FUNC' returned value >= 0.
462
463[source,c]
464-------------------------------------------------------------------------------
465/* Keep trying for 1 second */
466TST_RETRY_FUNC(FUNC, SUCCESS_CHECK)
467
468/* Keep trying for up to 2*N seconds */
469TST_RETRY_FN_EXP_BACKOFF(FUNC, SUCCESS_CHECK, N)
470-------------------------------------------------------------------------------
471
472The shell version of 'TST_RETRY_FUNC()' is simpler and takes slightly
473different arguments:
474
475* 'FUNC' is a string containing the complete function or program call with
476  arguments.
477* 'EXPECTED_RET' is a single expected return value. 'FUNC' call was successful
478  if the return value is equal to EXPECTED_RET.
479
480[source,sh]
481-------------------------------------------------------------------------------
482# Keep trying for 1 second
483TST_RETRY_FUNC "FUNC arg1 arg2 ..." "EXPECTED_RET"
484
485# Keep trying for up to 2*N seconds
486TST_RETRY_FN_EXP_BACKOFF "FUNC arg1 arg2 ..." "EXPECTED_RET" "N"
487-------------------------------------------------------------------------------
488
489Checking for integers
490+++++++++++++++++++++
491
492[source,sh]
493-------------------------------------------------------------------------------
494# returns zero if passed an integer parameter, non-zero otherwise
495tst_is_int "$FOO"
496-------------------------------------------------------------------------------
497
498Checking for integers and floating point numbers
499++++++++++++++++++++++++++++++++++++++++++++++++
500
501[source,sh]
502-------------------------------------------------------------------------------
503# returns zero if passed an integer or floating point number parameter,
504# non-zero otherwise
505tst_is_num "$FOO"
506-------------------------------------------------------------------------------
507
508Obtaining random numbers
509++++++++++++++++++++++++
510
511There is no '$RANDOM' in portable shell, use 'tst_random' instead.
512
513[source,sh]
514-------------------------------------------------------------------------------
515# get random integer between 0 and 1000 (including 0 and 1000)
516tst_random 0 1000
517-------------------------------------------------------------------------------
518
519Formatting device with a filesystem
520+++++++++++++++++++++++++++++++++++
521
522'TST_FORMAT_DEVICE=1' can be used to format device before running the test.
523Uses '$TST_FS_TYPE' (by default ext2), '$TST_DEVICE' a block device to be
524formatted, usually prepared by the library (TST_NEEDS_DEVICE=1 must be set).
525'$TST_DEV_FS_OPTS' a 'mkfs' options _before_ the device path and
526'$TST_DEV_EXTRA_OPTS' extra 'mkfs'' options _after_ the device path.
527
528[source,sh]
529-------------------------------------------------------------------------------
530TST_FORMAT_DEVICE=1
531TST_DEV_FS_OPTS="-b 1024 -O quota"
532TST_DEV_EXTRA_OPTS="5m"
533TST_TESTFUNC=test
534
535test()
536{
537	tst_res TPASS "device formatted"
538}
539-------------------------------------------------------------------------------
540
541[source,sh]
542-------------------------------------------------------------------------------
543# format test device with ext2
544tst_mkfs ext2 $TST_DEVICE
545# default params are $TST_FS_TYPE $TST_DEVICE
546tst_mkfs
547# optional parameters
548tst_mkfs ext4 /dev/device -T largefile
549-------------------------------------------------------------------------------
550
551Mounting and unmounting filesystems
552+++++++++++++++++++++++++++++++++++
553
554The 'tst_mount' and 'tst_umount' helpers are a safe way to mount/umount
555a filesystem.
556
557The 'tst_mount' mounts '$TST_DEVICE' of '$TST_FS_TYPE' (optional) to
558'$TST_MNTPOINT' (defaults to mntpoint), optionally using the
559'$TST_MNT_PARAMS'. The '$TST_MNTPOINT' directory is created if it didn't
560exist prior to the function call.
561
562If the path passed (optional, must be absolute path, defaults to '$TST_MNTPOINT')
563to the 'tst_umount' is not mounted (present in '/proc/mounts') it's noop.
564Otherwise it retries to umount the filesystem a few times on failure.
565This is a workaround since there are daemons dumb enough to probe all newly
566mounted filesystems, and prevents them from being umounted shortly after they
567were mounted.
568
569ROD and ROD_SILENT
570++++++++++++++++++
571
572These functions supply the 'SAFE_MACROS' used in C although they work and are
573named differently.
574
575[source,sh]
576-------------------------------------------------------------------------------
577ROD_SILENT command arg1 arg2 ...
578
579# is shorthand for:
580
581command arg1 arg2 ... > /dev/null 2>&1
582if [ $? -ne 0 ]; then
583        tst_brk TBROK "..."
584fi
585
586
587ROD command arg1 arg2 ...
588
589# is shorthand for:
590
591ROD arg1 arg2 ...
592if [ $? -ne 0 ]; then
593        tst_brk TBROK "..."
594fi
595-------------------------------------------------------------------------------
596
597WARNING: Keep in mind that output redirection (to a file) happens in the
598         caller rather than in the ROD function and cannot be checked for
599         write errors by the ROD function.
600
601As a matter of a fact doing +ROD echo a > /proc/cpuinfo+ would work just fine
602since the 'ROD' function will only get the +echo a+ part that will run just
603fine.
604
605[source,sh]
606-------------------------------------------------------------------------------
607# Redirect output to a file with ROD
608ROD echo foo \> bar
609-------------------------------------------------------------------------------
610
611Note the '>' is escaped with '\', this causes that the '>' and filename are
612passed to the 'ROD' function as parameters and the 'ROD' function contains
613code to split '$@' on '>' and redirects the output to the file.
614
615EXPECT_PASS{,_BRK} and EXPECT_FAIL{,_BRK}
616+++++++++++++++++++++++++++++++++++++++++
617
618[source,sh]
619-------------------------------------------------------------------------------
620EXPECT_PASS command arg1 arg2 ... [ \> file ]
621EXPECT_FAIL command arg1 arg2 ... [ \> file ]
622-------------------------------------------------------------------------------
623
624'EXPECT_PASS' calls 'tst_res TPASS' if the command exited with 0 exit code,
625and 'tst_res TFAIL' otherwise. 'EXPECT_FAIL' does vice versa.
626
627Output redirection rules are the same as for the 'ROD' function. In addition
628to that, 'EXPECT_FAIL' always redirects the command's stderr to '/dev/null'.
629
630There are also 'EXPECT_PASS_BRK' and 'EXPECT_FAIL_BRK', which works the same way
631except breaking a test when unexpected action happen.
632
633It's possible to detect whether expected value happened:
634[source,sh]
635-------------------------------------------------------------------------------
636if ! EXPECT_PASS command arg1 2\> /dev/null; then
637	continue
638fi
639-------------------------------------------------------------------------------
640
641tst_kvcmp
642+++++++++
643
644This command compares the currently running kernel version given conditions
645with syntax similar to the shell test command.
646
647[source,sh]
648-------------------------------------------------------------------------------
649# Exit the test if kernel version is older or equal to 4.0.0
650if tst_kvcmp -le 4.0.0; then
651	tst_brk TCONF "Kernel newer than 4.0.0 is needed"
652fi
653
654# Exit the test if kernel is newer than 3.16 and older than 4.0.1
655if tst_kvcmp -gt 3.16 -a -lt 4.0.1; then
656	tst_brk TCONF "Kernel must be older than 3.16 or newer than 4.0.1"
657fi
658
659if tst_kvcmp -lt "6.1 RHEL9:5.14.0-191"; then
660	# code for kernel < 6.1 or RHEL9 kernel < 5.14.0-191
661fi
662-------------------------------------------------------------------------------
663
664[options="header"]
665|=======================================================================
666| expression | description
667| -eq kver   | Returns true if kernel version is equal
668| -ne kver   | Returns true if kernel version is not equal
669| -gt kver   | Returns true if kernel version is greater
670| -ge kver   | Returns true if kernel version is greater or equal
671| -lt kver   | Returns true if kernel version is lesser
672| -le kver   | Returns true if kernel version is lesser or equal
673| -a         | Does logical and between two expressions
674| -o         | Does logical or between two expressions
675|=======================================================================
676
677The format for kernel version has to either be with one dot e.g. '2.6' or with
678two dots e.g. '4.8.1'.
679
680Kernel version can also be followed by a space separated list of extra versions
681prefixed by distribution which when matched take precedence, e.g. '6.1 RHEL9:5.14.0-191'.
682
683For more info see 'tst_kvercmp()' and 'tst_kvercmp2()' in
684https://github.com/linux-test-project/ltp/wiki/C-Test-API#16-runtime-kernel-version-detection[C Test API].
685
686NOTE: See also LTP
687      https://github.com/linux-test-project/ltp/wiki/Supported-kernel,-libc,-toolchain-versions#13-minimal-supported-kernel-version[minimal supported kernel version].
688
689tst_fs_has_free
690+++++++++++++++
691
692[source,sh]
693-------------------------------------------------------------------------------
694#!/bin/sh
695
696...
697
698# whether current directory has 100MB free space at least.
699if ! tst_fs_has_free . 100MB; then
700	tst_brkm TCONF "Not enough free space"
701fi
702
703...
704-------------------------------------------------------------------------------
705
706The 'tst_fs_has_free' shell interface returns 0 if the specified free space is
707satisfied, 1 if not, and 2 on error.
708
709The second argument supports suffixes kB, MB and GB, the default unit is Byte.
710
711tst_retry
712+++++++++
713
714[source,sh]
715-------------------------------------------------------------------------------
716#!/bin/sh
717
718...
719
720# Retry ping command three times
721tst_retry "ping -c 1 127.0.0.1"
722
723if [ $? -ne 0 ]; then
724	tst_resm TFAIL "Failed to ping 127.0.0.1"
725else
726	tst_resm TPASS "Successfully pinged 127.0.0.1"
727fi
728
729...
730-------------------------------------------------------------------------------
731
732The 'tst_retry' function allows you to retry a command after waiting small
733amount of time until it succeeds or until given amount of retries has been
734reached (default is three attempts).
735
7361.5 Restarting daemons
737~~~~~~~~~~~~~~~~~~~~~~
738
739Restarting system daemons is a complicated task for two reasons.
740
741* There are different init systems
742  (SysV init, systemd, etc...)
743
744* Daemon names are not unified between distributions
745  (apache vs httpd, cron vs crond, various syslog variations)
746
747To solve these problems LTP has 'testcases/lib/daemonlib.sh' library that
748provides functions to start/stop/query daemons as well as variables that store
749correct daemon name.
750
751.Supported operations
752|==============================================================================
753| start_daemon()   | Starts daemon, name is passed as first parameter.
754| stop_daemon()    | Stops daemon, name is passed as first parameter.
755| restart_daemon() | Restarts daemon, name is passed as first parameter.
756| status_daemon()  | Detect daemon status (exit code: 0: running, 1: not running).
757|==============================================================================
758
759.Variables with detected names
760|==============================================================================
761| CROND_DAEMON | Cron daemon name (cron, crond).
762| SYSLOG_DAEMON | Syslog daemon name (syslog, syslog-ng, rsyslog).
763|==============================================================================
764
765Cron daemon restart example
766+++++++++++++++++++++++++++
767
768[source,sh]
769-------------------------------------------------------------------------------
770#!/bin/sh
771# SPDX-License-Identifier: GPL-2.0-or-later
772# Cron daemon restart example
773
774TCID=cron01
775TST_COUNT=1
776. test.sh
777. daemonlib.sh
778
779...
780
781restart_daemon $CROND_DAEMON
782
783...
784
785tst_exit
786-------------------------------------------------------------------------------
787
7881.6 Access to the checkpoint interface
789~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
790
791The shell library provides an implementation of the checkpoint interface
792compatible with the C version. All 'TST_CHECKPOINT_*' functions are available.
793
794In order to initialize checkpoints '$TST_NEEDS_CHECKPOINTS' must be set to '1'
795before the inclusion of 'tst_test.sh':
796
797[source,sh]
798-------------------------------------------------------------------------------
799#!/bin/sh
800
801TST_NEEDS_CHECKPOINTS=1
802. tst_test.sh
803-------------------------------------------------------------------------------
804
805Since both the implementations are compatible, it's also possible to start
806a child binary process from a shell test and synchronize with it. This process
807must have checkpoints initialized by calling 'tst_reinit()'.
808
8091.7 Parsing kernel .config
810~~~~~~~~~~~~~~~~~~~~~~~~~~
811The shell library provides an implementation of the kconfig parsing interface
812compatible with the C version.
813
814It's possible to pass kernel kconfig list for tst_require_kconfigs API with
815'$TST_NEEDS_KCONFIGS'.
816Optional '$TST_NEEDS_KCONFIGS_IFS' is used for splitting, default value is comma.
817
818-------------------------------------------------------------------------------
819#!/bin/sh
820TST_NEEDS_KCONFIGS="CONFIG_EXT4_FS, CONFIG_QUOTACTL=y"
821
822. tst_test.sh
823-------------------------------------------------------------------------------
824
8251.8 Skipping test based on system state
826~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
827Test can be skipped on various conditions: on enabled SecureBoot
828('TST_SKIP_IN_SECUREBOOT=1'), lockdown ('TST_SKIP_IN_LOCKDOWN=1').
829