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