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