1f08c3bdfSopenharmony_ciMotivation for metadata extraction 2f08c3bdfSopenharmony_ci================================== 3f08c3bdfSopenharmony_ci 4f08c3bdfSopenharmony_ciExporting documentation 5f08c3bdfSopenharmony_ci----------------------- 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ciThis allow us to build browsable documentation for the testcases, e.g. a 8f08c3bdfSopenharmony_cicatalogue of test information that would be searchable etc. At this point there 9f08c3bdfSopenharmony_ciis a single page generated from the extracted data that tries to outline the 10f08c3bdfSopenharmony_ciintent. 11f08c3bdfSopenharmony_ci 12f08c3bdfSopenharmony_ci 13f08c3bdfSopenharmony_ciPropagating test requirements 14f08c3bdfSopenharmony_ci----------------------------- 15f08c3bdfSopenharmony_ci 16f08c3bdfSopenharmony_ciSome subtests require different hardware resources/software versions/etc. the 17f08c3bdfSopenharmony_citest execution framework needs to consume these so that it can locate proper 18f08c3bdfSopenharmony_cihardware, install proper software, etc. 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ciSome examples of requirements are: 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci* Test needs at least 1GB of RAM. 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ci* Test needs a block device at least 512MB in size 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_ci* Test needs a NUMA machine with two memory nodes and at least 300 free pages on each node 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci* Test needs i2c eeprom connected on a i2c bus 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci* Test needs two serial ports connected via null-modem cable 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ciWith this information extracted from the tests the testrunner can then map the 34f08c3bdfSopenharmony_cirequirements on the available machines in a lab and select a proper machine for 35f08c3bdfSopenharmony_cithe particular (sub)set of testcases as well as supply a particular test with 36f08c3bdfSopenharmony_ciadditional information needed for the test, such as address of the i2c device, 37f08c3bdfSopenharmony_cipaths to the serial devices, etc. In the case of virtual machines the test could 38f08c3bdfSopenharmony_cialso dynamically prepare the correct environment for the test on demand. 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ciParallel test execution 42f08c3bdfSopenharmony_ci----------------------- 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ciAn LTP testrun on a modern hardware wastes most of the machine resources 45f08c3bdfSopenharmony_cibecause the testcases are running sequentially. However in order to execute 46f08c3bdfSopenharmony_citests in parallel we need to know which system resources are utilized by a 47f08c3bdfSopenharmony_cigiven test, as obviously we cannot run two tests that monopolize the same 48f08c3bdfSopenharmony_ciresource. In some cases we would also need to partition the system resource 49f08c3bdfSopenharmony_ciaccordingly, e.g. if we have two memory stress tests running at the same time 50f08c3bdfSopenharmony_ciwe will need to cap each of these tests on half of the available memory, or 51f08c3bdfSopenharmony_cimake sure that sum of the memory used by these two tests is not greater than 52f08c3bdfSopenharmony_ciavailable memory. 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ciExamples of such tests are: 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci* Tests that mess with global system state 57f08c3bdfSopenharmony_ci - system time (e.g. settimeofday() test and leap second test) 58f08c3bdfSopenharmony_ci - SysV SHM 59f08c3bdfSopenharmony_ci - ... 60f08c3bdfSopenharmony_ci 61f08c3bdfSopenharmony_ci* Tests that use block device 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ci* Tests that work with a particular hardware resource 64f08c3bdfSopenharmony_ci - i2c eeprom test 65f08c3bdfSopenharmony_ci - serial port tests 66f08c3bdfSopenharmony_ci - ... 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_ciExporting test runtime/timeout to the testrunner 69f08c3bdfSopenharmony_ci------------------------------------------------ 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ciCurrently most of the testrunners usually do not know for how long is the test 72f08c3bdfSopenharmony_cisupposed to run, this means that we have to guess some upper limit on how long 73f08c3bdfSopenharmony_cia test is supposed to run. The value is usually twice of the maximal runtime 74f08c3bdfSopenharmony_cifor all testcases or whole suite or even larger. This means that we are wasting 75f08c3bdfSopenharmony_citime in the case that the test ends up stuck and we could have failed it much 76f08c3bdfSopenharmony_cisooner in most of the cases. This becomes quite important for a kernel 77f08c3bdfSopenharmony_ciregression tests that do crash the host, if the information that the test is 78f08c3bdfSopenharmony_cisupposed to crash a kernel under a minute is exported to the testrunner we can 79f08c3bdfSopenharmony_cireboot the machine much faster in an event of a crash. 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ciGetting rid of runtest files 82f08c3bdfSopenharmony_ci---------------------------- 83f08c3bdfSopenharmony_ci 84f08c3bdfSopenharmony_ciThis would also allow us to get rid of the unflexible and hard to maintain 85f08c3bdfSopenharmony_ciruntest files. Once this system is in place we will have a list of all tests 86f08c3bdfSopenharmony_cialong with their respective metadata - which means that we will be able to 87f08c3bdfSopenharmony_cigenerate subsets of the test easily on the fly. 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ciIn order to achieve this we need two things: 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ciEach test will describe which syscall/functionality it tests in the metadata. 92f08c3bdfSopenharmony_ciThen we could define groups of tests based on that. I.e. instead of having 93f08c3bdfSopenharmony_cisyscall runtest file we would ask the testrunner to run all test that have a 94f08c3bdfSopenharmony_cidefined which syscall they test, or whose filename matches a particular syscall name. 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ciSecondly we will have to store the test variants in the test metadata instead 97f08c3bdfSopenharmony_ciof putting them in a file that is unrelated to the test. 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ciFor example: 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci* To run CVE related test we would select testcases with CVE tag 102f08c3bdfSopenharmony_ci 103f08c3bdfSopenharmony_ci* To run IPC test we will define a list of IPC syscalls and run all syscall 104f08c3bdfSopenharmony_ci test that are in the list 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci* And many more... 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci 109f08c3bdfSopenharmony_ciImplementation 110f08c3bdfSopenharmony_ci============== 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ciThe docparser is implemented as a minimal C tokenizer that can parse and 113f08c3bdfSopenharmony_ciextract code comments and C structures. The docparser then runs over all C 114f08c3bdfSopenharmony_cisources in the testcases directory and if tst\_test structure is present in the 115f08c3bdfSopenharmony_cisource it's parsed and the result is included in the resulting metadata. 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ciDuring parsing the metadata is stored in a simple key/value storage that more 118f08c3bdfSopenharmony_cior less follows C structure layout, i.e. can include hash, array, and string. 119f08c3bdfSopenharmony_ciOnce the parsing is finished the result is filtered so that only interesting 120f08c3bdfSopenharmony_cifields of the tst\_test structure are included and then converted into JSON 121f08c3bdfSopenharmony_cioutput. 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ciThis process produces one big JSON file with metadata for all tests, that 124f08c3bdfSopenharmony_ciis then installed along with the testcases. This would then be used by the 125f08c3bdfSopenharmony_citestrunner. 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ciThe test requirements are stored in the tst\_test structure either as 128f08c3bdfSopenharmony_cibitflags, integers or arrays of strings: 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci```c 131f08c3bdfSopenharmony_cistruct tst_test test = { 132f08c3bdfSopenharmony_ci ... 133f08c3bdfSopenharmony_ci /* tests needs to run with UID=0 */ 134f08c3bdfSopenharmony_ci .needs_root = 1, 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci /* 137f08c3bdfSopenharmony_ci * Tests needs a block device at least 1024MB in size and also 138f08c3bdfSopenharmony_ci * mkfs.ext4 installed. 139f08c3bdfSopenharmony_ci */ 140f08c3bdfSopenharmony_ci .needs_device = 1, 141f08c3bdfSopenharmony_ci .dev_min_size = 1024, 142f08c3bdfSopenharmony_ci .dev_fs_type = ext4, 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci /* Indicates that the test is messing with system wall clock */ 145f08c3bdfSopenharmony_ci .restore_wallclock = 1, 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci /* Tests needs uinput either compiled in or loaded as a module */ 148f08c3bdfSopenharmony_ci .needs_drivers = (const char *[]) { 149f08c3bdfSopenharmony_ci "uinput", 150f08c3bdfSopenharmony_ci NULL 151f08c3bdfSopenharmony_ci }, 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci /* Tests needs enabled kernel config flags */ 154f08c3bdfSopenharmony_ci .needs_kconfigs = (const char *[]) { 155f08c3bdfSopenharmony_ci "CONFIG_X86_INTEL_UMIP=y", 156f08c3bdfSopenharmony_ci NULL 157f08c3bdfSopenharmony_ci }, 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci /* Additional array of key value pairs */ 160f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 161f08c3bdfSopenharmony_ci {"linux-git", "43a6684519ab"}, 162f08c3bdfSopenharmony_ci {"CVE", "2017-2671"}, 163f08c3bdfSopenharmony_ci {NULL, NULL} 164f08c3bdfSopenharmony_ci } 165f08c3bdfSopenharmony_ci}; 166f08c3bdfSopenharmony_ci``` 167f08c3bdfSopenharmony_ci 168f08c3bdfSopenharmony_ciThe test documentation is stored in a special comment such as: 169f08c3bdfSopenharmony_ci 170f08c3bdfSopenharmony_ci``` 171f08c3bdfSopenharmony_ci/*\ 172f08c3bdfSopenharmony_ci * Test description 173f08c3bdfSopenharmony_ci * 174f08c3bdfSopenharmony_ci * This is a test description. 175f08c3bdfSopenharmony_ci * Consisting of several lines. 176f08c3bdfSopenharmony_ci */ 177f08c3bdfSopenharmony_ci``` 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ciWhich will yield following JSON output: 180f08c3bdfSopenharmony_ci 181f08c3bdfSopenharmony_ci```json 182f08c3bdfSopenharmony_ci "testcaseXY": { 183f08c3bdfSopenharmony_ci "needs_root": "1", 184f08c3bdfSopenharmony_ci "needs_device": "1", 185f08c3bdfSopenharmony_ci "dev_min_size": "1024", 186f08c3bdfSopenharmony_ci "dev_fs_type": "ext4", 187f08c3bdfSopenharmony_ci "restore_wallclock": "1", 188f08c3bdfSopenharmony_ci "needs_drivers": [ 189f08c3bdfSopenharmony_ci "uinput", 190f08c3bdfSopenharmony_ci ], 191f08c3bdfSopenharmony_ci "needs_kconfigs": [ 192f08c3bdfSopenharmony_ci "CONFIG_X86_INTEL_UMIP=y", 193f08c3bdfSopenharmony_ci ], 194f08c3bdfSopenharmony_ci "tags": [ 195f08c3bdfSopenharmony_ci [ 196f08c3bdfSopenharmony_ci "linux-git", 197f08c3bdfSopenharmony_ci "43a6684519ab" 198f08c3bdfSopenharmony_ci ], 199f08c3bdfSopenharmony_ci [ 200f08c3bdfSopenharmony_ci "CVE", 201f08c3bdfSopenharmony_ci "2017-2671" 202f08c3bdfSopenharmony_ci ], 203f08c3bdfSopenharmony_ci ], 204f08c3bdfSopenharmony_ci "doc": [ 205f08c3bdfSopenharmony_ci "Test description", 206f08c3bdfSopenharmony_ci "", 207f08c3bdfSopenharmony_ci "This is a test description.", 208f08c3bdfSopenharmony_ci "Consisting of several lines." 209f08c3bdfSopenharmony_ci ], 210f08c3bdfSopenharmony_ci "fname": "testcases/kernel/syscalls/foo/testcaseXY.c" 211f08c3bdfSopenharmony_ci }, 212f08c3bdfSopenharmony_ci``` 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ciThe final JSON file is JSON object of test descriptions indexed by a test name 215f08c3bdfSopenharmony_ciwith a header describing the testsuite: 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci```json 218f08c3bdfSopenharmony_ci{ 219f08c3bdfSopenharmony_ci "testsuite": "Linux Test Project", 220f08c3bdfSopenharmony_ci "testsuite_short": "LTP", 221f08c3bdfSopenharmony_ci "url": "https://github.com/linux-test-project/ltp/", 222f08c3bdfSopenharmony_ci "scm_url_base": "https://github.com/linux-test-project/ltp/tree/master/", 223f08c3bdfSopenharmony_ci "timeout": 300, 224f08c3bdfSopenharmony_ci "version": "20200930", 225f08c3bdfSopenharmony_ci "tests": { 226f08c3bdfSopenharmony_ci "testcaseXY": { 227f08c3bdfSopenharmony_ci ... 228f08c3bdfSopenharmony_ci }, 229f08c3bdfSopenharmony_ci ... 230f08c3bdfSopenharmony_ci } 231f08c3bdfSopenharmony_ci} 232f08c3bdfSopenharmony_ci``` 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ciOpen Points 235f08c3bdfSopenharmony_ci=========== 236f08c3bdfSopenharmony_ci 237f08c3bdfSopenharmony_ciThere are stil some loose ends. Mostly it's not well defined where to put 238f08c3bdfSopenharmony_cithings and how to format them. 239f08c3bdfSopenharmony_ci 240f08c3bdfSopenharmony_ci* Some of the hardware requirements are already listed in the tst\_test. Should 241f08c3bdfSopenharmony_ci we put all of them there? 242f08c3bdfSopenharmony_ci 243f08c3bdfSopenharmony_ci* What would be the format for test documentation and how to store things such 244f08c3bdfSopenharmony_ci as test variants there? 245f08c3bdfSopenharmony_ci 246f08c3bdfSopenharmony_ciSo far this proof of concept generates a metadata file. I guess that we need 247f08c3bdfSopenharmony_ciactual consumers which will help to settle things down, I will try to look into 248f08c3bdfSopenharmony_cimaking use of this in the runltp-ng at least as a reference implementation. 249