1f08c3bdfSopenharmony_ciC Test Case Tutorial 2f08c3bdfSopenharmony_ci==================== 3f08c3bdfSopenharmony_ci 4f08c3bdfSopenharmony_ciNOTE: See also 5f08c3bdfSopenharmony_ci https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[Test Writing Guidelines], 6f08c3bdfSopenharmony_ci https://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API]. 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ciThis is a step-by-step tutorial on writing a simple C LTP test, where topics 9f08c3bdfSopenharmony_ciof the LTP and Linux kernel testing will be introduced gradually using a 10f08c3bdfSopenharmony_ciconcrete example. Most sections will include exercises, some trivial and 11f08c3bdfSopenharmony_ciothers not so much. If you find an exercise is leading you off at too much of 12f08c3bdfSopenharmony_cia tangent, just leave it for later and move on. 13f08c3bdfSopenharmony_ci 14f08c3bdfSopenharmony_ciLTP tests can be written in C or Shell script. This tutorial is only for tests 15f08c3bdfSopenharmony_ciwritten in C using the new LTP test API. Note that while we go into some 16f08c3bdfSopenharmony_cidetail on using Git, this is not intended as a canonical or complete guide 17f08c3bdfSopenharmony_cifor Git. 18f08c3bdfSopenharmony_ci 19f08c3bdfSopenharmony_ci0. Assumptions & Feedback 20f08c3bdfSopenharmony_ci------------------------- 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ciWe assume the reader is familiar with C, Git and common Unix/Linux/GNU tools 23f08c3bdfSopenharmony_ciand has some general knowledge of Operating Systems. Experienced Linux 24f08c3bdfSopenharmony_cidevelopers may find it too verbose while people new to system level Linux 25f08c3bdfSopenharmony_cidevelopment may find it overwhelming. 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_ciComments and feedback are welcome, please direct them to 28f08c3bdfSopenharmony_cihttps://lists.linux.it/listinfo/ltp[the mailing list]. 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci1. Getting Started 31f08c3bdfSopenharmony_ci------------------ 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ciGit-clone the main LTP repository as described in 34f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp#quick-guide-to-running-the-tests[the +README.md+] 35f08c3bdfSopenharmony_ciand change directory to the checked-out Git repository. We recommend installing the LTP 36f08c3bdfSopenharmony_ciand running one of the tests mentioned in the Quick guide (in the +README.md+) to 37f08c3bdfSopenharmony_ciensure you are starting from a good state. 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ciWe also recommended cloning the Linux kernel repository for reference, this 40f08c3bdfSopenharmony_ciguide will refer to files and directories within the mainline kernel 4.12. 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci[source,shell] 43f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 44f08c3bdfSopenharmony_ci$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 45f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ciThere are a number of other repositories which are useful for reference as 48f08c3bdfSopenharmony_ciwell, including the GNU C library +glibc+ and the alternative C library 49f08c3bdfSopenharmony_ci+musl+. Some system calls are partially or even entirely implemented in user 50f08c3bdfSopenharmony_ciland as part of the standard C library. So in these cases, the C library is an 51f08c3bdfSopenharmony_ciimportant reference. +glibc+ is the most common C library for Linux, however 52f08c3bdfSopenharmony_ci+musl+ is generally easier to understand. 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ciHow system calls are implemented varies from one architecture to another and 55f08c3bdfSopenharmony_ciacross kernel and C library versions. To find out whether a system call is 56f08c3bdfSopenharmony_ciactually accessing the kernel (whether it is actually a system call) on any 57f08c3bdfSopenharmony_cigiven machine you can use the +strace+ utility. This intercepts system calls 58f08c3bdfSopenharmony_cimade by an executable and prints them. We will use this later in the tutorial. 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci2. Choose a System Call to test 61f08c3bdfSopenharmony_ci------------------------------- 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_ciWe will use the +statx()+ system call, to provide a concrete example of a 64f08c3bdfSopenharmony_citest. At the time of writing there is no test for this call which was 65f08c3bdfSopenharmony_ciintroduced in Linux kernel version 4.11. 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ciLinux system call specific tests are primarily contained in 68f08c3bdfSopenharmony_ci+testcases/kernel/syscalls+, but you should also +git grep+ the entire LTP 69f08c3bdfSopenharmony_cirepository to check for any existing usages of a system call. 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ciOne way to find a system call which is not currently tested by the LTP is to 72f08c3bdfSopenharmony_cilook at +include/linux/syscalls.h+ in the kernel tree. 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ciSomething the LTP excels at is ensuring bug-fixes are back ported to 75f08c3bdfSopenharmony_cimaintenance releases, so targeting a specific regression is another 76f08c3bdfSopenharmony_cioption. 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci2.1. Find an untested System call 79f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ciTry to find an untested system call which has a manual page (i.e. +man 82f08c3bdfSopenharmony_cisyscall+ produces a result). It is a good idea to Git-clone the latest kernel 83f08c3bdfSopenharmony_ciman-pages repository. 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci[source,shell] 86f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 87f08c3bdfSopenharmony_ci$ git clone git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git 88f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 89f08c3bdfSopenharmony_ci 90f08c3bdfSopenharmony_ciAt the time of writing the difference between the latest man-pages release and 91f08c3bdfSopenharmony_cithe +HEAD+ of the repository (usually the latest commit) is well over 100 92f08c3bdfSopenharmony_cicommits. This represents about 9 weeks of changes. If you are using a stable 93f08c3bdfSopenharmony_ciLinux distribution, your man-pages package may well be years old. So as with 94f08c3bdfSopenharmony_cithe kernel, it is best to have the Git repository as a reference. 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ciYou could also find a system call with untested parameters or use whatever it 97f08c3bdfSopenharmony_ciis you are planning to use the LTP for. 98f08c3bdfSopenharmony_ci 99f08c3bdfSopenharmony_ci3. Create the test skeleton 100f08c3bdfSopenharmony_ci--------------------------- 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ciI shall call my test +statx01.c+, by the time you read this that file name 103f08c3bdfSopenharmony_ciwill probably be taken, so increment the number in the file name as 104f08c3bdfSopenharmony_ciappropriate or replace +statx+ with the system call chosen in exercise 2.1. 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci[source,shell] 107f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 108f08c3bdfSopenharmony_ci$ mkdir testcases/kernel/syscalls/statx 109f08c3bdfSopenharmony_ci$ cd testcases/kernel/syscalls/statx 110f08c3bdfSopenharmony_ci$ echo statx >> .gitignore 111f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ciNext open +statx01.c+ and add the following boilerplate. Make sure to change 114f08c3bdfSopenharmony_cithe copy right notice to your name/company, correct the test name and minimum 115f08c3bdfSopenharmony_cikernel version if necessary. I will explain what the code does below. 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci[source,c] 118f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 119f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 120f08c3bdfSopenharmony_ci/* 121f08c3bdfSopenharmony_ci * Copyright (c) 2017 Instruction Ignorer <"can't"@be.bothered.com> 122f08c3bdfSopenharmony_ci */ 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci/*\ 125f08c3bdfSopenharmony_ci * [Description] 126f08c3bdfSopenharmony_ci * 127f08c3bdfSopenharmony_ci * All tests should start with a description of _what_ we are testing. 128f08c3bdfSopenharmony_ci * Non-trivial explanations of _how_ the code works should also go here. 129f08c3bdfSopenharmony_ci * Include relevant links, Git commit hashes and CVE numbers. 130f08c3bdfSopenharmony_ci * Inline comments should be avoided. 131f08c3bdfSopenharmony_ci */ 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci#include "tst_test.h" 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_cistatic void run(void) 136f08c3bdfSopenharmony_ci{ 137f08c3bdfSopenharmony_ci tst_res(TPASS, "Doing hardly anything is easy"); 138f08c3bdfSopenharmony_ci} 139f08c3bdfSopenharmony_ci 140f08c3bdfSopenharmony_cistatic struct tst_test test = { 141f08c3bdfSopenharmony_ci .test_all = run, 142f08c3bdfSopenharmony_ci .min_kver = "4.11", 143f08c3bdfSopenharmony_ci}; 144f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ciStarting with the +#include+ statement we copy in the main LTP test library 147f08c3bdfSopenharmony_ciheaders. This includes the most common test API functions and the test harness 148f08c3bdfSopenharmony_ciinitialisation code. It is important to note that this is a completely 149f08c3bdfSopenharmony_ciordinary, independent C program, however +main()+ is missing because it is 150f08c3bdfSopenharmony_ciimplemented in +tst_test.h+. 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_ciWe specify what code we want to run as part of the test using the +tst_test 153f08c3bdfSopenharmony_citest+ structure. Various callbacks can be set by the test writer, including 154f08c3bdfSopenharmony_ci+test.test_all+, which we have set to +run()+. The test harness will execute 155f08c3bdfSopenharmony_cithis callback in a separate process (using +fork()+), forcibly terminating it 156f08c3bdfSopenharmony_ciif it does not return after +test.timeout+ seconds. 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ciWe have also set +test.min_kver+ to the kernel version where +statx+ was 159f08c3bdfSopenharmony_ciintroduced. The test library will determine the kernel version at runtime. If 160f08c3bdfSopenharmony_cithe version is less than 4.11 then the test harness will return +TCONF+, 161f08c3bdfSopenharmony_ciindicating that this test is not suitable for the current system 162f08c3bdfSopenharmony_ciconfiguration. 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ciOccasionally features are back ported to older kernel versions, so +statx+ may 165f08c3bdfSopenharmony_ciexist on kernels with a lower version. However we don't need to worry about 166f08c3bdfSopenharmony_cithat unless there is evidence of it happening. 167f08c3bdfSopenharmony_ci 168f08c3bdfSopenharmony_ciAs mentioned in the code itself, you should specify what you are testing and 169f08c3bdfSopenharmony_cithe expected outcome, even if it is relatively simple. If your program flow is 170f08c3bdfSopenharmony_cinecessarily complex and difficult to understand (which is often the case when 171f08c3bdfSopenharmony_citrying to manipulate the kernel into doing something bad), then a detailed 172f08c3bdfSopenharmony_ciexplanation of how the code works is welcome. 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ciWhat you should not do, is use inline comments or include the same level of 175f08c3bdfSopenharmony_ciexplanation which is written here. As a general rule, if something is easy to 176f08c3bdfSopenharmony_cidocument, then the code should also be easy to read. So don't document the easy 177f08c3bdfSopenharmony_cistuff (except for the basic test specification). 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ciBefore continuing we should compile this and check that the basics work. In 180f08c3bdfSopenharmony_ciorder to compile the test we need a +Makefile+ in the same subdirectory. If 181f08c3bdfSopenharmony_cione already exists, then nothing needs to be done, otherwise add one with the 182f08c3bdfSopenharmony_cifollowing contents. 183f08c3bdfSopenharmony_ci 184f08c3bdfSopenharmony_ci[source,make] 185f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 186f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later 187f08c3bdfSopenharmony_ci# Copyright (c) 2019 Linux Test Project 188f08c3bdfSopenharmony_ci 189f08c3bdfSopenharmony_citop_srcdir ?= ../../../.. 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ciinclude $(top_srcdir)/include/mk/testcases.mk 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ciinclude $(top_srcdir)/include/mk/generic_leaf_target.mk 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci------------------------------------------------------------------------------ 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ciThis will automatically add +statx01.c+ as a build target producing a 198f08c3bdfSopenharmony_ci+statx01+ executable. Unless you have heavily deviated from the tutorial, and 199f08c3bdfSopenharmony_ciprobably need to change +top_srcdir+, nothing else needs to be done. 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ciNormally, if you were starting a Makefile from scratch, then you would need to 202f08c3bdfSopenharmony_ciadd +statx01+ as a build target. Specifying that you would like to run some 203f08c3bdfSopenharmony_ciprogram (e.g. +gcc+ or +clang+) to transform +statx01.c+ into +statx01+. Here 204f08c3bdfSopenharmony_ciwe don't need to do that, but sometimes it is still necessary. For example, if 205f08c3bdfSopenharmony_ciwe needed to link to the POSIX threading library, then we could add the 206f08c3bdfSopenharmony_cifollowing line after +testcases.mk+. 207f08c3bdfSopenharmony_ci 208f08c3bdfSopenharmony_ci[source,make] 209f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 210f08c3bdfSopenharmony_cistatx01: CFLAGS += -pthread 211f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 212f08c3bdfSopenharmony_ci 213f08c3bdfSopenharmony_ciAssuming you are in the test's subdirectory +testcases/kernel/syscalls/statx+, 214f08c3bdfSopenharmony_cido 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci[source,shell] 217f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 218f08c3bdfSopenharmony_ci$ make 219f08c3bdfSopenharmony_ci$ ./statx01 220f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ciThis should build the test and then run it. However, even though the test is 223f08c3bdfSopenharmony_ciin the +syscalls+ directory it won't be automatically ran as part of the 224f08c3bdfSopenharmony_ci_syscalls_ test group (remember +./runltp -f syscalls+ from the +README.md+?). For 225f08c3bdfSopenharmony_cithis we need to add it to the +runtest+ file. So open +runtest/syscalls+ and add 226f08c3bdfSopenharmony_cithe lines starting with a +++. 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci[source,diff] 229f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 230f08c3bdfSopenharmony_ci statvfs01 statvfs01 231f08c3bdfSopenharmony_ci statvfs02 statvfs02 232f08c3bdfSopenharmony_ci 233f08c3bdfSopenharmony_ci+statx01 statx01 234f08c3bdfSopenharmony_ci+ 235f08c3bdfSopenharmony_ci stime01 stime01 236f08c3bdfSopenharmony_ci stime02 stime02 237f08c3bdfSopenharmony_ci 238f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 239f08c3bdfSopenharmony_ci 240f08c3bdfSopenharmony_ciThe +runtest+ files are in a two column format. The first column is the test 241f08c3bdfSopenharmony_ciname, which is mainly used by test runners for reporting and filtering. It is 242f08c3bdfSopenharmony_cijust a single string of text with no spaces. The second column, which can 243f08c3bdfSopenharmony_cicontain spaces, is passed to the shell in order to execute the test. Often it 244f08c3bdfSopenharmony_ciis just the executable name, but some tests also take arguments (the LTP has a 245f08c3bdfSopenharmony_cilibrary for argument parsing, by the way). 246f08c3bdfSopenharmony_ci 247f08c3bdfSopenharmony_ciIf you haven't done so already, we should add all these new files to Git. It 248f08c3bdfSopenharmony_ciis vitally important that you do not make changes to the master branch. If you 249f08c3bdfSopenharmony_cido then pulling changes from upstream becomes a major issue. So first of all 250f08c3bdfSopenharmony_cicreate a new branch. 251f08c3bdfSopenharmony_ci 252f08c3bdfSopenharmony_ci[source,shell] 253f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 254f08c3bdfSopenharmony_ci$ git checkout -b statx01 master 255f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 256f08c3bdfSopenharmony_ci 257f08c3bdfSopenharmony_ciNow we want to add the files we have created or modified, but before doing a 258f08c3bdfSopenharmony_cicommit make sure you have configured Git correctly. You need to at least set 259f08c3bdfSopenharmony_ciyour Name and e-mail address in +~/.gitconfig+, but there are some other 260f08c3bdfSopenharmony_cisettings which come in handy too. My relatively simple configuration is similar to 261f08c3bdfSopenharmony_cithe below 262f08c3bdfSopenharmony_ci 263f08c3bdfSopenharmony_ci[source,conf] 264f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 265f08c3bdfSopenharmony_ci[user] 266f08c3bdfSopenharmony_ci name = Sarah Jane 267f08c3bdfSopenharmony_ci email = sjane@e-mail.address 268f08c3bdfSopenharmony_ci[core] 269f08c3bdfSopenharmony_ci editor = emacs 270f08c3bdfSopenharmony_ci[sendemail] 271f08c3bdfSopenharmony_ci smtpServer = smtp.server.address 272f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 273f08c3bdfSopenharmony_ci 274f08c3bdfSopenharmony_ciObviously you need to at least change your name and e-mail. The SMTP server is 275f08c3bdfSopenharmony_ciuseful for +git send-email+, which we will discuss later. The editor value is 276f08c3bdfSopenharmony_ciused for things like writing commits (without the +-m+ option). 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci[source,shell] 279f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 280f08c3bdfSopenharmony_ci$ git add -v :/testcases/kernel/syscalls/statx :/runtest/syscalls 281f08c3bdfSopenharmony_ci$ git commit -m "statx01: Add new test for statx syscall" 282f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ciThis should add all the new files in the +statx+ directory and the +runtest+ 285f08c3bdfSopenharmony_cifile. It is good practice to commit early and often. Later on we will do a 286f08c3bdfSopenharmony_ciGit-rebase, which allows us to clean up the commit history. So don't worry 287f08c3bdfSopenharmony_ciabout how presentable your commit log is for now. Also don't hesitate to 288f08c3bdfSopenharmony_cicreate a new branch when doing the exercises or experimenting. This will allow 289f08c3bdfSopenharmony_ciyou to diverge from the tutorial and then easily come back again. 290f08c3bdfSopenharmony_ci 291f08c3bdfSopenharmony_ciI can't emphasize enough that Git makes things easy through branching and that 292f08c3bdfSopenharmony_cithings quickly get complicated if you don't do it. However if you do get into 293f08c3bdfSopenharmony_cia mess, Git-reflog and Git-reset, will usually get you out of it. If you also 294f08c3bdfSopenharmony_cimess that up then it may be possible to cherry pick 'dangling' commits out of 295f08c3bdfSopenharmony_cithe database into a branch. 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_ci3.1 Report TCONF instead of TPASS 298f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 299f08c3bdfSopenharmony_ci 300f08c3bdfSopenharmony_ciMaybe the test should report "TCONF: Not implemented" instead or perhaps 301f08c3bdfSopenharmony_ci+TBROK+. Try changing it do so (see +doc/test-writing-guidelines.txt+ or 302f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[the 303f08c3bdfSopenharmony_ciWiki]). 304f08c3bdfSopenharmony_ci 305f08c3bdfSopenharmony_ci3.2 Check Git ignores the executable 306f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_ciIs your +.gitignore+ correct? 309f08c3bdfSopenharmony_ci 310f08c3bdfSopenharmony_ci3.3 Run make check 311f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~ 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ciCheck coding style with `make check` 314f08c3bdfSopenharmony_ci (more in https://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#21-c-coding-style[C coding style]) 315f08c3bdfSopenharmony_ci 316f08c3bdfSopenharmony_ci3.4 Install the LTP and run the test with runtest 317f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318f08c3bdfSopenharmony_ci 319f08c3bdfSopenharmony_ciRun +statx01+ on its own; similar to the +madvise+ tests in the +README.md+. 320f08c3bdfSopenharmony_ci 321f08c3bdfSopenharmony_ci4. Call the system call 322f08c3bdfSopenharmony_ci----------------------- 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ciAt the time of writing +statx+ has no +glibc+ wrapper. It is also fairly common 325f08c3bdfSopenharmony_cifor a distribution's C library version to be older than its kernel or it may use a 326f08c3bdfSopenharmony_cicut down C library in comparison to the GNU one. So we must call +statx()+ 327f08c3bdfSopenharmony_ciusing the general +syscall()+ interface. 328f08c3bdfSopenharmony_ci 329f08c3bdfSopenharmony_ciThe LTP contains a library for dealing with the +syscall+ interface, which is 330f08c3bdfSopenharmony_cilocated in +include/lapi+. System call numbers are listed against the relevant 331f08c3bdfSopenharmony_cicall in the +*.in+ files (e.g. +x86_64.in+) which are used to generate 332f08c3bdfSopenharmony_ci+syscalls.h+, which is the header you should include. On rare occasions you 333f08c3bdfSopenharmony_cimay find the system call number is missing from the +*.in+ files and will need 334f08c3bdfSopenharmony_cito add it (see +include/lapi/syscalls/strip_syscall.awk+). 335f08c3bdfSopenharmony_ci 336f08c3bdfSopenharmony_ciSystem call numbers vary between architectures, hence there are multiple 337f08c3bdfSopenharmony_ci+*.in+ files for each architecture. You can find the various values for the 338f08c3bdfSopenharmony_ci+statx+ system call across a number of +unistd.h+ files in the Linux kernel. 339f08c3bdfSopenharmony_ci 340f08c3bdfSopenharmony_ciNote that we don't use the system-call-identifier value available in 341f08c3bdfSopenharmony_ci+/usr/include/linux/uinstd.h+ because the kernel might be much newer than the 342f08c3bdfSopenharmony_ciuser land development packages. 343f08c3bdfSopenharmony_ci 344f08c3bdfSopenharmony_ciFor +statx+ we had to add +statx 332+ to +include/lapi/syscalls/x86_64.in+, 345f08c3bdfSopenharmony_ci+statx 383+ to +include/lapi/syscalls/powerpc.in+, etc. Now lets look at 346f08c3bdfSopenharmony_cithe code, which I will explain in more detail further down. 347f08c3bdfSopenharmony_ci 348f08c3bdfSopenharmony_ci[source,c] 349f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 350f08c3bdfSopenharmony_ci/* 351f08c3bdfSopenharmony_ci * Test statx 352f08c3bdfSopenharmony_ci * 353f08c3bdfSopenharmony_ci * Check if statx exists and what error code it returns when we give it dodgy 354f08c3bdfSopenharmony_ci * data. 355f08c3bdfSopenharmony_ci */ 356f08c3bdfSopenharmony_ci 357f08c3bdfSopenharmony_ci#include <stdint.h> 358f08c3bdfSopenharmony_ci#include "tst_test.h" 359f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 360f08c3bdfSopenharmony_ci 361f08c3bdfSopenharmony_cistruct statx_timestamp { 362f08c3bdfSopenharmony_ci int64_t tv_sec; 363f08c3bdfSopenharmony_ci uint32_t tv_nsec; 364f08c3bdfSopenharmony_ci int32_t __reserved; 365f08c3bdfSopenharmony_ci}; 366f08c3bdfSopenharmony_ci 367f08c3bdfSopenharmony_cistruct statx { 368f08c3bdfSopenharmony_ci uint32_t stx_mask; 369f08c3bdfSopenharmony_ci uint32_t stx_blksize; 370f08c3bdfSopenharmony_ci uint64_t stx_attributes; 371f08c3bdfSopenharmony_ci uint32_t stx_nlink; 372f08c3bdfSopenharmony_ci uint32_t stx_uid; 373f08c3bdfSopenharmony_ci uint32_t stx_gid; 374f08c3bdfSopenharmony_ci uint16_t stx_mode; 375f08c3bdfSopenharmony_ci uint16_t __spare0[1]; 376f08c3bdfSopenharmony_ci uint64_t stx_ino; 377f08c3bdfSopenharmony_ci uint64_t stx_size; 378f08c3bdfSopenharmony_ci uint64_t stx_blocks; 379f08c3bdfSopenharmony_ci uint64_t stx_attributes_mask; 380f08c3bdfSopenharmony_ci struct statx_timestamp stx_atime; 381f08c3bdfSopenharmony_ci struct statx_timestamp stx_btime; 382f08c3bdfSopenharmony_ci struct statx_timestamp stx_ctime; 383f08c3bdfSopenharmony_ci struct statx_timestamp stx_mtime; 384f08c3bdfSopenharmony_ci uint32_t stx_rdev_major; 385f08c3bdfSopenharmony_ci uint32_t stx_rdev_minor; 386f08c3bdfSopenharmony_ci uint32_t stx_dev_major; 387f08c3bdfSopenharmony_ci uint32_t stx_dev_minor; 388f08c3bdfSopenharmony_ci uint64_t __spare2[14]; 389f08c3bdfSopenharmony_ci}; 390f08c3bdfSopenharmony_ci 391f08c3bdfSopenharmony_cistatic int sys_statx(int dirfd, const char *pathname, int flags, 392f08c3bdfSopenharmony_ci unsigned int mask, struct statx *statxbuf) 393f08c3bdfSopenharmony_ci{ 394f08c3bdfSopenharmony_ci return tst_syscall(__NR_statx, dirfd, pathname, flags, mask, statxbuf); 395f08c3bdfSopenharmony_ci} 396f08c3bdfSopenharmony_ci 397f08c3bdfSopenharmony_ci... 398f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 399f08c3bdfSopenharmony_ci 400f08c3bdfSopenharmony_ciSo the top part of the code is now boiler plate for calling +statx+. It is 401f08c3bdfSopenharmony_cicommon for the kernel to be newer than the user land libraries and headers. So 402f08c3bdfSopenharmony_cifor new system calls like +statx+, we copy, with a few modifications, the 403f08c3bdfSopenharmony_cirelevant definitions into the LTP. This is somewhat like 'vendoring', although 404f08c3bdfSopenharmony_ciwe are usually just copying headers required for interacting with the Kernel's 405f08c3bdfSopenharmony_ciABI (Application Binary Interface), rather than internalising actual 406f08c3bdfSopenharmony_cifunctionality. 407f08c3bdfSopenharmony_ci 408f08c3bdfSopenharmony_ciSo from the top we include the +stdint.h+ library which gives us the standard 409f08c3bdfSopenharmony_ci+(u)int*_t+ type definitions. We use these in place of the Kernel type 410f08c3bdfSopenharmony_cidefinitions such as +__u64+ in +linux/types.h+. We then have a couple of 411f08c3bdfSopenharmony_cistructure definitions which form part of the +statx+ API. These were copied 412f08c3bdfSopenharmony_cifrom +include/uapi/linux/stat.h+ in the Kernel tree. 413f08c3bdfSopenharmony_ci 414f08c3bdfSopenharmony_ciAfter that, there is a wrapper function, which saves us from writing 415f08c3bdfSopenharmony_ci+tst_syscall(__NR_statx, ...+, every time we want to make a call to 416f08c3bdfSopenharmony_ci+statx+. This also provides a stub for when +statx+ is eventually integrated 417f08c3bdfSopenharmony_ciinto the LTP library and also implemented by the C library. At that point we 418f08c3bdfSopenharmony_cican switch to using the C library implementation if available or fallback to 419f08c3bdfSopenharmony_ciour own. 420f08c3bdfSopenharmony_ci 421f08c3bdfSopenharmony_ciThe advantage of using the C library implementation is that it will often be 422f08c3bdfSopenharmony_cibetter supported across multiple architectures. It will also mean we are using 423f08c3bdfSopenharmony_cithe system call in the same way most real programs would. Sometimes there are 424f08c3bdfSopenharmony_ciadvantages to bypassing the C library, but in general it should not be our 425f08c3bdfSopenharmony_cifirst choice. 426f08c3bdfSopenharmony_ci 427f08c3bdfSopenharmony_ciThe final test should do a check during configuration (i.e. when we run 428f08c3bdfSopenharmony_ci+./configure+ before building) which checks if the +statx+ system call and 429f08c3bdfSopenharmony_ciassociated structures exists. This requires writing an +m4+ file for use with 430f08c3bdfSopenharmony_ci+configure.ac+ which is processed during +make autotools+ and produces the 431f08c3bdfSopenharmony_ciconfigure script. 432f08c3bdfSopenharmony_ci 433f08c3bdfSopenharmony_ciFor the time being though we shall just ignore this. All you need to know for 434f08c3bdfSopenharmony_cinow is that this is a problem which eventually needs to be dealt with and that 435f08c3bdfSopenharmony_cithere is a system in place to handle it. 436f08c3bdfSopenharmony_ci 437f08c3bdfSopenharmony_ci[source,c] 438f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 439f08c3bdfSopenharmony_ci... 440f08c3bdfSopenharmony_ci 441f08c3bdfSopenharmony_cistatic void run(void) 442f08c3bdfSopenharmony_ci{ 443f08c3bdfSopenharmony_ci struct statx statxbuf = { 0 }; 444f08c3bdfSopenharmony_ci 445f08c3bdfSopenharmony_ci TEST(sys_statx(0, NULL, 0, 0, &statxbuf)); 446f08c3bdfSopenharmony_ci 447f08c3bdfSopenharmony_ci if (TST_RET == 0) 448f08c3bdfSopenharmony_ci tst_res(TFAIL, "statx thinks it can stat NULL"); 449f08c3bdfSopenharmony_ci else if (TST_ERR == EFAULT) 450f08c3bdfSopenharmony_ci tst_res(TPASS, "statx set errno to EFAULT as expected"); 451f08c3bdfSopenharmony_ci else 452f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx set errno to some unexpected value"); 453f08c3bdfSopenharmony_ci} 454f08c3bdfSopenharmony_ci 455f08c3bdfSopenharmony_cistatic struct tst_test test = { 456f08c3bdfSopenharmony_ci .test_all = run, 457f08c3bdfSopenharmony_ci .min_kver = "4.11", 458f08c3bdfSopenharmony_ci}; 459f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 460f08c3bdfSopenharmony_ci 461f08c3bdfSopenharmony_ciThe +TEST+ macro sets +TST_RET+ to the return value of +tst_statx()+ and 462f08c3bdfSopenharmony_ci+TST_ERR+ to the value of +errno+ immediately after the functions 463f08c3bdfSopenharmony_cireturn. This is mainly just for convenience, although it potentially could 464f08c3bdfSopenharmony_cihave other uses. 465f08c3bdfSopenharmony_ci 466f08c3bdfSopenharmony_ciWe check whether the return value indicates success and if it doesn't also 467f08c3bdfSopenharmony_cicheck the value of +errno+. The last call to +tst_res+ includes +TERRNO+, 468f08c3bdfSopenharmony_ciwhich will print the current error number and associated description in 469f08c3bdfSopenharmony_ciaddition to the message we have provided. Note that it uses the current value 470f08c3bdfSopenharmony_ciof +errno+ not +TST_ERR+. 471f08c3bdfSopenharmony_ci 472f08c3bdfSopenharmony_ciWhat we should have done in the example above is use +TTERRNO+ which takes the 473f08c3bdfSopenharmony_civalue of +TST_ERR+. 474f08c3bdfSopenharmony_ci 475f08c3bdfSopenharmony_ciIf we try to run the test on a kernel where +statx+ does not exist, then 476f08c3bdfSopenharmony_ci+tst_syscall+ will cause it to fail gracefully with +TCONF+. Where +TCONF+ 477f08c3bdfSopenharmony_ciindicates the test is not applicable to our configuration. 478f08c3bdfSopenharmony_ci 479f08c3bdfSopenharmony_ciThe function +tst_syscall+ calls +tst_brk(TCONF,...)+ on failure. +tst_brk+ 480f08c3bdfSopenharmony_cicauses the test to exit immediately, which prevents any further test code from 481f08c3bdfSopenharmony_cibeing run. 482f08c3bdfSopenharmony_ci 483f08c3bdfSopenharmony_ci4.1 What are the differences between tst_brk and tst_res? 484f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 485f08c3bdfSopenharmony_ci 486f08c3bdfSopenharmony_ciSee +include/tst_test.h+ and the 487f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[test 488f08c3bdfSopenharmony_ciwriting guide]. Also what do they have in common? 489f08c3bdfSopenharmony_ci 490f08c3bdfSopenharmony_ci4.2 What happens if you call tst_res(TINFO, ...) after sys_statx? 491f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492f08c3bdfSopenharmony_ci 493f08c3bdfSopenharmony_ciDoes the test still function correctly? 494f08c3bdfSopenharmony_ci 495f08c3bdfSopenharmony_ci4.3 Extend the test to handle other basic error conditions. 496f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497f08c3bdfSopenharmony_ci 498f08c3bdfSopenharmony_ciFor example, see if you can trigger +ENOENT+ instead. You shouldn't 499f08c3bdfSopenharmony_cihave to create any files, which is discussed in the next section. 500f08c3bdfSopenharmony_ci 501f08c3bdfSopenharmony_ci5. Setup, Cleanup and files 502f08c3bdfSopenharmony_ci--------------------------- 503f08c3bdfSopenharmony_ci 504f08c3bdfSopenharmony_ciSome tests require resources to be allocated, or system settings to be 505f08c3bdfSopenharmony_cichanged, before the test begins. This 'setup' only has to be done once at the 506f08c3bdfSopenharmony_cibeginning and at the end of the test needs to be removed or reverted. The 507f08c3bdfSopenharmony_ci'cleanup' also has to be done regardless of whether the test breaks. 508f08c3bdfSopenharmony_ci 509f08c3bdfSopenharmony_ciFortunately, like most test libraries, we have setup and cleanup (teardown) 510f08c3bdfSopenharmony_cicallbacks. +setup+ is called once before +run+ and +cleanup+ is called once 511f08c3bdfSopenharmony_ciafterwards. Note that +run+ itself can be called multiple times by the test 512f08c3bdfSopenharmony_ciharness, but that +setup+ and +cleanup+ are only called once. 513f08c3bdfSopenharmony_ci 514f08c3bdfSopenharmony_ciIf either your code, a +SAFE_*+ macro or a library function such as 515f08c3bdfSopenharmony_ci+tst_syscall+ call +tst_brk+, then +run+ will exit immediately and the 516f08c3bdfSopenharmony_ci+cleanup+ function is then called. Once 'cleanup' is completed, the test 517f08c3bdfSopenharmony_ciexecutable will then exit altogether abandoning any remaining iterations of 518f08c3bdfSopenharmony_ci+run+. 519f08c3bdfSopenharmony_ci 520f08c3bdfSopenharmony_ciFor +statx+ we would like to create some files or file like objects which we 521f08c3bdfSopenharmony_cihave control over. Deciding where to create the files is easy, we just create 522f08c3bdfSopenharmony_ciit in the current working directory and let the LTP test harness handle where 523f08c3bdfSopenharmony_cithat should be by setting +.needs_tmpdir = 1+. 524f08c3bdfSopenharmony_ci 525f08c3bdfSopenharmony_ci[source,c] 526f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 527f08c3bdfSopenharmony_ci/* 528f08c3bdfSopenharmony_ci * Test statx 529f08c3bdfSopenharmony_ci * 530f08c3bdfSopenharmony_ci * Check if statx exists and what error code it returns when we give it dodgy 531f08c3bdfSopenharmony_ci * data. Then stat a file and check it returns success. 532f08c3bdfSopenharmony_ci */ 533f08c3bdfSopenharmony_ci 534f08c3bdfSopenharmony_ci#include <stdint.h> 535f08c3bdfSopenharmony_ci#include "tst_test.h" 536f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 537f08c3bdfSopenharmony_ci#include "lapi/fcntl.h" 538f08c3bdfSopenharmony_ci 539f08c3bdfSopenharmony_ci#define FNAME "file_to_stat" 540f08c3bdfSopenharmony_ci#define STATX_BASIC_STATS 0x000007ffU 541f08c3bdfSopenharmony_ci 542f08c3bdfSopenharmony_ci/*************** statx structure and wrapper goes here ! ***************/ 543f08c3bdfSopenharmony_ci 544f08c3bdfSopenharmony_ci... 545f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 546f08c3bdfSopenharmony_ci 547f08c3bdfSopenharmony_ciWe have added an extra include +lapi/fcntl.h+ which wraps the system header by 548f08c3bdfSopenharmony_cithe same name (+#include <fcntl.h>+). This header ensures we have definitions 549f08c3bdfSopenharmony_cifor recently added macros such as +AT_FDCWD+ by providing fall backs if the 550f08c3bdfSopenharmony_cisystem header does not have them. The +lapi+ directory contains a number of 551f08c3bdfSopenharmony_ciheaders like this. 552f08c3bdfSopenharmony_ci 553f08c3bdfSopenharmony_ciAt some point we may wish to add +lapi/stat.h+ to provide a fall back for 554f08c3bdfSopenharmony_cimacros such as +STATX_BASIC_STATS+. However for the time being we have just 555f08c3bdfSopenharmony_cidefined it in the test. 556f08c3bdfSopenharmony_ci 557f08c3bdfSopenharmony_ci[source,c] 558f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 559f08c3bdfSopenharmony_ci... 560f08c3bdfSopenharmony_ci 561f08c3bdfSopenharmony_cistatic void setup(void) 562f08c3bdfSopenharmony_ci{ 563f08c3bdfSopenharmony_ci SAFE_TOUCH(FNAME, 0777, NULL); 564f08c3bdfSopenharmony_ci} 565f08c3bdfSopenharmony_ci 566f08c3bdfSopenharmony_cistatic void run(void) 567f08c3bdfSopenharmony_ci{ 568f08c3bdfSopenharmony_ci struct statx statxbuf = { 0 }; 569f08c3bdfSopenharmony_ci 570f08c3bdfSopenharmony_ci TEST(sys_statx(0, NULL, 0, 0, &statxbuf)); 571f08c3bdfSopenharmony_ci if (TST_RET == 0) 572f08c3bdfSopenharmony_ci tst_res(TFAIL, "statx thinks it can stat NULL"); 573f08c3bdfSopenharmony_ci else if (TST_ERR == EFAULT) 574f08c3bdfSopenharmony_ci tst_res(TPASS, "statx set errno to EFAULT as expected"); 575f08c3bdfSopenharmony_ci else 576f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx set errno to some unexpected value"); 577f08c3bdfSopenharmony_ci 578f08c3bdfSopenharmony_ci TEST(sys_statx(AT_FDCWD, FNAME, 0, STATX_BASIC_STATS, &statxbuf)); 579f08c3bdfSopenharmony_ci if (TST_RET == 0) 580f08c3bdfSopenharmony_ci tst_res(TPASS, "It returned zero so it must have worked!"); 581f08c3bdfSopenharmony_ci else 582f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx can not stat a basic file"); 583f08c3bdfSopenharmony_ci} 584f08c3bdfSopenharmony_ci 585f08c3bdfSopenharmony_cistatic struct tst_test test = { 586f08c3bdfSopenharmony_ci .setup = setup, 587f08c3bdfSopenharmony_ci .test_all = run, 588f08c3bdfSopenharmony_ci .min_kver = "4.11", 589f08c3bdfSopenharmony_ci .needs_tmpdir = 1 590f08c3bdfSopenharmony_ci}; 591f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 592f08c3bdfSopenharmony_ci 593f08c3bdfSopenharmony_ciThe +setup+ callback uses one of the LTP's +SAFE+ functions to create an empty 594f08c3bdfSopenharmony_cifile +file_to_stat+. Because we have set +.needs_tmpdir+, we can just create 595f08c3bdfSopenharmony_cithis file in the present working directory. We don't need to create a 596f08c3bdfSopenharmony_ci+cleanup+ callback yet because the LTP test harness will recursively delete 597f08c3bdfSopenharmony_cithe temporary directory and its contents. 598f08c3bdfSopenharmony_ci 599f08c3bdfSopenharmony_ciThe +run+ function can be called multiple times by the test harness, however 600f08c3bdfSopenharmony_ci+setup+ and +cleanup+ callbacks will only be ran once. 601f08c3bdfSopenharmony_ci 602f08c3bdfSopenharmony_ci[WARNING] 603f08c3bdfSopenharmony_ciBy this point you may have begun to explore the LTP library headers or older 604f08c3bdfSopenharmony_citests. In which case you will have come across functions from the old API such 605f08c3bdfSopenharmony_cias +tst_brkm+. The old API is being phased out, so you should not use these 606f08c3bdfSopenharmony_cifunctions. 607f08c3bdfSopenharmony_ci 608f08c3bdfSopenharmony_ciSo far we haven't had to do any clean up. So our example doesn't answer the 609f08c3bdfSopenharmony_ciquestion "what happens if part of the clean up fails?". To answer this we are 610f08c3bdfSopenharmony_cigoing to modify the test to ask the (highly contrived) question "What happens 611f08c3bdfSopenharmony_ciif I create and open a file, then create a hard-link to it, then call open 612f08c3bdfSopenharmony_ciagain on the hard-link, then 'stat' the file". 613f08c3bdfSopenharmony_ci 614f08c3bdfSopenharmony_ci[source,c] 615f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 616f08c3bdfSopenharmony_ci#define LNAME "file_to_stat_link" 617f08c3bdfSopenharmony_ci 618f08c3bdfSopenharmony_ci... 619f08c3bdfSopenharmony_ci 620f08c3bdfSopenharmony_cistatic void setup(void) 621f08c3bdfSopenharmony_ci{ 622f08c3bdfSopenharmony_ci fd = SAFE_OPEN(FNAME, O_CREAT, 0777); 623f08c3bdfSopenharmony_ci SAFE_LINK(FNAME, LNAME); 624f08c3bdfSopenharmony_ci lfd = SAFE_OPEN(LNAME, 0); 625f08c3bdfSopenharmony_ci} 626f08c3bdfSopenharmony_ci 627f08c3bdfSopenharmony_cistatic void cleanup(void) 628f08c3bdfSopenharmony_ci{ 629f08c3bdfSopenharmony_ci if (lfd != 0) 630f08c3bdfSopenharmony_ci SAFE_CLOSE(lfd); 631f08c3bdfSopenharmony_ci 632f08c3bdfSopenharmony_ci if (fd != 0) 633f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 634f08c3bdfSopenharmony_ci} 635f08c3bdfSopenharmony_ci 636f08c3bdfSopenharmony_cistatic void run(void) 637f08c3bdfSopenharmony_ci{ 638f08c3bdfSopenharmony_ci ... 639f08c3bdfSopenharmony_ci 640f08c3bdfSopenharmony_ci TEST(sys_statx(AT_FDCWD, LNAME, 0, STATX_BASIC_STATS, &statxbuf)); 641f08c3bdfSopenharmony_ci if (TST_RET == 0) 642f08c3bdfSopenharmony_ci tst_res(TPASS, "It returned zero so it must have worked!"); 643f08c3bdfSopenharmony_ci else 644f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx can not stat a basic file"); 645f08c3bdfSopenharmony_ci} 646f08c3bdfSopenharmony_ci 647f08c3bdfSopenharmony_cistatic struct tst_test test = { 648f08c3bdfSopenharmony_ci .setup = setup, 649f08c3bdfSopenharmony_ci .cleanup = cleanup, 650f08c3bdfSopenharmony_ci .test_all = run, 651f08c3bdfSopenharmony_ci .tcnt = 2, 652f08c3bdfSopenharmony_ci .min_kver = "4.11", 653f08c3bdfSopenharmony_ci .needs_tmpdir = 1 654f08c3bdfSopenharmony_ci}; 655f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 656f08c3bdfSopenharmony_ci 657f08c3bdfSopenharmony_ciBecause we are now opening a file, we need a +cleanup+ function to close the 658f08c3bdfSopenharmony_cifile descriptors. We have to manually close the files to ensure the temporary 659f08c3bdfSopenharmony_cidirectory is deleted by the test harness (see the 660f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines[test 661f08c3bdfSopenharmony_ciwriting guidelines] for details). 662f08c3bdfSopenharmony_ci 663f08c3bdfSopenharmony_ciAs a matter of good practice, the file descriptors are closed in reverse 664f08c3bdfSopenharmony_ciorder. In some circumstances the order in which clean up is performed is 665f08c3bdfSopenharmony_cisignificant. In that case resources created towards the end of 'setup' are 666f08c3bdfSopenharmony_cidependent on ones near the beginning. So during 'cleanup' we remove the 667f08c3bdfSopenharmony_cidependants before their dependencies. 668f08c3bdfSopenharmony_ci 669f08c3bdfSopenharmony_ciIf, for some reason, the file descriptor +lfd+ became invalid during the test, 670f08c3bdfSopenharmony_cibut +fd+ was still open, we do not want +SAFE_CLOSE(lfd)+ to cause the 671f08c3bdfSopenharmony_ci+cleanup+ function to exit prematurely. If it did, then +fd+ would remain open 672f08c3bdfSopenharmony_ciwhich would cause problems on some file systems. 673f08c3bdfSopenharmony_ci 674f08c3bdfSopenharmony_ciNor do we want to call +cleanup+ recursively. So during 'cleanup' +tst_brk+, 675f08c3bdfSopenharmony_ciand consequently the +SAFE+ functions, do not cause the test to exit with 676f08c3bdfSopenharmony_ci+TBROK+. Instead they just print an error message with +TWARN+. 677f08c3bdfSopenharmony_ci 678f08c3bdfSopenharmony_ciIt is not entirely necessary to check if the file descriptors have a none zero 679f08c3bdfSopenharmony_civalue before attempting to close them. However it avoids a bunch of spurious 680f08c3bdfSopenharmony_ciwarning messages if we fail to open +file_to_stat+. Test case failures can be 681f08c3bdfSopenharmony_cidifficult to interpret at the best of times, so avoid filling the log with 682f08c3bdfSopenharmony_cinoise. 683f08c3bdfSopenharmony_ci 684f08c3bdfSopenharmony_ci5.1 Check statx returns the correct number of hard links 685f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 686f08c3bdfSopenharmony_ci 687f08c3bdfSopenharmony_ciThe field +statx.stx_nlink+ should be equal to 2, right? 688f08c3bdfSopenharmony_ci 689f08c3bdfSopenharmony_ci5.2 Git-branch 690f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~ 691f08c3bdfSopenharmony_ci 692f08c3bdfSopenharmony_ciWe are about to make some organisational changes to the test, so now would be 693f08c3bdfSopenharmony_cia good time to branch. Then we can switch between the old and new versions, to 694f08c3bdfSopenharmony_cicheck the behavior has not been changed by accident. 695f08c3bdfSopenharmony_ci 696f08c3bdfSopenharmony_ci6. Split the test 697f08c3bdfSopenharmony_ci----------------- 698f08c3bdfSopenharmony_ci 699f08c3bdfSopenharmony_ciIn our current test, we have essentially rolled two different test cases into 700f08c3bdfSopenharmony_cione. Firstly we check if an error is returned when bad arguments are provided 701f08c3bdfSopenharmony_ciand secondly we check what happens when we stat an actual file. Quite often it 702f08c3bdfSopenharmony_cimakes sense to call +tst_res+ multiple times in a single test case because we 703f08c3bdfSopenharmony_ciare checking different properties of the same result, but here we are clearly 704f08c3bdfSopenharmony_citesting two different scenarios. 705f08c3bdfSopenharmony_ci 706f08c3bdfSopenharmony_ciSo we should split the test in two. One obvious way to do this is to create 707f08c3bdfSopenharmony_ci+statx02.c+, but that seems like overkill in order to separate two simple test 708f08c3bdfSopenharmony_cicases. So, for now at least, we are going to do it a different way. 709f08c3bdfSopenharmony_ci 710f08c3bdfSopenharmony_ci[source,c] 711f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 712f08c3bdfSopenharmony_ci... 713f08c3bdfSopenharmony_ci 714f08c3bdfSopenharmony_cistatic void run_stat_null(void) 715f08c3bdfSopenharmony_ci{ 716f08c3bdfSopenharmony_ci struct statx statxbuf = { 0 }; 717f08c3bdfSopenharmony_ci 718f08c3bdfSopenharmony_ci TEST(sys_statx(0, NULL, 0, 0, &statxbuf)); 719f08c3bdfSopenharmony_ci if (TST_RET == 0) 720f08c3bdfSopenharmony_ci tst_res(TFAIL, "statx thinks it can stat NULL"); 721f08c3bdfSopenharmony_ci else if (TST_ERR == EFAULT) 722f08c3bdfSopenharmony_ci tst_res(TPASS, "statx set errno to EFAULT as expected"); 723f08c3bdfSopenharmony_ci else 724f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx set errno to some unexpected value"); 725f08c3bdfSopenharmony_ci} 726f08c3bdfSopenharmony_ci 727f08c3bdfSopenharmony_cistatic void run_stat_symlink(void) 728f08c3bdfSopenharmony_ci{ 729f08c3bdfSopenharmony_ci struct statx statxbuf = { 0 }; 730f08c3bdfSopenharmony_ci 731f08c3bdfSopenharmony_ci TEST(sys_statx(AT_FDCWD, LNAME, 0, STATX_BASIC_STATS, &statxbuf)); 732f08c3bdfSopenharmony_ci if (TST_RET == 0) 733f08c3bdfSopenharmony_ci tst_res(TPASS, "It returned zero so it must have worked!"); 734f08c3bdfSopenharmony_ci else 735f08c3bdfSopenharmony_ci tst_res(TFAIL | TERRNO, "statx can not stat a basic file"); 736f08c3bdfSopenharmony_ci} 737f08c3bdfSopenharmony_ci 738f08c3bdfSopenharmony_cistatic void run(unsigned int i) 739f08c3bdfSopenharmony_ci{ 740f08c3bdfSopenharmony_ci switch(i) { 741f08c3bdfSopenharmony_ci case 0: run_stat_null(); 742f08c3bdfSopenharmony_ci case 1: run_stat_symlink(); 743f08c3bdfSopenharmony_ci } 744f08c3bdfSopenharmony_ci} 745f08c3bdfSopenharmony_ci 746f08c3bdfSopenharmony_cistatic struct tst_test test = { 747f08c3bdfSopenharmony_ci .setup = setup, 748f08c3bdfSopenharmony_ci .cleanup = cleanup, 749f08c3bdfSopenharmony_ci .test = run, 750f08c3bdfSopenharmony_ci .tcnt = 2, 751f08c3bdfSopenharmony_ci .min_kver = "4.11", 752f08c3bdfSopenharmony_ci .needs_tmpdir = 1 753f08c3bdfSopenharmony_ci}; 754f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 755f08c3bdfSopenharmony_ci 756f08c3bdfSopenharmony_ciSo we have used an alternative form of the +test+ or +run+ callback which 757f08c3bdfSopenharmony_ciaccepts an index. Some tests use this index with an array of parameters and 758f08c3bdfSopenharmony_ciexpected return values. Others do something similar to the above. The index 759f08c3bdfSopenharmony_cican be used how you want so long as each iteration calls +tst_res+ in a 760f08c3bdfSopenharmony_cimeaningful way. 761f08c3bdfSopenharmony_ci 762f08c3bdfSopenharmony_ciIf an iteration fails to return a result (i.e. call +tst_res+ with a value 763f08c3bdfSopenharmony_ciother than +TINFO+) then the test harness will report +TBROK+ and print the 764f08c3bdfSopenharmony_ciiteration which failed. This prevents a scenario in your test from silently 765f08c3bdfSopenharmony_cifailing due to some faulty logic. 766f08c3bdfSopenharmony_ci 767f08c3bdfSopenharmony_ci6.1 What is wrong with the switch statement? 768f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 769f08c3bdfSopenharmony_ci 770f08c3bdfSopenharmony_ciWere you paying attention? Also see the output of +make check+. 771f08c3bdfSopenharmony_ci 772f08c3bdfSopenharmony_ci6.2 Test a feature unique to statx 773f08c3bdfSopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774f08c3bdfSopenharmony_ci 775f08c3bdfSopenharmony_ciSo far we have not tested anything which is unique to +statx+. So, for 776f08c3bdfSopenharmony_ciexample, you could check stx_btime is correct (possibly only to within a 777f08c3bdfSopenharmony_cimargin of error) and that it differs from +stx_mtime+ after writing to the 778f08c3bdfSopenharmony_cifile. 779f08c3bdfSopenharmony_ci 780f08c3bdfSopenharmony_ciAlternatively you could check that +stx_dev_major+ and +stx_dev_minor+ are set 781f08c3bdfSopenharmony_cicorrectly. Note that the LTP has helper functions for creating devices and 782f08c3bdfSopenharmony_cifile systems (see 783f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/Test-Writing-Guidelines#2214-testing-with-a-block-device[section 784f08c3bdfSopenharmony_ci2.2.14] of the Test Writing Guidelines). 785f08c3bdfSopenharmony_ci 786f08c3bdfSopenharmony_ciThis could be quite a challenging exercise. You may wish to tackle an 787f08c3bdfSopenharmony_cialtogether different test scenario instead. If you get stuck just move onto 788f08c3bdfSopenharmony_cithe next section and come back later. 789f08c3bdfSopenharmony_ci 790f08c3bdfSopenharmony_ci7. Submitting the test for review 791f08c3bdfSopenharmony_ci--------------------------------- 792f08c3bdfSopenharmony_ci 793f08c3bdfSopenharmony_ciIgnoring the fact we should probably create +lapi/stat.h+ along with a bunch 794f08c3bdfSopenharmony_ciof fallback logic in the build system. We can now get our test ready for 795f08c3bdfSopenharmony_cisubmission. 796f08c3bdfSopenharmony_ci 797f08c3bdfSopenharmony_ciThe first thing you need to do before considering submitting your test is run 798f08c3bdfSopenharmony_ci+make check-statx01+ or + make check+ in the test's directory. Again, we use 799f08c3bdfSopenharmony_cithe kernel style guidelines where possible. Next you should create a new 800f08c3bdfSopenharmony_cibranch, this will allow you to reshape your commit history without fear. 801f08c3bdfSopenharmony_ci 802f08c3bdfSopenharmony_ciAfter that we have the pleasure of doing an interactive 'rebase' to clean up 803f08c3bdfSopenharmony_ciour commit history. In its current form the test only really needs a single 804f08c3bdfSopenharmony_cicommit, but if you have been using Git correctly then you should have 805f08c3bdfSopenharmony_cimany. The main reason we want to compress it to a single commit, is to make 806f08c3bdfSopenharmony_cithe LTP's Git-log readable. It also allows us to write a coherent description 807f08c3bdfSopenharmony_ciof the work as a whole in retrospective. Although, when adding a new test, the 808f08c3bdfSopenharmony_citest description in the code will probably make the commit message redundant. 809f08c3bdfSopenharmony_ci 810f08c3bdfSopenharmony_ciAnyway, as an example, we shall look at my personal commit history from this 811f08c3bdfSopenharmony_citutorial and 'rebase' it. You should try following along with your own 812f08c3bdfSopenharmony_cirepository. First lets look at the commit history since we branched from 813f08c3bdfSopenharmony_cimaster. 814f08c3bdfSopenharmony_ci 815f08c3bdfSopenharmony_ci[source,shell] 816f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 817f08c3bdfSopenharmony_ci$ git log --oneline master..HEAD 818f08c3bdfSopenharmony_ci152d39fe7 (HEAD -> tutorial-rebase2, tutorial-rebase) tutorial: Start Submitting patch section 819f08c3bdfSopenharmony_ci70f7ce7ce statx01: Stop checkpatch from complaining 820f08c3bdfSopenharmony_cibb0332bd7 tutorial: Fix review problems 821f08c3bdfSopenharmony_ci6a87a084a statx01: Fix review problems 822f08c3bdfSopenharmony_cid784b1e85 test-writing-guidelines: Remove old API argument 823f08c3bdfSopenharmony_cic26e1be7a fixup! tutorial 824f08c3bdfSopenharmony_ci1e24a5fb5 (me/tutorial-rebase) fixup! tutorial 825f08c3bdfSopenharmony_ci568a3f7be fixup! tutorial 826f08c3bdfSopenharmony_ci09dd2c829 statx: stage 6 827f08c3bdfSopenharmony_cibfeef7902 statx: stage 5b 828f08c3bdfSopenharmony_ci76e03d714 statx: stage 5a 829f08c3bdfSopenharmony_ci98f5bc7ac statx: stage 4 830f08c3bdfSopenharmony_ci6f8c16438 statx: stage 3 (Add statx01) 831f08c3bdfSopenharmony_ci5d93b84d8 Add statx and other syscall numbers 832f08c3bdfSopenharmony_ci5ca627b78 tutorial: Add a step-by-step C test tutorial 833f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 834f08c3bdfSopenharmony_ci 835f08c3bdfSopenharmony_ciSo we have told git to show all the commits which don't exist in 'master', but 836f08c3bdfSopenharmony_ciare in +HEAD+, where +HEAD+ is the top of the current branch. The current 837f08c3bdfSopenharmony_cibranch is +tutorial-rebase2+ which I just created. I have already done one 838f08c3bdfSopenharmony_ci'rebase' and submitted a patch for review, so my original branch was just called 839f08c3bdfSopenharmony_ci+tutorial+. 840f08c3bdfSopenharmony_ci 841f08c3bdfSopenharmony_ciAs usual my commit history is starting to look like a bit of mess! There is 842f08c3bdfSopenharmony_cieven a commit in there which should not be in the this branch (Remove old API 843f08c3bdfSopenharmony_ciargument), however it can be ignored for now and 'cherry picked' into a new branch 844f08c3bdfSopenharmony_cilater. 845f08c3bdfSopenharmony_ci 846f08c3bdfSopenharmony_ciFor my patch I actually need at least two commits, one which contains the 847f08c3bdfSopenharmony_citutorial text and one which contains the test and associated files. So first 848f08c3bdfSopenharmony_ciof all I want to 'squash' (amalgamate) all the commits appended with 849f08c3bdfSopenharmony_ci+tutorial:+ into the bottom commit. 850f08c3bdfSopenharmony_ci 851f08c3bdfSopenharmony_ci[source,shell] 852f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 853f08c3bdfSopenharmony_ci$ git rebase -i 5ca627b78\^ 854f08c3bdfSopenharmony_ci... 855f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 856f08c3bdfSopenharmony_ci 857f08c3bdfSopenharmony_ciThis begins an interactive 'rebase' where commit 5ca6427b78 is the earliest 858f08c3bdfSopenharmony_cicommit we want to edit. The +^+ symbol after the commit hash, specifies the 859f08c3bdfSopenharmony_cicommit before this one. The interactive 'rebase' command takes the last commit 860f08c3bdfSopenharmony_ciwe want to keep unaltered as it's argument (in other words it takes a 861f08c3bdfSopenharmony_cinon-inclusive range). 862f08c3bdfSopenharmony_ci 863f08c3bdfSopenharmony_ciUpon entering a similar command you will be presented with a text file 864f08c3bdfSopenharmony_cisimilar to the following. The file should be displayed in your text editor of 865f08c3bdfSopenharmony_cichoice, if it doesn't, then you may change the editor variable in +.gitconfig+ 866f08c3bdfSopenharmony_ciwhich was shown in section 3. 867f08c3bdfSopenharmony_ci 868f08c3bdfSopenharmony_ci[source,rebase] 869f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 870f08c3bdfSopenharmony_cipick 5ca627b78 tutorial: Add a step-by-step C test tutorial 871f08c3bdfSopenharmony_cipick 5d93b84d8 Add statx and other syscall numbers 872f08c3bdfSopenharmony_cipick 6f8c16438 statx: stage 3 (Add statx01) 873f08c3bdfSopenharmony_cipick 98f5bc7ac statx: stage 4 874f08c3bdfSopenharmony_cipick 76e03d714 statx: stage 5a 875f08c3bdfSopenharmony_cipick bfeef7902 statx: stage 5b 876f08c3bdfSopenharmony_cipick 09dd2c829 statx: stage 6 877f08c3bdfSopenharmony_cipick 568a3f7be fixup! tutorial 878f08c3bdfSopenharmony_cipick 1e24a5fb5 fixup! tutorial 879f08c3bdfSopenharmony_cipick c26e1be7a fixup! tutorial 880f08c3bdfSopenharmony_cipick d784b1e85 test-writing-guidelines: Remove old API argument 881f08c3bdfSopenharmony_cipick 6a87a084a statx01: Fix review problems 882f08c3bdfSopenharmony_cipick bb0332bd7 tutorial: Fix review problems 883f08c3bdfSopenharmony_cipick 70f7ce7ce statx01: Stop checkpatch from complaining 884f08c3bdfSopenharmony_cipick 152d39fe7 tutorial: Start Submitting patch section 885f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 886f08c3bdfSopenharmony_ci 887f08c3bdfSopenharmony_ciThe last commit from Git-log is shown at the top. The left hand column 888f08c3bdfSopenharmony_cicontains the commands we want to run on each commit. +pick+ just means we 889f08c3bdfSopenharmony_cire-apply the commit as-is. We can reorder the lines to apply the commits in a 890f08c3bdfSopenharmony_cidifferent order, but we need to be careful when reordering commits to the same 891f08c3bdfSopenharmony_cifile. If your 'rebase' results in a merge conflict, then you have probably 892f08c3bdfSopenharmony_cireordered some commits which contained changes to the same piece of code. 893f08c3bdfSopenharmony_ci 894f08c3bdfSopenharmony_ciPerhaps a better name for the interactive 'rebase' command would be 'replay'. As 895f08c3bdfSopenharmony_ciwe pick a point in the commit history, undo all those commits before that 896f08c3bdfSopenharmony_cipoint, then reapply them one at a time. During the replay we can reorder the 897f08c3bdfSopenharmony_cicommits, drop, merge, split and edit them, creating a new history. 898f08c3bdfSopenharmony_ci 899f08c3bdfSopenharmony_ciThe commands I am going to use are +reword+ and +fixup+. The +reword+ command 900f08c3bdfSopenharmony_ciallows you to edit a single commit's message. The 'fixup' command 'squashes' a 901f08c3bdfSopenharmony_cicommit into the commit above/preceding it, merging the two commits into 902f08c3bdfSopenharmony_cione. The commit which has +fixup+ applied has its commit message deleted. If 903f08c3bdfSopenharmony_ciyou think a commit might have something useful in its message then you can use 904f08c3bdfSopenharmony_ci+squash+ instead. 905f08c3bdfSopenharmony_ci 906f08c3bdfSopenharmony_ci[source,rebase] 907f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 908f08c3bdfSopenharmony_cireword 5ca627b78 tutorial: Add a step-by-step C test tutorial 909f08c3bdfSopenharmony_cifixup 568a3f7be fixup! tutorial 910f08c3bdfSopenharmony_cifixup 1e24a5fb5 fixup! tutorial 911f08c3bdfSopenharmony_cifixup c26e1be7a fixup! tutorial 912f08c3bdfSopenharmony_cifixup bb0332bd7 tutorial: Fix review problems 913f08c3bdfSopenharmony_cifixup 152d39fe7 tutorial: Start Submitting patch section 914f08c3bdfSopenharmony_cifixup 276edecab tutorial: Save changes before rebase 915f08c3bdfSopenharmony_cipick 5d93b84d8 Add statx and other syscall numbers 916f08c3bdfSopenharmony_cipick 6f8c16438 statx: stage 3 (Add statx01) 917f08c3bdfSopenharmony_cipick 98f5bc7ac statx: stage 4 918f08c3bdfSopenharmony_cipick 76e03d714 statx: stage 5a 919f08c3bdfSopenharmony_cipick bfeef7902 statx: stage 5b 920f08c3bdfSopenharmony_cipick 09dd2c829 statx: stage 6 921f08c3bdfSopenharmony_cipick d784b1e85 test-writing-guidelines: Remove old API argument 922f08c3bdfSopenharmony_cipick 6a87a084a statx01: Fix review problems 923f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 924f08c3bdfSopenharmony_ci 925f08c3bdfSopenharmony_ciSo all the commits marked with +fixup+ will be re-played by Git immediately 926f08c3bdfSopenharmony_ciafter 5ca62 at the top. A new commit will then be created with the amalgamated 927f08c3bdfSopenharmony_cichanges of all the commits and 5ca62's log message. It turns out that I didn't 928f08c3bdfSopenharmony_cineed to reword anything, but there is no harm in checking. It is easy to 929f08c3bdfSopenharmony_ciforget the +Signed-off-by:+ line. 930f08c3bdfSopenharmony_ci 931f08c3bdfSopenharmony_ciI could now do the same for the commits to the +statx+ test, making the commit 932f08c3bdfSopenharmony_cimessage prefixes consistent. However I am not actually going to submit the 933f08c3bdfSopenharmony_citest (yet). 934f08c3bdfSopenharmony_ci 935f08c3bdfSopenharmony_ciI won't attempt to show you this, but if you need to do the opposite and split 936f08c3bdfSopenharmony_ciapart a commit. It is also possible using Git-rebase by marking a line with 937f08c3bdfSopenharmony_ci+edit+. This will pause Git just after replaying the marked commit. You can 938f08c3bdfSopenharmony_cithen use a 'soft' Git-reset to bring the selected commit's changes back into 939f08c3bdfSopenharmony_cithe 'index' where you are then able to un-stage some parts before 940f08c3bdfSopenharmony_cire-committing. 941f08c3bdfSopenharmony_ci 942f08c3bdfSopenharmony_ciYou can also use +edit+ and +git commit --amend+ together to change a commit 943f08c3bdfSopenharmony_cideep in your history, but without resetting the 'index'. The 'index' contains 944f08c3bdfSopenharmony_cichanges which you have staged with +git add+, but not yet committed. 945f08c3bdfSopenharmony_ci 946f08c3bdfSopenharmony_ciSo now that the commit history has been cleaned up, we need to submit a patch 947f08c3bdfSopenharmony_cito the mailing list or make a pull request on GitHub. The mailing list is the 948f08c3bdfSopenharmony_cipreferred place to make submissions and is more difficult for most people, so 949f08c3bdfSopenharmony_ciI will only cover that method. 950f08c3bdfSopenharmony_ci 951f08c3bdfSopenharmony_ciJust before we create the patch, we need to check that our changes will still 952f08c3bdfSopenharmony_ciapply to the master branch without problems. To do this we can use another 953f08c3bdfSopenharmony_citype of 'rebase' and then try rebuilding and running the test. 954f08c3bdfSopenharmony_ci 955f08c3bdfSopenharmony_ci[source,shell] 956f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 957f08c3bdfSopenharmony_ci$ git checkout master 958f08c3bdfSopenharmony_ci$ git pull origin 959f08c3bdfSopenharmony_ci$ git checkout tutorial-rebase2 960f08c3bdfSopenharmony_ci$ git rebase master 961f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 962f08c3bdfSopenharmony_ci 963f08c3bdfSopenharmony_ciAbove, I update the master branch and then replay our changes onto it using 964f08c3bdfSopenharmony_ci+git rebase master+. You may find that after the rebase there is a merge 965f08c3bdfSopenharmony_ciconflict. This will result in something which looks like the following (taken 966f08c3bdfSopenharmony_cifrom a Makefile conflict which was caused by reordering commits in a 'rebase'). 967f08c3bdfSopenharmony_ci 968f08c3bdfSopenharmony_ci[source,diff] 969f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 970f08c3bdfSopenharmony_ci<<<<<<< HEAD 971f08c3bdfSopenharmony_cicve-2016-7117: LDFLAGS += -lpthread 972f08c3bdfSopenharmony_ci======= 973f08c3bdfSopenharmony_cicve-2014-0196: LDFLAGS += -lpthread -lutil -lrt 974f08c3bdfSopenharmony_cicve-2016-7117: LDFLAGS += -lpthread -lrt 975f08c3bdfSopenharmony_ci>>>>>>> 4dbfb8e79... Add -lrt 976f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 977f08c3bdfSopenharmony_ci 978f08c3bdfSopenharmony_ciThe first line tells us this is the beginning of a conflict. The third line 979f08c3bdfSopenharmony_ciseparates the two conflicting pieces of content and the last line is the end 980f08c3bdfSopenharmony_ciof the conflict. Usually, all you need to do is remove the lines you don't 981f08c3bdfSopenharmony_ciwant, stage the changes and continue the 'rebase' with +git rebase 982f08c3bdfSopenharmony_ci--continue+. 983f08c3bdfSopenharmony_ci 984f08c3bdfSopenharmony_ciIn order to create a patch e-mail we use https://git-scm.com/docs/git-format-patch[+git format-patch+], 985f08c3bdfSopenharmony_ciwe can then send that e-mail using https://git-scm.com/docs/git-send-email[+git send-email+]. 986f08c3bdfSopenharmony_ciIt is also possible to import the patch (+mbox+) file into a number of e-mail programs. 987f08c3bdfSopenharmony_ci 988f08c3bdfSopenharmony_ci[source,shell] 989f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 990f08c3bdfSopenharmony_ci$ git format-patch -1 -v 2 -o output --to ltp@lists.linux.it fd3cc8596 991f08c3bdfSopenharmony_cioutput/v2-0001-tutorial-Add-a-step-by-step-C-test-tutorial.patch 992f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 993f08c3bdfSopenharmony_ci 994f08c3bdfSopenharmony_ciThe first argument +-1+ specifies we want one commit from fd3cc8596 995f08c3bdfSopenharmony_cionwards. If we wanted this commit and the one after it we could specify +-2+ 996f08c3bdfSopenharmony_ciinstead. 997f08c3bdfSopenharmony_ci 998f08c3bdfSopenharmony_ciThis is my second patch submission so I have used +-v 2+, which indicates this 999f08c3bdfSopenharmony_ciis the second version of a patch set. The +-o+ option specifies the output 1000f08c3bdfSopenharmony_cidirectory (literally called +output+). The +--to+ option adds the +To:+ e-mail 1001f08c3bdfSopenharmony_ciheader, which I have set to the LTP mailing list. 1002f08c3bdfSopenharmony_ci 1003f08c3bdfSopenharmony_ciWe can then send this patch with the following command sans +--dry-run+. 1004f08c3bdfSopenharmony_ci 1005f08c3bdfSopenharmony_ci[source,shell] 1006f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 1007f08c3bdfSopenharmony_ci$ git send-email --dry-run output/v2-0001-tutorial-Add-a-step-by-step-C-test-tutorial.patch 1008f08c3bdfSopenharmony_ci-------------------------------------------------------------------------------- 1009f08c3bdfSopenharmony_ci 1010f08c3bdfSopenharmony_ciGit will ask some questions (which you can ignore) and then tell you what it 1011f08c3bdfSopenharmony_ciwould do if this weren't a dry-run. In order for this to work you have to have 1012f08c3bdfSopenharmony_cia valid SMTP server set in +.gitconfig+ and also be signed up to the LTP 1013f08c3bdfSopenharmony_cimailing list under the same e-mail address you have configured in Git. You can 1014f08c3bdfSopenharmony_cisign up at https://lists.linux.it/listinfo/ltp. 1015f08c3bdfSopenharmony_ci 1016f08c3bdfSopenharmony_ci8. Doing code review 1017f08c3bdfSopenharmony_ci-------------------- 1018f08c3bdfSopenharmony_ci 1019f08c3bdfSopenharmony_ciWhile waiting for your test to be reviewed, you are invited and encouraged to 1020f08c3bdfSopenharmony_cireview other contributors' code. This may seem bizarre when you are completely 1021f08c3bdfSopenharmony_cinew to the project, but there are two important ways in which you can 1022f08c3bdfSopenharmony_cicontribute here: 1023f08c3bdfSopenharmony_ci 1024f08c3bdfSopenharmony_ciA. Point out logical errors in the code. 1025f08c3bdfSopenharmony_ciB. Improve your own understanding 1026f08c3bdfSopenharmony_ci 1027f08c3bdfSopenharmony_ciIt doesn't matter whether you know the canonical way of writing an LTP test in 1028f08c3bdfSopenharmony_ciC. An error of logic, when properly explained, is usually indisputable. These 1029f08c3bdfSopenharmony_ciare the most important errors to find as they always result in false test 1030f08c3bdfSopenharmony_ciresults. Once someone points out such an error it is usually obvious to 1031f08c3bdfSopenharmony_cieveryone that it is a bug and needs to be fixed. 1032f08c3bdfSopenharmony_ci 1033f08c3bdfSopenharmony_ciObviously testing the patch is one way of finding errors. You can apply 1034f08c3bdfSopenharmony_cipatches using +git am+. Then it is just a case of compiling and running the 1035f08c3bdfSopenharmony_citests. 1036f08c3bdfSopenharmony_ci 1037f08c3bdfSopenharmony_ciFinally, reading and attempting to comment on other peoples patches, gives 1038f08c3bdfSopenharmony_ciyou a better understanding of the reviewers perspective. This is better for 1039f08c3bdfSopenharmony_cithe project and for you. 1040f08c3bdfSopenharmony_ci 1041f08c3bdfSopenharmony_ciStyle and organisational issues are best left to after you have found logical 1042f08c3bdfSopenharmony_cierrors. 1043f08c3bdfSopenharmony_ci 1044f08c3bdfSopenharmony_ci9. Final notes 1045f08c3bdfSopenharmony_ci-------------- 1046f08c3bdfSopenharmony_ci 1047f08c3bdfSopenharmony_ciHopefully you can now grasp the structure of an LTP test and have some idea of 1048f08c3bdfSopenharmony_ciwhat is available in the LTP test library. There are a vast number of library 1049f08c3bdfSopenharmony_cifunctions available (mainly located in include and lib), some of which are 1050f08c3bdfSopenharmony_cidocumented in the test writing guidelines and many of which are not. 1051f08c3bdfSopenharmony_ci 1052f08c3bdfSopenharmony_ciWe have only scratched the surface of the immense technical complexity of 1053f08c3bdfSopenharmony_cisystems programming across multiple Kernel and C lib versions as well as 1054f08c3bdfSopenharmony_cidifferent hardware architectures. The important thing to take away from this 1055f08c3bdfSopenharmony_ciis that you have to be conscientious of what will happen on systems different 1056f08c3bdfSopenharmony_cifrom yours. The LTP has a huge and varied user base, so situations you may 1057f08c3bdfSopenharmony_cithink are unlikely can and do happen to somebody. 1058f08c3bdfSopenharmony_ci 1059f08c3bdfSopenharmony_ciOf course you don't want to spend time allowing for situations which may never 1060f08c3bdfSopenharmony_ciarise either, so you have to do your research and think about each situation 1061f08c3bdfSopenharmony_cicritically. The more systems you can test on before submitting your changes, 1062f08c3bdfSopenharmony_cithe better, although we understand not everyone has access to a lab. 1063f08c3bdfSopenharmony_ci 1064f08c3bdfSopenharmony_ciOne important topic which has not been covered by this tutorial, is 1065f08c3bdfSopenharmony_cimulti-process or multi-threaded testing. The LTP library functions work inside 1066f08c3bdfSopenharmony_cichild processes and threads, but their semantics change slightly. There are 1067f08c3bdfSopenharmony_cialso various helper functions for synchronising and forking processes. For 1068f08c3bdfSopenharmony_cimore information see 1069f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/C-Test-API[C Test API], 1070f08c3bdfSopenharmony_ciin particular sections 1071f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/C-Test-API#17-fork-ing[1.7 Fork()-ing] to 1072f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/C-Test-API#110-signals-and-signal-handlers[1.10 Signals and signal handlers] and 1073f08c3bdfSopenharmony_cihttps://github.com/linux-test-project/ltp/wiki/C-Test-API#114-thread-safety-in-the-ltp-library[1.14 Thread-safety in the LTP library]. 1074f08c3bdfSopenharmony_ci 1075f08c3bdfSopenharmony_ciWhen it comes time to submit a test, the preferred way to do it is on the 1076f08c3bdfSopenharmony_cimailing list although you can also use GitHub. The LTP follows similar rules 1077f08c3bdfSopenharmony_cito the kernel for formatting and submitting patches. Generally speaking the 1078f08c3bdfSopenharmony_cireview cycle is easier for small patches, so try to make small changes or 1079f08c3bdfSopenharmony_ciadditions where possible. 1080