xref: /aosp_15_r20/external/ltp/lib/README.md (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker# Test library design document
2*49cdfc7eSAndroid Build Coastguard Worker
3*49cdfc7eSAndroid Build Coastguard Worker## High-level picture
4*49cdfc7eSAndroid Build Coastguard Worker
5*49cdfc7eSAndroid Build Coastguard Worker    library process
6*49cdfc7eSAndroid Build Coastguard Worker    +----------------------------+
7*49cdfc7eSAndroid Build Coastguard Worker    | main                       |
8*49cdfc7eSAndroid Build Coastguard Worker    |  tst_run_tcases            |
9*49cdfc7eSAndroid Build Coastguard Worker    |   do_setup                 |
10*49cdfc7eSAndroid Build Coastguard Worker    |   for_each_variant         |
11*49cdfc7eSAndroid Build Coastguard Worker    |    for_each_filesystem     |   test process
12*49cdfc7eSAndroid Build Coastguard Worker    |     fork_testrun ------------->+--------------------------------------------+
13*49cdfc7eSAndroid Build Coastguard Worker    |      waitpid               |   | testrun                                    |
14*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |  do_test_setup                             |
15*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |   tst_test->setup                          |
16*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |  run_tests                                 |
17*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |   tst_test->test(i) or tst_test->test_all  |
18*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |  do_test_cleanup                           |
19*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |   tst_test->cleanup                        |
20*49cdfc7eSAndroid Build Coastguard Worker    |                            |   |  exit(0)                                   |
21*49cdfc7eSAndroid Build Coastguard Worker    |   do_exit                  |   +--------------------------------------------+
22*49cdfc7eSAndroid Build Coastguard Worker    |    do_cleanup              |
23*49cdfc7eSAndroid Build Coastguard Worker    |     exit(ret)              |
24*49cdfc7eSAndroid Build Coastguard Worker    +----------------------------+
25*49cdfc7eSAndroid Build Coastguard Worker
26*49cdfc7eSAndroid Build Coastguard Worker## Test lifetime overview
27*49cdfc7eSAndroid Build Coastguard Worker
28*49cdfc7eSAndroid Build Coastguard WorkerWhen a test is executed the very first thing to happen is that we check for
29*49cdfc7eSAndroid Build Coastguard Workervarious test prerequisites. These are described in the tst\_test structure and
30*49cdfc7eSAndroid Build Coastguard Workerrange from simple '.needs\_root' to a more complicated kernel .config boolean
31*49cdfc7eSAndroid Build Coastguard Workerexpressions such as: "CONFIG\_X86\_INTEL\_UMIP=y | CONFIG\_X86\_UMIP=y".
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard WorkerIf all checks are passed, the process continues with setting up the test
34*49cdfc7eSAndroid Build Coastguard Workerenvironment as requested in the tst\_test structure. There are many different
35*49cdfc7eSAndroid Build Coastguard Workersetup steps that have been put into the test library again ranging from rather
36*49cdfc7eSAndroid Build Coastguard Workersimple creation of a unique test temporary directory to a bit more complicated
37*49cdfc7eSAndroid Build Coastguard Workerones such as preparing, formatting, and mounting a block device.
38*49cdfc7eSAndroid Build Coastguard Worker
39*49cdfc7eSAndroid Build Coastguard WorkerThe test library also initializes shared memory used for IPC at this step.
40*49cdfc7eSAndroid Build Coastguard Worker
41*49cdfc7eSAndroid Build Coastguard WorkerOnce all the prerequisites are checked and test environment has been prepared
42*49cdfc7eSAndroid Build Coastguard Workerwe can move on executing the testcase itself. The actual test is executed in a
43*49cdfc7eSAndroid Build Coastguard Workerforked process, however there are a few hops before we get there.
44*49cdfc7eSAndroid Build Coastguard Worker
45*49cdfc7eSAndroid Build Coastguard WorkerFirst of all there are test variants, which means that the test is re-executed
46*49cdfc7eSAndroid Build Coastguard Workerseveral times with a slightly different setting. This is usually used to test a
47*49cdfc7eSAndroid Build Coastguard Workerfamily of similar syscalls, where we test each of these syscalls exactly the
48*49cdfc7eSAndroid Build Coastguard Workersame, but without re-executing the test binary itself. Test variants are
49*49cdfc7eSAndroid Build Coastguard Workerimplemented as a simple global variable counter that gets increased on each
50*49cdfc7eSAndroid Build Coastguard Workeriteration. In a case of syscall tests we switch between which syscall to call
51*49cdfc7eSAndroid Build Coastguard Workerbased on the global counter.
52*49cdfc7eSAndroid Build Coastguard Worker
53*49cdfc7eSAndroid Build Coastguard WorkerThen there is all\_filesystems flag which is mostly the same as test variants
54*49cdfc7eSAndroid Build Coastguard Workerbut executes the test for each filesystem supported by the system. Note that we
55*49cdfc7eSAndroid Build Coastguard Workercan get cartesian product between test variants and all filesystems as well.
56*49cdfc7eSAndroid Build Coastguard Worker
57*49cdfc7eSAndroid Build Coastguard WorkerIn a pseudo code it could be expressed as:
58*49cdfc7eSAndroid Build Coastguard Worker
59*49cdfc7eSAndroid Build Coastguard Worker```
60*49cdfc7eSAndroid Build Coastguard Workerfor test_variants:
61*49cdfc7eSAndroid Build Coastguard Worker	for all_filesystems:
62*49cdfc7eSAndroid Build Coastguard Worker		fork_testrun()
63*49cdfc7eSAndroid Build Coastguard Worker```
64*49cdfc7eSAndroid Build Coastguard Worker
65*49cdfc7eSAndroid Build Coastguard WorkerBefore we fork the test process, the test library sets up a timeout alarm and
66*49cdfc7eSAndroid Build Coastguard Workera heartbeat signal handler and it also sets up an alarm(2) accordingly to
67*49cdfc7eSAndroid Build Coastguard Workerthe test timeout. When a test times out, the test library gets SIGALRM and the
68*49cdfc7eSAndroid Build Coastguard Workeralarm handler mercilessly kills all forked children by sending SIGKILL to the
69*49cdfc7eSAndroid Build Coastguard Workerwhole process group. The heartbeat handler is used by the test process to reset
70*49cdfc7eSAndroid Build Coastguard Workerthis timer for example when the test functions run in a loop.
71*49cdfc7eSAndroid Build Coastguard Worker
72*49cdfc7eSAndroid Build Coastguard WorkerWith that done we finally fork() the test process. The test process firstly
73*49cdfc7eSAndroid Build Coastguard Workerresets signal handlers and sets its pid to be a process group leader so that we
74*49cdfc7eSAndroid Build Coastguard Workercan slaughter all children if needed. The test library proceeds with suspending
75*49cdfc7eSAndroid Build Coastguard Workeritself in waitpid() syscall and waits for the child to finish at this point.
76*49cdfc7eSAndroid Build Coastguard Worker
77*49cdfc7eSAndroid Build Coastguard WorkerThe test process goes ahead and calls the test setup() function if present in
78*49cdfc7eSAndroid Build Coastguard Workerthe tst\_test structure. It's important that we execute all test callbacks
79*49cdfc7eSAndroid Build Coastguard Workerafter we have forked the process, that way we cannot crash the test library
80*49cdfc7eSAndroid Build Coastguard Workerprocess. The setup can also cause the test to exit prematurely by either direct
81*49cdfc7eSAndroid Build Coastguard Workeror indirect (SAFE\_MACROS()) call to tst\_brk().  In this case the
82*49cdfc7eSAndroid Build Coastguard Workerfork\_testrun() function exits, but the loops for test variants or filesystems
83*49cdfc7eSAndroid Build Coastguard Workercarries on.
84*49cdfc7eSAndroid Build Coastguard Worker
85*49cdfc7eSAndroid Build Coastguard WorkerAll that is left to be done is to actually execute the tests, what happnes now
86*49cdfc7eSAndroid Build Coastguard Workerdepends on the -i and -I command line parameters that can request that the
87*49cdfc7eSAndroid Build Coastguard Workerrun() or run\_all() callbacks are executed N times or for N seconds. Again the
88*49cdfc7eSAndroid Build Coastguard Workertest can exit at any time by direct or indirect call to tst\_brk().
89*49cdfc7eSAndroid Build Coastguard Worker
90*49cdfc7eSAndroid Build Coastguard WorkerOnce the test is finished all that is left for the test process is the test
91*49cdfc7eSAndroid Build Coastguard Workercleanup(). So if a there is a cleanup() callback in the tst\_test structure
92*49cdfc7eSAndroid Build Coastguard Workerit's executed. The cleanup() callback runs in a special context where the
93*49cdfc7eSAndroid Build Coastguard Workertst\_brk(TBROK, ...) calls are converted into tst\_res(TWARN, ...) calls. This
94*49cdfc7eSAndroid Build Coastguard Workeris because we found out that carrying on with partially broken cleanup is
95*49cdfc7eSAndroid Build Coastguard Workerusually better option than exiting it in the middle.
96*49cdfc7eSAndroid Build Coastguard Worker
97*49cdfc7eSAndroid Build Coastguard WorkerThe test cleanup() is also called by the tst\_brk() handler in order to cleanup
98*49cdfc7eSAndroid Build Coastguard Workerbefore exiting the test process, hence it must be able to cope even with
99*49cdfc7eSAndroid Build Coastguard Workerpartial test setup. Usually it suffices to make sure to clean up only
100*49cdfc7eSAndroid Build Coastguard Workerresources that already have been set up and to do that in the reverse order
101*49cdfc7eSAndroid Build Coastguard Workerthat we did in setup().
102*49cdfc7eSAndroid Build Coastguard Worker
103*49cdfc7eSAndroid Build Coastguard WorkerOnce the test process exits or leaves the run() or run\_all() function the test
104*49cdfc7eSAndroid Build Coastguard Workerlibrary wakes up from the waitpid() call, and checks if the test process
105*49cdfc7eSAndroid Build Coastguard Workerexited normally.
106*49cdfc7eSAndroid Build Coastguard Worker
107*49cdfc7eSAndroid Build Coastguard WorkerOnce the testrun is finished, the test library does a cleanup() as well to clean
108*49cdfc7eSAndroid Build Coastguard Workerup resources set up in the test library setup(), reports test results and
109*49cdfc7eSAndroid Build Coastguard Workerfinally exits the process.
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker### Test library and fork()-ing
112*49cdfc7eSAndroid Build Coastguard Worker
113*49cdfc7eSAndroid Build Coastguard WorkerThings are a bit more complicated when fork()-ing is involved, however the test
114*49cdfc7eSAndroid Build Coastguard Workerresults are stored in a page of a shared memory and incremented by atomic
115*49cdfc7eSAndroid Build Coastguard Workeroperations, hence the results are stored right after the test reporting
116*49cdfc7eSAndroid Build Coastguard Workerfunction returns from the test library and the access is, by definition,
117*49cdfc7eSAndroid Build Coastguard Workerrace-free as well.
118*49cdfc7eSAndroid Build Coastguard Worker
119*49cdfc7eSAndroid Build Coastguard WorkerOn the other hand the test library, apart from sending a SIGKILL to the whole
120*49cdfc7eSAndroid Build Coastguard Workerprocess group on timeout, does not track grandchildren.
121*49cdfc7eSAndroid Build Coastguard Worker
122*49cdfc7eSAndroid Build Coastguard WorkerThis especially means that:
123*49cdfc7eSAndroid Build Coastguard Worker
124*49cdfc7eSAndroid Build Coastguard Worker- The test exits once the main test process exits.
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker- While the test results are, by the design, propagated to the test library
127*49cdfc7eSAndroid Build Coastguard Worker  we may still miss a child that gets killed by a signal or exits unexpectedly.
128*49cdfc7eSAndroid Build Coastguard Worker
129*49cdfc7eSAndroid Build Coastguard WorkerThe test writer should, because of this, take care of reaping these
130*49cdfc7eSAndroid Build Coastguard Workerprocesses properly, in most cases this could be simply done by calling
131*49cdfc7eSAndroid Build Coastguard Workertst\_reap\_children() to collect and dissect deceased.
132*49cdfc7eSAndroid Build Coastguard Worker
133*49cdfc7eSAndroid Build Coastguard WorkerAlso note that tst\_brk() does exit only the current process, so if a child
134*49cdfc7eSAndroid Build Coastguard Workerprocess calls tst\_brk() the counters are incremented and only the process
135*49cdfc7eSAndroid Build Coastguard Workerexits.
136*49cdfc7eSAndroid Build Coastguard Worker
137*49cdfc7eSAndroid Build Coastguard Worker### Test library and exec()
138*49cdfc7eSAndroid Build Coastguard Worker
139*49cdfc7eSAndroid Build Coastguard WorkerThe piece of mapped memory to store the results is not preserved over
140*49cdfc7eSAndroid Build Coastguard Workerexec(2), hence to use the test library from a binary started by an exec() it
141*49cdfc7eSAndroid Build Coastguard Workerhas to be remapped. In this case, the process must call tst\_reinit() before
142*49cdfc7eSAndroid Build Coastguard Workercalling any other library functions. In order to make this happen the program
143*49cdfc7eSAndroid Build Coastguard Workerenvironment carries LTP\_IPC\_PATH variable with a path to the backing file on
144*49cdfc7eSAndroid Build Coastguard Workertmpfs. This also allows us to use the test library from shell testcases.
145*49cdfc7eSAndroid Build Coastguard Worker
146*49cdfc7eSAndroid Build Coastguard Worker### Test library and process synchronization
147*49cdfc7eSAndroid Build Coastguard Worker
148*49cdfc7eSAndroid Build Coastguard WorkerThe piece of mapped memory is also used as a base for a futex-based
149*49cdfc7eSAndroid Build Coastguard Workersynchronization primitives called checkpoints. And as said previously the
150*49cdfc7eSAndroid Build Coastguard Workermemory can be mapped to any process by calling the tst\_reinit() function. As a
151*49cdfc7eSAndroid Build Coastguard Workermatter of a fact, there is even a tst\_checkpoint binary that allows us to use
152*49cdfc7eSAndroid Build Coastguard Workerthe checkpoints from shell code as well.
153