• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1LTP Style Guide
2===============
3
4**********************************************************************
5Welcome to the *LTP Project Coding Guideline* document! This document is
6designed to guide committers and contributors in producing consistent, quality
7deterministic testcases and port testcases from other sources to LTP so that
8they can be easily maintained by project members and external contributors.
9
10Please refer to the *Linux Kernel Coding Guidelines* unless stated otherwise
11in this document.
12
13Changelog:
14
15 * Initial version: Ngie Cooper <yaneurabeya@gmail.com>
16 * Reformatted for asciidoc: Cyril Hrubis <chrubis@suse.cz>
17**********************************************************************
18
19Using libltp
20------------
21
22Of course the manpages should be the primary source of information in
23terms of how you should use libltp, but this section provides a quick
24set of guidelines to hit the ground running with libltp.
25
26When you can use libltp please observe the following guidelines:
27
281. Should I use tst_*() interface in forked processes?
29~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30
31No, only use libltp in non-forked processes and functions +perror(3)+ /
32+exit(3)+ otherwise. Reason being:
33
34 * Calling +tst_resm()+ from multiple processes is messy.
35 * Calling cleanup can break test execution.
36 * Establishing a complicated scheme of tracking the testcase state
37   for teardown is undesirable.
38
392. Use SAFE_* macros
40~~~~~~~~~~~~~~~~~~~~
41
42Use +SAFE_*+ macros (see +safe_macros.h+) instead of bare calls to libcalls and
43syscalls. This will:
44
45 * Reduce number of lines wasted on repeated in multiple files with
46   error catching logic.
47 * Ensure that error catching is consistent and informative; all
48   +SAFE_*+ macros contain the line number of the failure as well as
49   the file where the failure occurred by design. So unless the
50   stack gets stomped on, you will be able to determine where
51   the failures occurred if and when they do occur with absolute
52   determinism.
53 * Mute some unchecked return code warnings.
54
553. Don't call cleanup() from within setup()
56~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57
58Unless you need to clean up or reset system state that wouldn't otherwise be
59handled by a proper release of all OS resources.
60
61This includes (but is not limited to):
62
63 * Memory mapped pages.
64 * Mounted filesystems.
65 * File descriptors (if they're in temporary directories, etc).
66 * Temporary files / directories.
67 * Waiting for child processes.
68 * +/proc+ & +/sysfs+ tunable states.
69
70You don't need to clean up the following:
71
72 * +malloc(3)+'ed memory.
73 * Read-only file descriptors in persistent paths (i.e. not
74   temporary directories).
75
76Please be aware of some of the caveats surrounding forking,
77exec'ing and descriptor inheritance, etc.
78
794. Call APIs that don't require freeing up resources on failure first
80~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81
82 * +tst_require_root()+
83 * +tst_sig(...)+
84 * +malloc(3)+
85 * +tst_tmpdir()+
86
87That way you can simplify your setup and avoid calling cleanup whenever
88possible!
89
905. If the test needs to run as root
91~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92
93If the test need to run as root, check to make sure that you're root
94*before doing any other setup* via +tst_require_root()+.
95
966. No custom reporting APIs
97~~~~~~~~~~~~~~~~~~~~~~~~~~~
98
99Don't roll your own reporting APIs unless you're porting testcases or are
100concerned about portability.
101
1027. Handle TBROK and TFAIL correctly
103~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
104
105Use +TBROK+ when an unexpected failure unrelated to the goal of the testcase
106occurred, and use +TFAIL+ when an unexpected failure related to the goal of
107the testcase occurred.
108
1098. Don't roll your own syscall numbers
110~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111
112Header +linux_syscall_numbers.h+ exists for this purpose and does a pretty
113dang good job.
114
1159. Keep errors as short and sweet as possible
116~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117
118For example:
119[source,c]
120----------------------------------------------------
121if (fork() == -1)
122	tst_brkm(TBROK, cleanup, "fork failed");
123
124/* or */
125
126if (fork() == -1)
127	tst_brkm(TBROK, cleanup, "fork # 1 failed");
128
129if (fork() == -1)
130	tst_brkm(TBROK, cleanup, "fork # 2 failed");
131----------------------------------------------------
132
133If you can't determine where the failure has occurred in a testcase based on
134the entire content of the failure messages, then determining the cause of
135failure may be impossible.
136
13710. Reporting errno and the TEST() macro
138~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139
140Don't roll your own +errno+ / +strerror()+ printout when you use +tst_resm()+
141calls. Use either +TERRNO+ or +TTERRNO+. Similarly, if a testcase passed and
142it's obvious why it passed (for example a function call returns +0+ or
143+TEST_RETURN == 0+).
144
145[source,c]
146-------------------------------------------------------------------------------
147/* Example without TEST(...) macro */
148
149exp_errno = ENOENT;
150
151if (fn() == -1) {
152	/*
153	 * Using TERRNO here is valid because the error case
154	 * isn't static.
155	 */
156	if (exp_errno == ENOENT)
157		tst_resm(TPASS|TERRNO,
158		    "fn failed as expected");
159	/*
160	 * Using strerror(TEST_ERRNO) here is valid because
161	 * the error case isn't static.
162	 */
163	else
164		tst_resm(TFAIL|TERRNO,
165		    "fn failed unexpectedly; expected "
166		    "%d - %s",
167		    exp_errno, strerror(exp_errno));
168} else
169	tst_resm(TBROK, "fn passed unexpectedly");
170
171/* Example using TEST(...) macro */
172
173TEST(fn());
174if (TEST_RETURN == 0)
175	tst_resm(TPASS, "fn passed as expected");
176else
177	tst_resm(TFAIL|TTERRNO, "fn failed");
178-------------------------------------------------------------------------------
179
180[NOTE]
181The +TEST()+ macro is not thread-safe as it saves return value and errno into
182global variable.
183
18412. Use tst_brkm() when possible
185~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186
187Use...
188[source,c]
189------------------------------
190tst_brkm(TBROK, cleanup, ...);
191------------------------------
192...instead of...
193[source,c]
194------------------------------
195tst_resm(TBROK, ...);
196cleanup();
197tst_exit();
198------------------------------
199
200[NOTE]
201As you see the +tst_brkm()+ no longer requires non +NULL+ cleanup_fn argument
202in order to call +tst_exit()+.
203
20413. Indentation
205~~~~~~~~~~~~~~~
206
207Use hard tabs for first-level indentation, and 4 spaces for every line longer
208than 80 columns. Use a linebreak with string constants in format functions
209like +*printf()+, the +tst_resm()+ APIs, etc.
210
211Example:
212[source,c]
213-------------------------------------------------------------------------------
214if ((this_is_a_poorly_formed_really_long_variable = function_call()) == NULL &&
215    statement1() && i < j && l != 5) {
216	/* Use tabs here */
217	printf("The rain in Spain falls mainly in the plain.\nThe quick brown "
218	    "fox jumped over the lazy yellow dog\n");
219	tst_resm(TPASS,
220	    "Half would turn and fight. The other half would try to swim "
221	    "across. But my uncle told me about a few that... they'd swim "
222	    "halfway out, turn with the current, and ride it all the way out "
223	    "to sea. Fisherman would find them a mile offshore, swimming.");
224}
225-------------------------------------------------------------------------------
226
22714. System headers
228~~~~~~~~~~~~~~~~~~
229
230Don't use +linux/+ headers if at all possible. Usually they are replaced with
231+sys/+ headers as things work their way into glibc.  Furthermore, +linux/+
232headers get shuffled around a lot more than their +sys/+ counterparts it
233seems.
234
23515. Signal handlers
236~~~~~~~~~~~~~~~~~~~~
237
238Avoid doing tricky things in signal handlers. Calling most of the libc
239functions from signal handler may lead to deadlocks or memory corruption.  If
240you really need to do anything more complicated that +should_run = 0;+ in your
241signal handler consult +man 7 signal+ for async-signal-safe functions.
242
243Porting Testcases
244-----------------
245
246If one of the following is true...
247
248 1. You are porting a testcase directly to LTP which doesn't need to
249    be ported outside of Linux.
250 2. The beforementioned project or source is no longer contributing
251    changes to the testcases.
252
253Then please fully port the testcase(s) to LTP. Otherwise, add robust porting
254shims around the testcases using libltp APIs to reduce longterm maintenance
255and leave the sources alone so it's easier to sync the testcases from the
256upstream source.
257
258New Testcases
259-------------
260
261 1. Always use libltp for Linux centric tests. No ifs, ands, or buts
262    about it.
263 2. Sort headers, like:
264
265[source,c]
266---------------------------------------------------------------------------
267/*
268 * sys/types.h is usually (but not always) required by POSIX
269 * APIs.
270 */
271#include <sys/types.h>
272/* sys headers, alphabetical order. */
273/* directory prefixed libc headers. */
274/* non-directory prefixed libc headers. */
275/* directory prefixed non-libc (third-party) headers. */
276/* non-directory prefixed non-libc (third-party) headers. */
277/* Sourcebase relative includes. */
278
279/* e.g. */
280
281#include <sys/types.h>
282#include <sys/stat.h>
283#include <netinet/icmp.h>
284#include <stdio.h>
285#include <dbus-1.0/dbus/dbus.h>
286#include <archive.h>
287#include "foo/bar.h"
288#include "test.h"
289---------------------------------------------------------------------------
290
2913. Comments
292~~~~~~~~~~~
293
294Do not use obvious comments ("child process", "parse options", etc). This
295leads to visual comment noise pollution.
296
2974. Inline assignments
298~~~~~~~~~~~~~~~~~~~~
299
300Don't do inline assignment, i.e.
301
302[source,c]
303---------------------------------------------------------------------------
304int foo = 0;
305
306Use separate statements:
307
308int foo;
309
310foo = 0;
311---------------------------------------------------------------------------
312
313The only exception to this is when you define global variables.
314
3155. How to assert test is running as root?
316~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
317
318Your testcase should be runnable as root and non-root. What does that mean? It
319should fail gracefully as non-root if it has insufficient privileges, or use
320+tst_require_root()+ if root access is absolutely required.
321
322A lot of newer testcases don't honor this fact and it causes random
323unnecessary errors when run as non-privileged users.
324
3256. Do I need to create temporary directory?
326~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
327
328Use +tst_tmpdir()+ if your testcase will:
329
330* Create temporary files.
331* Dump core.
332* Etc. Otherwise, don't bother with the API.
333
334[NOTE]
335If you created temporary directory with +tst_tmpdir()+ don't forget to call
336+tst_rmdir()+ when the test is cleaning up. This is *NOT* done automatically.
337
3387. Setting up signal handlers
339~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
340
341Use +tst_sig()+ instead of bothering with sigaction / signal. This reduces
342potential of leaving a mess around if your test doesn't exit cleanly (now,
343there are some signals that can't be blocked, i.e. +SIGKILL+ and +SIGSTOP+,
344but the rest can be caught).
345
3468. Basic template
347~~~~~~~~~~~~~~~~~
348
349The following is a basic testcase template:
350[source,c]
351---------------------------------------------------------------------------
352#include "test.h"
353
354char *TCID = "testname";
355int TST_TOTAL = /* ... */
356
357static void setup(void)
358{
359	/* ... */
360
361	tst_require_root();
362
363	tst_tmpdir();
364
365	/* ... */
366
367	TEST_PAUSE;
368}
369
370static void cleanup(void)
371{
372
373	TEST_CLEANUP;
374
375	/* ... */
376
377	tst_rmdir();
378}
379
380int main(void)
381{
382	/* ... */
383
384	setup();	/* Optional */
385
386	cleanup();	/* Optional */
387	tst_exit();	/* DON'T FORGET THIS -- this must be last! */
388}
389---------------------------------------------------------------------------
390
391Fixing Legacy Testcases
392-----------------------
393
394Unless you interested in exercising self-masochism, do minimal changes
395to testcases when fixing them so it's easier to track potential
396breakage in testcases after a commit is made (mistakes happen and no
397one is perfect). If it works after you fix it -- great -- move on.
398It's more the job of the committers / maintainers to do things like
399style commits.
400
401It's better to focus on adding more content to LTP as a contributor
402and fixing functional issues with existing tests than it is worrying
403about whitespace, unnecessary pedanticness of function calls, etc.
404
405As ugly as the style is in the surrounding code may be, stick to it.
406Otherwise anyone reading the code will cringe at the chaos and
407non-uniform `style', and it will be more difficult to fix later.
408
409
410Fixing Open Posix Testsuite
411---------------------------
412
413The *Open Posix Testsuite* does not use libltp interface and moreover aims to
414be usable on any *POSIX* compatible operating system.
415
416So *NO* Linux, BSD specific syscalls there.
417
418Contribution to the project
419---------------------------
420
421Since CVS is effectively dead for LTP proper, we ask that you submit
422patches that are git friendly and patchable.
423
424Guidelines for submitting patches are as follows:
425
4261. Use +git commit -s+ . You know you want to ;) .. (you may need to
427   submit a correct signed-off-by line, e.g. use git config first).
4282. Provide a short (<= 50 character) description of the commit.
4293. Provide a little more terse (1-2 paragraph maximum, <= 72 character
430   lines) description of what the commit does.
4314. Format the email with +git format-patch --attach+ command .
432
433Example of a commit message:
434
435-------------------------------------------------------------------
436Short description of my commit.
437
438This is a much longer description of my commit. Blah blah blah blah
439blah blah blah blah blah.
440
441Signed-off-by: John Smith <dev@null>
442-------------------------------------------------------------------
443