xref: /freebsd/contrib/kyua/doc/kyuafile.5.in (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
1.\" Copyright 2012-2024 The Kyua Authors.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions are
6.\" met:
7.\"
8.\" * Redistributions of source code must retain the above copyright
9.\"   notice, this list of conditions and the following disclaimer.
10.\" * Redistributions in binary form must reproduce the above copyright
11.\"   notice, this list of conditions and the following disclaimer in the
12.\"   documentation and/or other materials provided with the distribution.
13.\" * Neither the name of Google Inc. nor the names of its contributors
14.\"   may be used to endorse or promote products derived from this software
15.\"   without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21.\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.Dd March 23, 2024
29.Dt KYUAFILE 5
30.Os
31.Sh NAME
32.Nm Kyuafile
33.Nd Test suite description files
34.Sh SYNOPSIS
35.Fn atf_test_program "string name" "[string metadata]"
36.Fn current_kyuafile
37.Fn fs.basename "string path"
38.Fn fs.dirname "string path"
39.Fn fs.exists "string path"
40.Fn fs.files "string path"
41.Fn fs.is_absolute "string path"
42.Fn fs.join "string path" "string path"
43.Fn include "string path"
44.Fn plain_test_program "string name" "[string metadata]"
45.Fn syntax "int version"
46.Fn tap_test_program "string name" "[string metadata]"
47.Fn test_suite "string name"
48.Sh DESCRIPTION
49A test suite is a collection of test programs and is represented by a
50hierarchical layout of test binaries on the file system.
51Any subtree of the file system can represent a test suite, provided that it
52includes one or more
53.Nm Ns s ,
54which are the test suite definition files.
55.Pp
56A
57.Nm
58is a Lua script whose purpose is to describe the structure of the test
59suite it belongs to.
60To do so, the script has access to a collection of special functions provided
61by
62.Xr kyua 1
63as described in
64.Sx Helper functions .
65.Ss File versioning
66Every
67.Nm
68file starts with a call to
69.Fn syntax "int version" .
70This call determines the specific schema used by the file so that future
71backwards-incompatible modifications to the file can be introduced.
72.Pp
73Any new
74.Nm
75file should set
76.Fa version
77to
78.Sq 2 .
79.Ss Test suite definition
80If the
81.Nm
82registers any test programs,
83the
84.Nm
85must define the name of the test suite the test programs belong to by using the
86.Fn test_suite
87function at the very beginning of the file.
88.Pp
89The test suite name provided in the
90.Fn test_suite
91call tells
92.Xr kyua 1
93which set of configuration variables from
94.Xr kyua.conf 5
95to pass to the test programs at run time.
96.Ss Test program registration
97A
98.Nm
99can register test programs by means of a variety of
100.Fn *_test_program
101functions, all of which take the name of a test program and a set of
102optional metadata properties that describe such test program.
103.Pp
104The test programs to be registered must live in the current directory; in
105other words, the various
106.Fn *_test_program
107calls cannot reference test programs in other directories.
108The rationale for this is to force all
109.Nm
110files to be self-contained, and to simplify their internal representation.
111.Pp
112.Em ATF test programs
113are those that use the
114.Xr atf 7
115libraries.
116They can be registered with the
117.Fn atf_test_program
118table constructor.
119This function takes the
120.Fa name
121of the test program and a collection of optional metadata settings for all
122the test cases in the test program.
123Any metadata properties defined by the test cases themselves override the
124metadata values defined here.
125.Pp
126.Em Plain test programs
127are those that return 0 on success and non-0 on failure; in general, most test
128programs (even those that use fancy unit-testing libraries) behave this way and
129thus also qualify as plain test programs.
130They can be registered with the
131.Fn plain_test_program
132table constructor.
133This function takes the
134.Fa name
135of the test program, an optional
136.Fa test_suite
137name that overrides the global test suite name, and a collection of optional
138metadata settings for the test program.
139.Pp
140.Em TAP test programs
141are those that implement the Test Anything Protocol.
142They can be registered with the
143.Fn tap_test_program
144table constructor.
145This function takes the
146.Fa name
147of the test program and a collection of optional metadata settings for the
148test program.
149.Pp
150The following metadata properties can be passed to any test program definition:
151.Bl -tag -width XX -offset indent
152.It Va allowed_architectures
153Whitespace-separated list of machine architecture names allowed by the test.
154If empty or not defined, the test is allowed to run on any machine
155architecture.
156.It Va allowed_platforms
157Whitespace-separated list of machine platform names allowed by the test.
158If empty or not defined, the test is allowed to run on any machine
159platform.
160.It Va custom.NAME
161Custom variable defined by the test where
162.Sq NAME
163denotes the name of the variable.
164These variables are useful to tag your tests with information specific to
165your project.
166The values of such variables are propagated all the way from the tests to the
167results files and later to any generated reports.
168.Pp
169Note that if the name happens to have dashes or any other special characters
170in it, you will have to use a special Lua syntax to define the property.
171Refer to the
172.Sx EXAMPLES
173section below for clarification.
174.It Va description
175Textual description of the test.
176.It Va execenv
177The name of the execution environment to be used for running the test.
178If empty or not defined, the
179.Sq host
180execution environment is meant.
181The possible values are:
182.Bl -tag -width xUnnnnnnn
183.It host
184The default environment which runs the test as a usual child process.
185.It jail
186The
187.Fx
188.Xr jail 8
189environment.
190It creates a temporary jail to run the test and its optional cleanup logic
191within.
192.Pp
193This feature requires
194.Xr kyua 1
195to be running with superuser privileges.
196.Pp
197The difference between
198.Va security.jail.children.max
199and
200.Va security.jail.children.cur
201sysctl of the jail
202.Xr kyua 1
203is running within must have a value high enough for the jail based tests
204planned to be run.
205For instance, the value 1 should be enough for a sequential run of simple
206tests.
207Otherwise, such aspects as parallel test execution and sub-jails spawned
208by specific test cases should be considered.
209.Pp
210The formula of a temporary jail name is
211.Sq kyua
212+
213.Va test program path
214+
215.Sq _
216+
217.Va test case name .
218All non-alphanumeric characters are replaced with
219.Sq _ .
220.Sq kyua_usr_tests_sys_netpfil_pf_pass_block_v4
221is an example for /usr/tests/sys/netpfil/pf/pass_block:v4 test case.
222.El
223.It Va execenv_jail_params
224Additional test-specific whitespace-separated parameters of
225.Fx
226.Xr jail 8
227to create a temporary jail within which the test is run.
228It makes sense only if execenv is set to
229.Sq jail .
230.sp
231.Xr kyua 1
232implicitly passes
233.Sq children.max
234parameter to
235.Xr jail 8
236for a temporary jail with the maximum possible value according to
237the jail
238.Xr kyua 1
239itself is running within.
240It allows tests to easily spawn their own sub-jails without additional
241configuration.
242It can be overridden via
243.Va execenv_jail_params
244if needed.
245.It Va is_exclusive
246If true, indicates that this test program cannot be executed along any other
247programs at the same time.
248Test programs that affect global system state, such as those that modify the
249value of a
250.Xr sysctl 8
251setting, must set themselves as exclusive to prevent failures due to race
252conditions.
253Defaults to false.
254.It Va required_configs
255Whitespace-separated list of configuration variables that the test requires
256to be defined before it can run.
257.It Va required_disk_space
258Amount of available disk space that the test needs to run successfully.
259.It Va required_files
260Whitespace-separated list of paths that the test requires to exist before
261it can run.
262.It Va required_memory
263Amount of physical memory that the test needs to run successfully.
264.It Va required_programs
265Whitespace-separated list of basenames or absolute paths pointing to executable
266binaries that the test requires to exist before it can run.
267.It Va required_user
268If empty, the test has no restrictions on the calling user for it to run.
269If set to
270.Sq unprivileged ,
271the test needs to not run as root.
272If set to
273.Sq root ,
274the test must run as root.
275.It Va timeout
276Amount of seconds that the test is allowed to execute before being killed.
277.El
278.Ss Recursion
279To reference test programs in another subdirectory, a different
280.Nm
281must be created in that directory and it must be included into the original
282.Nm
283by means of the
284.Fn include
285function.
286.Pp
287.Fn include
288may only be called with a relative path and with at most one directory
289component.
290This is by design: Kyua uses the file system structure as the layout of the
291test suite definition.
292Therefore, each subdirectory in a test suite must include its own
293.Nm
294and each
295.Nm
296can only descend into the
297.Nm Ns s
298of immediate subdirectories.
299.Pp
300If you need to source a
301.Nm
302located in disjoint parts of your file system namespace, you will have to
303create a
304.Sq shadow tree
305using symbolic links and possibly helper
306.Nm Ns s
307to plug the various subdirectories together.
308See the
309.Sx EXAMPLES
310section below for details.
311.Pp
312Note that each file is processed in its own Lua environment: there is no
313mechanism to pass state from one file to the other.
314The reason for this is that there is no such thing as a
315.Dq top-level
316.Nm
317in a test suite: the user has to be able to run the test suite from any
318directory in a given hierarchy, and this execution must not depend on files
319that live in parent directories.
320.Ss Top-level Kyuafile
321Every system has a top directory into which test suites get installed.
322The default is
323.Pa __TESTSDIR__ .
324Within this directory live test suites, each of which is in an independent
325subdirectory.
326Each subdirectory can be provided separately by independent third-party
327packages.
328.Pp
329Kyua allows running all the installed test suites at once in order to
330provide comprehensive cross-component reports.
331In order to do this, there is a special file in the top directory that knows
332how to inspect the subdirectories in search for other Kyuafiles and include
333them.
334.Pp
335The
336.Sx FILES
337section includes more details on where this file lives.
338.Ss Helper functions
339The
340.Sq base ,
341.Sq string ,
342and
343.Sq table
344Lua modules are fully available in the context of a
345.Nm .
346.Pp
347The following extra functions are provided by Kyua:
348.Bl -tag -width XX -offset indent
349.It Ft string Fn current_kyuafile
350Returns the absolute path to the current
351.Nm .
352.It Ft string Fn fs.basename "string path"
353Returns the last component of the given path.
354.It Ft string Fn fs.dirname "string path"
355Returns the given path without its last component or a dot if the path has
356a single component.
357.It Ft bool Fn fs.exists "string path"
358Checks if the given path exists.
359If the path is not absolute, it is relative to the directory containing the
360.Nm
361in which the call to this function occurs.
362.It Ft iterator Fn fs.files "string path"
363Opens a directory for scanning of its entries.
364The returned iterator yields an entry on each call, and the entry is simply
365the filename.
366If the path is not absolute, it is relative to the directory containing the
367.Nm
368in which the call to this function occurs.
369.It Ft is_absolute Fn fs.is_absolute "string path"
370Returns true if the given path is absolute; false otherwise.
371.It Ft join Fn fs.join "string path" "string path"
372Concatenates the two paths.
373The second path cannot be absolute.
374.El
375.Sh FILES
376.Bl -tag -width XX
377.It Pa __TESTSDIR__/Kyuafile .
378Top-level
379.Nm
380for the current system.
381.It Pa __EGDIR__/Kyuafile.top .
382Sample file to serve as a top-level
383.Nm .
384.El
385.Sh EXAMPLES
386The following
387.Nm
388is the simplest you can define.
389It provides a test suite definition and registers a couple of different test
390programs using different interfaces:
391.Bd -literal -offset indent
392syntax(2)
393
394test_suite('first')
395
396atf_test_program{name='integration_test'}
397plain_test_program{name='legacy_test'}
398.Ed
399.Pp
400The following example is a bit more elaborate.
401It introduces some metadata properties to the test program definitions and
402recurses into a couple of subdirectories:
403.Bd -literal -offset indent
404syntax(2)
405
406test_suite('second')
407
408plain_test_program{name='legacy_test',
409                   allowed_architectures='amd64 i386',
410                   required_files='/bin/ls',
411                   timeout=30}
412
413tap_test_program{name='privileged_test',
414                 required_user='root'}
415
416include('module-1/Kyuafile')
417include('module-2/Kyuafile')
418.Ed
419.Pp
420The syntax to define custom properties may be not obvious if their names
421have any characters that make the property name not be a valid Lua identifier.
422Dashes are just one example.
423To set such properties, do something like this:
424.Bd -literal -offset indent
425syntax(2)
426
427test_suite('FreeBSD')
428
429plain_test_program{name='the_test',
430                   ['custom.FreeBSD-Bug-Id']='category/12345'}
431.Ed
432.Ss FreeBSD jail execution environment
433The following example configures the test to be run within a temporary jail
434with
435.Xr vnet 9
436support and the permission to create raw sockets:
437.Bd -literal -offset indent
438syntax(2)
439
440test_suite('FreeBSD')
441
442atf_test_program{name='network_test',
443                 execenv='jail',
444                 execenv_jail_params='vnet allow.raw_sockets',
445                 required_user='root'}
446.Ed
447.Pp
448A test case itself may have no requirements in superuser privileges,
449but required_user='root' metadata property reminds that the jail execution
450environment requires
451.Xr kyua 1
452being running with root privileges, and the test is skipped otherwise with
453the respective message. The combination of
454.Va execenv
455set to
456.Sq jail
457and
458.Va required_user
459set to
460.Sq unprivileged
461does not work respectively.
462.Ss Connecting disjoint test suites
463Now suppose you had various test suites on your file system and you would
464like to connect them together so that they could be executed and treated as
465a single unit.
466The test suites we would like to connect live under
467.Pa /usr/tests ,
468.Pa /usr/local/tests
469and
470.Pa ~/local/tests .
471.Pp
472We cannot create a
473.Nm
474that references these because the
475.Fn include
476directive does not support absolute paths.
477Instead, what we can do is create a shadow tree using symbolic links:
478.Bd -literal -offset indent
479$ mkdir ~/everything
480$ ln -s /usr/tests ~/everything/system-tests
481$ ln -s /usr/local/tests ~/everything/local-tests
482$ ln -s ~/local/tests ~/everything/home-tests
483.Ed
484.Pp
485And then we create an
486.Pa ~/everything/Kyuafile
487file to drive the execution of the integrated test suite:
488.Bd -literal -offset indent
489syntax(2)
490
491test_suite('test-all-the-things')
492
493include('system-tests/Kyuafile')
494include('local-tests/Kyuafile')
495include('home-tests/Kyuafile')
496.Ed
497.Pp
498Or, simply, you could reuse the sample top-level
499.Nm
500to avoid having to manually craft the list of directories into which to
501recurse:
502.Bd -literal -offset indent
503$ cp __EGDIR__/Kyuafile.top ~/everything/Kyuafile
504.Ed
505.Sh SEE ALSO
506.Xr kyua 1
507