| Main index | Section 5 | Options |
A Kyuafile is a Lua script whose purpose is to describe the structure of the test suite it belongs to. To do so, the script has access to a collection of special functions provided by kyua(1) as described in Helper functions.
Any new Kyuafile file should set version to '2'.
The test suite name provided in the test_suite() call tells kyua(1) which set of configuration variables from kyua.conf(5) to pass to the test programs at run time.
The test programs to be registered must live in the current directory; in other words, the various *_test_program() calls cannot reference test programs in other directories. The rationale for this is to force all Kyuafile files to be self-contained, and to simplify their internal representation.
ATF test programs are those that use the atf(7) libraries. They can be registered with the atf_test_program() table constructor. This function takes the name of the test program and a collection of optional metadata settings for all the test cases in the test program. Any metadata properties defined by the test cases themselves override the metadata values defined here.
Plain test programs are those that return 0 on success and non-0 on failure; in general, most test programs (even those that use fancy unit-testing libraries) behave this way and thus also qualify as plain test programs. They can be registered with the plain_test_program() table constructor. This function takes the name of the test program, an optional test_suite name that overrides the global test suite name, and a collection of optional metadata settings for the test program.
TAP test programs are those that implement the Test Anything Protocol. They can be registered with the tap_test_program() table constructor. This function takes the name of the test program and a collection of optional metadata settings for the test program.
The following metadata properties can be passed to any test program definition:
| allowed_architectures | |
| Whitespace-separated list of machine architecture names allowed by the test. If empty or not defined, the test is allowed to run on any machine architecture. | |
| allowed_platforms | |
| Whitespace-separated list of machine platform names allowed by the test. If empty or not defined, the test is allowed to run on any machine platform. | |
| custom.NAME | |
|
Custom variable defined by the test where
'NAME'
denotes the name of the variable.
These variables are useful to tag your tests with information specific to
your project.
The values of such variables are propagated all the way from the tests to the
results files and later to any generated reports.
Note that if the name happens to have dashes or any other special characters in it, you will have to use a special Lua syntax to define the property. Refer to the EXAMPLES section below for clarification. | |
| description | |
| Textual description of the test. | |
| execenv | |
| The name of the execution environment to be used for running the test. If empty or not defined, the 'host' execution environment is meant. The possible values are: | |
| host | The default environment which runs the test as a usual child process. |
| jail |
The
FreeBSD
jail(8)
environment.
It creates a temporary jail to run the test and its optional cleanup logic
within.
This feature requires kyua(1) to be running with superuser privileges. The difference between security.jail.children.max and security.jail.children.cur sysctl of the jail kyua(1) is running within must have a value high enough for the jail based tests planned to be run. For instance, the value 1 should be enough for a sequential run of simple tests. Otherwise, such aspects as parallel test execution and sub-jails spawned by specific test cases should be considered. The formula of a temporary jail name is 'kyua' + test program path + '_' + test case name. All non-alphanumeric characters are replaced with '_'. 'kyua_usr_tests_sys_netpfil_pf_pass_block_v4' is an example for /usr/tests/sys/netpfil/pf/pass_block:v4 test case. |
| execenv_jail_params | |
|
Additional test-specific whitespace-separated parameters of
FreeBSD
jail(8)
to create a temporary jail within which the test is run.
It makes sense only if execenv is set to
'jail'.
kyua(1) implicitly passes 'children.max' parameter to jail(8) for a temporary jail with the maximum possible value according to the jail kyua(1) itself is running within. It allows tests to easily spawn their own sub-jails without additional configuration. It can be overridden via execenv_jail_params if needed. | |
| is_exclusive | |
| If true, indicates that this test program cannot be executed along any other programs at the same time. Test programs that affect global system state, such as those that modify the value of a sysctl(8) setting, must set themselves as exclusive to prevent failures due to race conditions. Defaults to false. | |
| required_configs | |
| Whitespace-separated list of configuration variables that the test requires to be defined before it can run. | |
| required_disk_space | |
| Amount of available disk space that the test needs to run successfully. | |
| required_files | |
| Whitespace-separated list of paths that the test requires to exist before it can run. | |
| required_memory | |
| Amount of physical memory that the test needs to run successfully. | |
| required_programs | |
| Whitespace-separated list of basenames or absolute paths pointing to executable binaries that the test requires to exist before it can run. | |
| required_user | |
| If empty, the test has no restrictions on the calling user for it to run. If set to 'unprivileged', the test needs to not run as root. If set to 'root', the test must run as root. | |
| timeout | |
| Amount of seconds that the test is allowed to execute before being killed. | |
include() may only be called with a relative path and with at most one directory component. This is by design: Kyua uses the file system structure as the layout of the test suite definition. Therefore, each subdirectory in a test suite must include its own Kyuafile and each Kyuafile can only descend into the Ns of immediate subdirectories.
If you need to source a Kyuafile located in disjoint parts of your file system namespace, you will have to create a 'shadow tree' using symbolic links and possibly helper Ns to plug the various subdirectories together. See the EXAMPLES section below for details.
Note that each file is processed in its own Lua environment: there is no mechanism to pass state from one file to the other. The reason for this is that there is no such thing as a "top-level" Kyuafile in a test suite: the user has to be able to run the test suite from any directory in a given hierarchy, and this execution must not depend on files that live in parent directories.
Kyua allows running all the installed test suites at once in order to provide comprehensive cross-component reports. In order to do this, there is a special file in the top directory that knows how to inspect the subdirectories in search for other Kyuafiles and include them.
The FILES section includes more details on where this file lives.
The following extra functions are provided by Kyua:
| stringcurrent_kyuafile() | |
| Returns the absolute path to the current Kyuafile. | |
| stringfs.basename(string path) | |
| Returns the last component of the given path. | |
| stringfs.dirname(string path) | |
| Returns the given path without its last component or a dot if the path has a single component. | |
| boolfs.exists(string path) | |
| Checks if the given path exists. If the path is not absolute, it is relative to the directory containing the Kyuafile in which the call to this function occurs. | |
| iteratorfs.files(string path) | |
| Opens a directory for scanning of its entries. The returned iterator yields an entry on each call, and the entry is simply the filename. If the path is not absolute, it is relative to the directory containing the Kyuafile in which the call to this function occurs. | |
| is_absolutefs.is_absolute(string path) | |
| Returns true if the given path is absolute; false otherwise. | |
| joinfs.join(string path, string path) | |
| Concatenates the two paths. The second path cannot be absolute. | |
| /usr/tests/Kyuafile. | |
| Top-level Kyuafile for the current system. | |
| /usr/share/examples/kyua/Kyuafile.top. | |
| Sample file to serve as a top-level Kyuafile. | |
syntax(2)test_suite('first')
atf_test_program{name='integration_test'} plain_test_program{name='legacy_test'}
The following example is a bit more elaborate. It introduces some metadata properties to the test program definitions and recurses into a couple of subdirectories:
syntax(2)test_suite('second')
plain_test_program{name='legacy_test', allowed_architectures='amd64 i386', required_files='/bin/ls', timeout=30}
tap_test_program{name='privileged_test', required_user='root'}
include('module-1/Kyuafile') include('module-2/Kyuafile')
The syntax to define custom properties may be not obvious if their names have any characters that make the property name not be a valid Lua identifier. Dashes are just one example. To set such properties, do something like this:
syntax(2)test_suite('FreeBSD')
plain_test_program{name='the_test', ['custom.FreeBSD-Bug-Id']='category/12345'}
syntax(2)test_suite('FreeBSD')
atf_test_program{name='network_test', execenv='jail', execenv_jail_params='vnet allow.raw_sockets', required_user='root'}
A test case itself may have no requirements in superuser privileges, but required_user='root' metadata property reminds that the jail execution environment requires kyua(1) being running with root privileges, and the test is skipped otherwise with the respective message. The combination of execenv set to 'jail' and required_user set to 'unprivileged' does not work respectively.
We cannot create a Kyuafile that references these because the include() directive does not support absolute paths. Instead, what we can do is create a shadow tree using symbolic links:
$ mkdir ~/everything $ ln -s /usr/tests ~/everything/system-tests $ ln -s /usr/local/tests ~/everything/local-tests $ ln -s ~/local/tests ~/everything/home-tests
And then we create an ~/everything/Kyuafile file to drive the execution of the integrated test suite:
syntax(2)test_suite('test-all-the-things')
include('system-tests/Kyuafile') include('local-tests/Kyuafile') include('home-tests/Kyuafile')
Or, simply, you could reuse the sample top-level Kyuafile to avoid having to manually craft the list of directories into which to recurse:
$ cp /usr/share/examples/kyua/Kyuafile.top ~/everything/Kyuafile
| KYUAFILE (5) | March 23, 2024 |
| Main index | Section 5 | Options |
Please direct any comments about this manual page service to Ben Bullock. Privacy policy.
