1*754f425fSjmmv.\" Copyright 2012 Google Inc. 2*754f425fSjmmv.\" All rights reserved. 3*754f425fSjmmv.\" 4*754f425fSjmmv.\" Redistribution and use in source and binary forms, with or without 5*754f425fSjmmv.\" modification, are permitted provided that the following conditions are 6*754f425fSjmmv.\" met: 7*754f425fSjmmv.\" 8*754f425fSjmmv.\" * Redistributions of source code must retain the above copyright 9*754f425fSjmmv.\" notice, this list of conditions and the following disclaimer. 10*754f425fSjmmv.\" * Redistributions in binary form must reproduce the above copyright 11*754f425fSjmmv.\" notice, this list of conditions and the following disclaimer in the 12*754f425fSjmmv.\" documentation and/or other materials provided with the distribution. 13*754f425fSjmmv.\" * Neither the name of Google Inc. nor the names of its contributors 14*754f425fSjmmv.\" may be used to endorse or promote products derived from this software 15*754f425fSjmmv.\" without specific prior written permission. 16*754f425fSjmmv.\" 17*754f425fSjmmv.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18*754f425fSjmmv.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19*754f425fSjmmv.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20*754f425fSjmmv.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21*754f425fSjmmv.\" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22*754f425fSjmmv.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23*754f425fSjmmv.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*754f425fSjmmv.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*754f425fSjmmv.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*754f425fSjmmv.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27*754f425fSjmmv.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*754f425fSjmmv.Dd September 9, 2012 29*754f425fSjmmv.Dt KYUA-ATF-INTERFACE 1 30*754f425fSjmmv.Os 31*754f425fSjmmv.Sh NAME 32*754f425fSjmmv.Nm atf-interface 33*754f425fSjmmv.Nd Description of the ATF test program interface 34*754f425fSjmmv.Sh DESCRIPTION 35*754f425fSjmmvThe interface of ATF test programs is the interface of the test 36*754f425fSjmmvprograms linked to the 37*754f425fSjmmv.Nm atf-c , 38*754f425fSjmmv.Nm atf-c++ 39*754f425fSjmmvand 40*754f425fSjmmv.Nm atf-sh 41*754f425fSjmmvlibraries provided by ATF. 42*754f425fSjmmv.Pp 43*754f425fSjmmvThe ATF interface can be understood as the mechanisms used by test programs 44*754f425fSjmmvto communicate with the runtime engine as well as the assumptions that test 45*754f425fSjmmvprograms and test cases can make while running. 46*754f425fSjmmv.Pp 47*754f425fSjmmvA test case is the most basic part of a test suite. A test case is 48*754f425fSjmmvsupposed to reproduce one, and only one, scenario. For example: if the 49*754f425fSjmmvitem under test was a function, the test case would provide a single set of 50*754f425fSjmmvinput parameters to the function and check its output; If the item under 51*754f425fSjmmvtest was a binary, the test case would provide a single set of arguments to 52*754f425fSjmmvthe program and check its behavior. 53*754f425fSjmmv.Ss Test case parts 54*754f425fSjmmvTest cases have three parts: 55*754f425fSjmmv.Bl -tag -width cleanupXX 56*754f425fSjmmv.It Head 57*754f425fSjmmvProgrammatically defines metadata properties. The head must not perform 58*754f425fSjmmvany other thing than defining such properties. In particular, no testing 59*754f425fSjmmvwhatsoever can happen in the head. (Ideally the definition of metadata 60*754f425fSjmmvproperties would not happen programmatically.) 61*754f425fSjmmv.It Body 62*754f425fSjmmvThe actual test case which performs any desired testing and reports a 63*754f425fSjmmvresult. The body is executed by the runtime engine in a deterministic way; 64*754f425fSjmmvsee the isolation section below. 65*754f425fSjmmv.It Cleanup 66*754f425fSjmmvAn optional cleanup routine. Note that the runtime engine will attempt to 67*754f425fSjmmvclean up the work directory automatically, so this routine should only be 68*754f425fSjmmvprovided in cases where the test modifies system-wide state not known by 69*754f425fSjmmvthe runtime engine. The cleanup part is executed in the same directory as 70*754f425fSjmmvthe body. However, the body and the cleanup parts 71*754f425fSjmmv.Em do not share the same process space ; 72*754f425fSjmmvthe only way to pass data around from the body to the cleanup is by means 73*754f425fSjmmvof files in the work directory. 74*754f425fSjmmv.El 75*754f425fSjmmv.Ss Metadata properties 76*754f425fSjmmvThe following test case metadata properties must be exported in the test 77*754f425fSjmmvcase list for every test case: 78*754f425fSjmmv.Bl -tag -width XX 79*754f425fSjmmv.It Va ident 80*754f425fSjmmvSingle-word string. The name of the test case. Must be unique within the 81*754f425fSjmmvtest program. 82*754f425fSjmmv.El 83*754f425fSjmmv.Pp 84*754f425fSjmmvThe following test case metadata properties may be exported in the 85*754f425fSjmmvtest case list for every test case: 86*754f425fSjmmv.Bl -tag -width XX 87*754f425fSjmmv.It Va descr 88*754f425fSjmmvMulti-word string. A textual description for the test case. Usually, 89*754f425fSjmmvproviding a descriptive identifier is better than providing a textual 90*754f425fSjmmvdescription. 91*754f425fSjmmv.It Va has.cleanup 92*754f425fSjmmvBoolean. Whether the test case defines a cleanup routine or not. 93*754f425fSjmmv.It Va require.arch 94*754f425fSjmmvWhitespace separated list of the architectures required by the test case. 95*754f425fSjmmvIf defined, the test case is skipped unless the host architecture matches 96*754f425fSjmmvany of the values defined in this property. 97*754f425fSjmmv.It Va require.config 98*754f425fSjmmvWhitespace separated list of configuration variable names. The list of 99*754f425fSjmmvconfiguration variables that must be defined. The test is skipped if any 100*754f425fSjmmvof these is missing. 101*754f425fSjmmv.It Va require.files 102*754f425fSjmmvWhitespace separated list of absolute paths to installed files. If any of 103*754f425fSjmmvthese files is not found, the test case is skipped. 104*754f425fSjmmv.It Va require.machine 105*754f425fSjmmvWhitespace separated list of the machine types required by the test case. 106*754f425fSjmmvIf defined, the test case is skipped unless the host machine type matches 107*754f425fSjmmvany of the values defined in this property. 108*754f425fSjmmv.It Va require.progs 109*754f425fSjmmvWhitespace separated list of program names (either absolute names or base 110*754f425fSjmmvnames). If any of these programs is not found, the test case is skipped. 111*754f425fSjmmv.It Va require.user 112*754f425fSjmmvEither 113*754f425fSjmmv.Sq root 114*754f425fSjmmvor 115*754f425fSjmmv.Sq unprivileged . 116*754f425fSjmmvIf 117*754f425fSjmmv.Sq root , 118*754f425fSjmmvthe test case must be run as the superuser or otherwise it is skipped. If 119*754f425fSjmmv.Sq unprivileged , 120*754f425fSjmmvthe test case must be run as an unprivileged user or else it is skipped. 121*754f425fSjmmv.It Va timeout 122*754f425fSjmmvInteger. The amount of seconds the test case can run for before it is 123*754f425fSjmmvkilled by the runtime engine. 124*754f425fSjmmv.El 125*754f425fSjmmv.Ss Configuration properties 126*754f425fSjmmvThe following properties may be defined by the runtime engine and are 127*754f425fSjmmvpropagated to the test cases: 128*754f425fSjmmv.Bl -tag -width XX 129*754f425fSjmmv.It Va unprivileged-user 130*754f425fSjmmvString, optional. Specifies the name of the user under which tests that 131*754f425fSjmmvset 132*754f425fSjmmv.Sq require.user=unprivileged 133*754f425fSjmmvare executed. 134*754f425fSjmmv.El 135*754f425fSjmmv.Ss Results 136*754f425fSjmmvA test case must always report a result by creating the results file 137*754f425fSjmmvspecified through the 138*754f425fSjmmv.Fl r 139*754f425fSjmmvflag. For convenience when running test cases without the runtime engine, 140*754f425fSjmmvthis file may point to 141*754f425fSjmmv.Pa /dev/stdout 142*754f425fSjmmvor 143*754f425fSjmmv.Pa /dev/stderr 144*754f425fSjmmvin which case the file must not be created (because the creation will 145*754f425fSjmmvfail). 146*754f425fSjmmv.Pp 147*754f425fSjmmvAside from creating the results file, the process in which the test case 148*754f425fSjmmvruns must terminate in particular ways for the test result to be considered 149*754f425fSjmmvvalid. 150*754f425fSjmmv.Pp 151*754f425fSjmmvIf the test case fails to create the test result, if the test result is 152*754f425fSjmmvcreated but contains an invalid syntax, or if the termination status of the 153*754f425fSjmmvprocess does not match the requirements of the test result, the runtime 154*754f425fSjmmvengine marks the test case as 155*754f425fSjmmv.Sq broken . 156*754f425fSjmmvNote that the 157*754f425fSjmmv.Sq broken 158*754f425fSjmmvstate is decided by the runtime engine; a test case cannot report itself as 159*754f425fSjmmv.Sq broken . 160*754f425fSjmmv.Pp 161*754f425fSjmmvThe general syntax for the results file is as follows: 162*754f425fSjmmv.Bd -literal -offset indent 163*754f425fSjmmv<status>[[(int)]: reason] 164*754f425fSjmmv.Ed 165*754f425fSjmmv.Pp 166*754f425fSjmmvThe following results are allowed: 167*754f425fSjmmv.Bl -tag -width XX 168*754f425fSjmmv.It expected_death 169*754f425fSjmmvThe process is expected to terminate either due to a clean call to 170*754f425fSjmmv.Xr exit 3 171*754f425fSjmmvor due to the reception of a signal. The contents of the file are 172*754f425fSjmmv.Sq expected_death: <reason>\\n . 173*754f425fSjmmvExample: 174*754f425fSjmmv.Sq expected_death: Calling libdofoo breaks due to bug xyz . 175*754f425fSjmmv.It expected_exit 176*754f425fSjmmvThe process is expected to terminate cleanly. The contents of the file are 177*754f425fSjmmv.Sq expected_exit: <reason> 178*754f425fSjmmvif the exit code is irrelevant or 179*754f425fSjmmv.Sq expected_exit(<exitcode>): <reason> 180*754f425fSjmmvif the process must terminate with a given exit code. Examples: 181*754f425fSjmmv.Sq expected_exit: Calling bar exits but it should not 182*754f425fSjmmvor 183*754f425fSjmmv.Sq expected_exit(123): Calling bar exits with an unexpected code . 184*754f425fSjmmv.It expected_failure 185*754f425fSjmmvThe process must exit cleanly with an 186*754f425fSjmmv.Va EXIT_SUCCESS 187*754f425fSjmmvexit code. The contents of the file are 188*754f425fSjmmv.Sq expected_failure: <reason>\\n 189*754f425fSjmmvExample: 190*754f425fSjmmv.Sq expected_failure: 2 + 2 = 3 . 191*754f425fSjmmv.It expected_signal 192*754f425fSjmmvThe process is expected to terminate due to the reception of a signal. The 193*754f425fSjmmvcontents of the file are 194*754f425fSjmmv.Sq expected_signal: <reason> 195*754f425fSjmmvif the signal number is irrelevant or 196*754f425fSjmmv.Sq expected_signal(<signalno>): <reason> 197*754f425fSjmmvif the process must terminate due to a particular signal. Examples: 198*754f425fSjmmv.Sq expected_signal: Calling bar crashes 199*754f425fSjmmvor 200*754f425fSjmmv.Sq expected_signal(1): Calling bar kills ourselves due to unhandled SIGHUP . 201*754f425fSjmmv.It expected_timeout 202*754f425fSjmmvThe process is expected to hang for longer than its 203*754f425fSjmmv.Va timeout 204*754f425fSjmmvmetadata property. Only the runtime engine can control this situation 205*754f425fSjmmvbecause the runtime engine is the one implementing the timeout 206*754f425fSjmmvfunctionality. 207*754f425fSjmmv.It failed 208*754f425fSjmmvThe process must exit cleanly with an 209*754f425fSjmmv.Va EXIT_FAILURE 210*754f425fSjmmvexit code. The contents of the file are 211*754f425fSjmmv.Sq failed: <reason>\\n . 212*754f425fSjmmvExample: 213*754f425fSjmmv.Sq failed: Failed on purpose\\n . 214*754f425fSjmmv.It passed 215*754f425fSjmmvThe process must exit cleanly with an 216*754f425fSjmmv.Va EXIT_SUCCESS 217*754f425fSjmmvexit code. The contents of the file are 218*754f425fSjmmv.Sq passed\\n . 219*754f425fSjmmv.It skipped 220*754f425fSjmmvThe process must exit cleanly with an 221*754f425fSjmmv.Va EXIT_SUCCESS 222*754f425fSjmmvexit code. The contents of the file are 223*754f425fSjmmv.Sq skipped: <reason>\\n . 224*754f425fSjmmvExample: 225*754f425fSjmmv.Sq skipped: Skipped because the foo is not present\\n . 226*754f425fSjmmv.El 227*754f425fSjmmv.Ss Isolation 228*754f425fSjmmvThe runtime engine attempts to isolate test cases from other test cases in 229*754f425fSjmmvthe same test program and from the rest of the system by performing what is 230*754f425fSjmmvcalled 231*754f425fSjmmv.Em test case isolation . 232*754f425fSjmmv.Pp 233*754f425fSjmmvWhenever the user runs a test program binary by hand (i.e. not through 234*754f425fSjmmv.Xr kyua 1 ) , 235*754f425fSjmmvthe test program will print a warning message stating that test case 236*754f425fSjmmvisolation does not work and therefore the program may cause side-effects 237*754f425fSjmmvand/or report invalid values. 238*754f425fSjmmv.Pp 239*754f425fSjmmvThe runtime engine must set the 240*754f425fSjmmv.Va __RUNNING_INSIDE_ATF_RUN 241*754f425fSjmmvenvironment variable to the magic value 242*754f425fSjmmv.Sq internal-yes-value 243*754f425fSjmmvto tell the test programs that they are being run with isolation enabled. 244*754f425fSjmmv.Pp 245*754f425fSjmmvThe test case isolation performs the following: 246*754f425fSjmmv.Bl -tag -width XX 247*754f425fSjmmv.It Process space 248*754f425fSjmmvEach test case body and cleanup routines are executed in independent 249*754f425fSjmmvprocesses. Corollary: the test case can do whatever it wants to the 250*754f425fSjmmvcurrent process (such as modifying global variables) without having to undo 251*754f425fSjmmvsuch changes. 252*754f425fSjmmv.It Process group 253*754f425fSjmmvThe test case body and cleanup are executed in their own process groups. 254*754f425fSjmmvShould they spawn any children, such children should maintain the same 255*754f425fSjmmvprocess group. This is done to allow the runtime engine to kill the whole 256*754f425fSjmmvprocess subtree once the test case finishes (or if the test case hangs). 257*754f425fSjmmv.It Work directory 258*754f425fSjmmvThe test case body and its cleanup (if any) are executed in a temporary 259*754f425fSjmmvdirectory automatically created by the runtime engine. This temporary 260*754f425fSjmmvdirectory is shared among the body and cleanup parts of a single test case 261*754f425fSjmmvbut is completely separate from the temporary directories of other tests. 262*754f425fSjmmvCorollary: the test case body and cleanup routines can write to their 263*754f425fSjmmvcurrent directory without bothering to clean any files and/or directories 264*754f425fSjmmvthey create. The runtime engine takes care to recursively delete the 265*754f425fSjmmvtemporary directories after the execution of a test case. Any file systems 266*754f425fSjmmvmounted within the temporary directory will be unmounted if possible. 267*754f425fSjmmv.It Home directory 268*754f425fSjmmvThe 269*754f425fSjmmv.Va HOME 270*754f425fSjmmvenvironment variable is set to the absolute path of the work directory. 271*754f425fSjmmv.It Umask 272*754f425fSjmmvThe value of the umask is set to 0022. 273*754f425fSjmmv.It Environment 274*754f425fSjmmvThe 275*754f425fSjmmv.Va LANG , 276*754f425fSjmmv.Va LC_ALL , 277*754f425fSjmmv.Va LC_COLLATE , 278*754f425fSjmmv.Va LC_CTYPE , 279*754f425fSjmmv.Va LC_MESSAGES , 280*754f425fSjmmv.Va LC_MONETARY , 281*754f425fSjmmv.Va LC_NUMERIC 282*754f425fSjmmvand 283*754f425fSjmmv.Va LC_TIME 284*754f425fSjmmvvariables are unset. The 285*754f425fSjmmv.Va TZ 286*754f425fSjmmvvariable is set to 287*754f425fSjmmv.Sq UTC . 288*754f425fSjmmv.It Process limits 289*754f425fSjmmvThe maximum soft core size limit is raised to its corresponding hard limit. 290*754f425fSjmmvThis is a simple, best-effort attempt at allowing test cases to dump core 291*754f425fSjmmvfor further diagnostic purposes. 292*754f425fSjmmv.El 293*754f425fSjmmv.Ss Test programs 294*754f425fSjmmvA test program is, simply put, a collection of related test cases. The 295*754f425fSjmmvtest program can be seen as a command-line dispatcher for the test cases. 296*754f425fSjmmvA test program must provide one or more test cases. If it does not contain 297*754f425fSjmmvany test case, the runtime system will report it as invalid. 298*754f425fSjmmv.Pp 299*754f425fSjmmvTest programs expose their list of test cases in a machine parseable 300*754f425fSjmmvformat. The runtime engine obtains the list of test cases to know what 301*754f425fSjmmvtests to run and to know how to set up the environment of each test prior 302*754f425fSjmmvexecution. The test program must not do any test when asked to dump its 303*754f425fSjmmvtest case list. 304*754f425fSjmmv.Pp 305*754f425fSjmmvThe generic syntax to obtain the list of test cases included in a test 306*754f425fSjmmvprogram is: 307*754f425fSjmmv.Bd -literal -offset indent 308*754f425fSjmmv<test-program> -l 309*754f425fSjmmv.Ed 310*754f425fSjmmv.Pp 311*754f425fSjmmvThe list of test cases follows the following format: 312*754f425fSjmmv.Bd -literal -offset indent 313*754f425fSjmmvLIST ::= HEADER NEWLINE TEST_CASES 314*754f425fSjmmv 315*754f425fSjmmvHEADER ::= 'Content-Type: application/X-atf-tp; version="1"' 316*754f425fSjmmvNEWLINE ::= '\\n' 317*754f425fSjmmvTEST_CASES ::= TEST_CASE | TEST_CASE NEWLINE TEST_CASES 318*754f425fSjmmv 319*754f425fSjmmvTEST_CASE ::= IDENT_PROPERTY PROPERTIES 320*754f425fSjmmvIDENT_PROPERTY ::= 'ident' DELIM STRING NEWLINE 321*754f425fSjmmvDELIM ::= ': ' 322*754f425fSjmmv 323*754f425fSjmmvPROPERTIES ::= PROPERTY | PROPERTY PROPERTIES 324*754f425fSjmmvPROPERTY ::= PROPERTY_NAME DELIM STRING NEWLINE 325*754f425fSjmmvPROPERTY_NAME ::= (see below) 326*754f425fSjmmv.Ed 327*754f425fSjmmv.Pp 328*754f425fSjmmvAn example: 329*754f425fSjmmv.Bd -literal -offset indent 330*754f425fSjmmvContent-Type: application/X-atf-tp; version="1" 331*754f425fSjmmv 332*754f425fSjmmvident: addition 333*754f425fSjmmvdescr: Tests that the addition function works 334*754f425fSjmmv 335*754f425fSjmmvident: subtraction 336*754f425fSjmmvdescr: Tests that the subtraction function works 337*754f425fSjmmv 338*754f425fSjmmvident: remove 339*754f425fSjmmvdescr: Tests removing files 340*754f425fSjmmvrequire.root: true 341*754f425fSjmmvtimeout: 50 342*754f425fSjmmvhas.cleanup: true 343*754f425fSjmmv.Ed 344*754f425fSjmmv.Pp 345*754f425fSjmmvThe syntax to run a test case body part is: 346*754f425fSjmmv.Bd -literal -offset indent 347*754f425fSjmmv<test-program> [-r resfile] [-s srcdir] [-v var=value]* <test-case>[:body] 348*754f425fSjmmv.Ed 349*754f425fSjmmv.Pp 350*754f425fSjmmvThis must run the test case body 351*754f425fSjmmv.Dq as is , 352*754f425fSjmmvwithout any attempt of isolating it from the rest of the system. It is the 353*754f425fSjmmvresponsibility of the runtime engine to do such isolation. 354*754f425fSjmmv.Pp 355*754f425fSjmmvThe runtime engine always passes the path of a nonexistent file to 356*754f425fSjmmv.Fl r , 357*754f425fSjmmvwhich must be created by the test case; and always passes an absolute path 358*754f425fSjmmvto the 359*754f425fSjmmv.Fl s 360*754f425fSjmmvflag pointing to the directory containing the test program executable. 361*754f425fSjmmv.Pp 362*754f425fSjmmvThe runtime engine shall pass any configuration variables it wants through 363*754f425fSjmmvthe 364*754f425fSjmmv.Fl v 365*754f425fSjmmvflag, and these can be later inspected by the test case at will. 366*754f425fSjmmv.Pp 367*754f425fSjmmvA note to users: if you run the test case by hand (not through 368*754f425fSjmmv.Xr kyua 1 nor 369*754f425fSjmmv.Xr atf-run 1 ) 370*754f425fSjmmvfrom the command line, none of the isolation features described in the 371*754f425fSjmmvisolation section apply. This means that the test case can (and probably 372*754f425fSjmmvwill) write to the current directory and leave garbage behind. Also, given 373*754f425fSjmmvthat the test case is executed without e.g. clearing the environment, the 374*754f425fSjmmvresults of the test case may differ from those obtained when running the 375*754f425fSjmmvtest case inside the runtime engine. 376*754f425fSjmmv.Em Only use this for debugging purposes 377*754f425fSjmmv(i.e. to run the test case code under GDB). 378*754f425fSjmmv.Pp 379*754f425fSjmmvThe syntax to run a test case cleanup part is: 380*754f425fSjmmv.Bd -literal -offset indent 381*754f425fSjmmv<test-program> [-s srcdir] [-v var=value]* <test-case>:cleanup 382*754f425fSjmmv.Ed 383*754f425fSjmmv.Pp 384*754f425fSjmmvThis can only be performed if and only if the test case sets the 385*754f425fSjmmv.Va has.cleanup 386*754f425fSjmmvproperty to true. Otherwise the behavior of executing the cleanup part is 387*754f425fSjmmvundefined. 388*754f425fSjmmv.Pp 389*754f425fSjmmvThe same rules for 390*754f425fSjmmv.Fl s 391*754f425fSjmmvand 392*754f425fSjmmv.Fl v 393*754f425fSjmmvapply as to when running the body. 394*754f425fSjmmv.Pp 395*754f425fSjmmvThe cleanup part must be executed in the same directory as the body but in 396*754f425fSjmmva separate process space. The only way for test cases to transfer state 397*754f425fSjmmv(if any) from the body to the cleanup routine is by means of files in the 398*754f425fSjmmvcurrent directory. 399*754f425fSjmmv.Pp 400*754f425fSjmmvThe cleanup part does not have to worry about deleting temporary files 401*754f425fSjmmvcreated in the current directory. The runtime engine does this 402*754f425fSjmmvautomatically. 403*754f425fSjmmv.Sh SEE ALSO 404*754f425fSjmmv.Xr kyua-test 1 , 405*754f425fSjmmv.Xr kyuafile 5 406