1*0677dfd1SJulio Merino.\" Copyright (c) 2008 The NetBSD Foundation, Inc. 2*0677dfd1SJulio Merino.\" All rights reserved. 3*0677dfd1SJulio Merino.\" 4*0677dfd1SJulio Merino.\" Redistribution and use in source and binary forms, with or without 5*0677dfd1SJulio Merino.\" modification, are permitted provided that the following conditions 6*0677dfd1SJulio Merino.\" are met: 7*0677dfd1SJulio Merino.\" 1. Redistributions of source code must retain the above copyright 8*0677dfd1SJulio Merino.\" notice, this list of conditions and the following disclaimer. 9*0677dfd1SJulio Merino.\" 2. Redistributions in binary form must reproduce the above copyright 10*0677dfd1SJulio Merino.\" notice, this list of conditions and the following disclaimer in the 11*0677dfd1SJulio Merino.\" documentation and/or other materials provided with the distribution. 12*0677dfd1SJulio Merino.\" 13*0677dfd1SJulio Merino.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14*0677dfd1SJulio Merino.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15*0677dfd1SJulio Merino.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16*0677dfd1SJulio Merino.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17*0677dfd1SJulio Merino.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18*0677dfd1SJulio Merino.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*0677dfd1SJulio Merino.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20*0677dfd1SJulio Merino.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21*0677dfd1SJulio Merino.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22*0677dfd1SJulio Merino.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23*0677dfd1SJulio Merino.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24*0677dfd1SJulio Merino.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*0677dfd1SJulio Merino.Dd October 13, 2014 26*0677dfd1SJulio Merino.Dt ATF-SH 3 27*0677dfd1SJulio Merino.Os 28*0677dfd1SJulio Merino.Sh NAME 29*0677dfd1SJulio Merino.Nm atf_add_test_case , 30*0677dfd1SJulio Merino.Nm atf_check , 31*0677dfd1SJulio Merino.Nm atf_check_equal , 32*0677dfd1SJulio Merino.Nm atf_config_get , 33*0677dfd1SJulio Merino.Nm atf_config_has , 34*0677dfd1SJulio Merino.Nm atf_expect_death , 35*0677dfd1SJulio Merino.Nm atf_expect_exit , 36*0677dfd1SJulio Merino.Nm atf_expect_fail , 37*0677dfd1SJulio Merino.Nm atf_expect_pass , 38*0677dfd1SJulio Merino.Nm atf_expect_signal , 39*0677dfd1SJulio Merino.Nm atf_expect_timeout , 40*0677dfd1SJulio Merino.Nm atf_fail , 41*0677dfd1SJulio Merino.Nm atf_get , 42*0677dfd1SJulio Merino.Nm atf_get_srcdir , 43*0677dfd1SJulio Merino.Nm atf_pass , 44*0677dfd1SJulio Merino.Nm atf_require_prog , 45*0677dfd1SJulio Merino.Nm atf_set , 46*0677dfd1SJulio Merino.Nm atf_skip , 47*0677dfd1SJulio Merino.Nm atf_test_case 48*0677dfd1SJulio Merino.Nd POSIX shell API to write ATF-based test programs 49*0677dfd1SJulio Merino.Sh SYNOPSIS 50*0677dfd1SJulio Merino.Nm atf_add_test_case 51*0677dfd1SJulio Merino.Qq name 52*0677dfd1SJulio Merino.Nm atf_check 53*0677dfd1SJulio Merino.Qq command 54*0677dfd1SJulio Merino.Nm atf_check_equal 55*0677dfd1SJulio Merino.Qq expected_expression 56*0677dfd1SJulio Merino.Qq actual_expression 57*0677dfd1SJulio Merino.Nm atf_config_get 58*0677dfd1SJulio Merino.Qq var_name 59*0677dfd1SJulio Merino.Nm atf_config_has 60*0677dfd1SJulio Merino.Qq var_name 61*0677dfd1SJulio Merino.Nm atf_expect_death 62*0677dfd1SJulio Merino.Qq reason 63*0677dfd1SJulio Merino.Qq ... 64*0677dfd1SJulio Merino.Nm atf_expect_exit 65*0677dfd1SJulio Merino.Qq exitcode 66*0677dfd1SJulio Merino.Qq reason 67*0677dfd1SJulio Merino.Qq ... 68*0677dfd1SJulio Merino.Nm atf_expect_fail 69*0677dfd1SJulio Merino.Qq reason 70*0677dfd1SJulio Merino.Qq ... 71*0677dfd1SJulio Merino.Nm atf_expect_pass 72*0677dfd1SJulio Merino.Qq 73*0677dfd1SJulio Merino.Nm atf_expect_signal 74*0677dfd1SJulio Merino.Qq signo 75*0677dfd1SJulio Merino.Qq reason 76*0677dfd1SJulio Merino.Qq ... 77*0677dfd1SJulio Merino.Nm atf_expect_timeout 78*0677dfd1SJulio Merino.Qq reason 79*0677dfd1SJulio Merino.Qq ... 80*0677dfd1SJulio Merino.Nm atf_fail 81*0677dfd1SJulio Merino.Qq reason 82*0677dfd1SJulio Merino.Nm atf_get 83*0677dfd1SJulio Merino.Qq var_name 84*0677dfd1SJulio Merino.Nm atf_get_srcdir 85*0677dfd1SJulio Merino.Nm atf_pass 86*0677dfd1SJulio Merino.Nm atf_require_prog 87*0677dfd1SJulio Merino.Qq prog_name 88*0677dfd1SJulio Merino.Nm atf_set 89*0677dfd1SJulio Merino.Qq var_name 90*0677dfd1SJulio Merino.Qq value 91*0677dfd1SJulio Merino.Nm atf_skip 92*0677dfd1SJulio Merino.Qq reason 93*0677dfd1SJulio Merino.Nm atf_test_case 94*0677dfd1SJulio Merino.Qq name 95*0677dfd1SJulio Merino.Qq cleanup 96*0677dfd1SJulio Merino.Sh DESCRIPTION 97*0677dfd1SJulio MerinoATF 98*0677dfd1SJulio Merinoprovides a simple but powerful interface to easily write test programs in 99*0677dfd1SJulio Merinothe POSIX shell language. 100*0677dfd1SJulio MerinoThese are extremely helpful given that they are trivial to write due to the 101*0677dfd1SJulio Merinolanguage simplicity and the great deal of available external tools, so they 102*0677dfd1SJulio Merinoare often ideal to test other applications at the user level. 103*0677dfd1SJulio Merino.Pp 104*0677dfd1SJulio MerinoTest programs written using this library must be run using the 105*0677dfd1SJulio Merino.Xr atf-sh 1 106*0677dfd1SJulio Merinointerpreter by putting the following on their very first line: 107*0677dfd1SJulio Merino.Bd -literal -offset indent 108*0677dfd1SJulio Merino#! /usr/bin/env atf-sh 109*0677dfd1SJulio Merino.Ed 110*0677dfd1SJulio Merino.Pp 111*0677dfd1SJulio MerinoShell-based test programs always follow this template: 112*0677dfd1SJulio Merino.Bd -literal -offset indent 113*0677dfd1SJulio Merinoatf_test_case tc1 114*0677dfd1SJulio Merinotc1_head() { 115*0677dfd1SJulio Merino ... first test case's header ... 116*0677dfd1SJulio Merino} 117*0677dfd1SJulio Merinotc1_body() { 118*0677dfd1SJulio Merino ... first test case's body ... 119*0677dfd1SJulio Merino} 120*0677dfd1SJulio Merino 121*0677dfd1SJulio Merinoatf_test_case tc2 cleanup 122*0677dfd1SJulio Merinotc2_head() { 123*0677dfd1SJulio Merino ... second test case's header ... 124*0677dfd1SJulio Merino} 125*0677dfd1SJulio Merinotc2_body() { 126*0677dfd1SJulio Merino ... second test case's body ... 127*0677dfd1SJulio Merino} 128*0677dfd1SJulio Merinotc2_cleanup() { 129*0677dfd1SJulio Merino ... second test case's cleanup ... 130*0677dfd1SJulio Merino} 131*0677dfd1SJulio Merino 132*0677dfd1SJulio Merino.Ns ... additional test cases ... 133*0677dfd1SJulio Merino 134*0677dfd1SJulio Merinoatf_init_test_cases() { 135*0677dfd1SJulio Merino atf_add_test_case tc1 136*0677dfd1SJulio Merino atf_add_test_case tc2 137*0677dfd1SJulio Merino ... add additional test cases ... 138*0677dfd1SJulio Merino} 139*0677dfd1SJulio Merino.Ed 140*0677dfd1SJulio Merino.Ss Definition of test cases 141*0677dfd1SJulio MerinoTest cases have an identifier and are composed of three different parts: 142*0677dfd1SJulio Merinothe header, the body and an optional cleanup routine, all of which are 143*0677dfd1SJulio Merinodescribed in 144*0677dfd1SJulio Merino.Xr atf-test-case 4 . 145*0677dfd1SJulio MerinoTo define test cases, one can use the 146*0677dfd1SJulio Merino.Nm atf_test_case 147*0677dfd1SJulio Merinofunction, which takes a first parameter specifiying the test case's 148*0677dfd1SJulio Merinoname and instructs the library to set things up to accept it as a valid 149*0677dfd1SJulio Merinotest case. 150*0677dfd1SJulio MerinoThe second parameter is optional and, if provided, must be 151*0677dfd1SJulio Merino.Sq cleanup ; 152*0677dfd1SJulio Merinoproviding this parameter allows defining a cleanup routine for the test 153*0677dfd1SJulio Merinocase. 154*0677dfd1SJulio MerinoIt is important to note that this function 155*0677dfd1SJulio Merino.Em does not 156*0677dfd1SJulio Merinoset the test case up for execution when the program is run. 157*0677dfd1SJulio MerinoIn order to do so, a later registration is needed through the 158*0677dfd1SJulio Merino.Nm atf_add_test_case 159*0677dfd1SJulio Merinofunction detailed in 160*0677dfd1SJulio Merino.Sx Program initialization . 161*0677dfd1SJulio Merino.Pp 162*0677dfd1SJulio MerinoLater on, one must define the three parts of the body by providing two 163*0677dfd1SJulio Merinoor three functions (remember that the cleanup routine is optional). 164*0677dfd1SJulio MerinoThese functions are named after the test case's identifier, and are 165*0677dfd1SJulio Merino.Nm \*(Ltid\*(Gt_head , 166*0677dfd1SJulio Merino.Nm \*(Ltid\*(Gt_body 167*0677dfd1SJulio Merinoand 168*0677dfd1SJulio Merino.Nm \*(Ltid\*(Gt_cleanup . 169*0677dfd1SJulio MerinoNone of these take parameters when executed. 170*0677dfd1SJulio Merino.Ss Program initialization 171*0677dfd1SJulio MerinoThe test program must define an 172*0677dfd1SJulio Merino.Nm atf_init_test_cases 173*0677dfd1SJulio Merinofunction, which is in charge of registering the test cases that will be 174*0677dfd1SJulio Merinoexecuted at run time by using the 175*0677dfd1SJulio Merino.Nm atf_add_test_case 176*0677dfd1SJulio Merinofunction, which takes the name of a test case as its single parameter. 177*0677dfd1SJulio MerinoThis main function should not do anything else, except maybe sourcing 178*0677dfd1SJulio Merinoauxiliary source files that define extra variables and functions. 179*0677dfd1SJulio Merino.Ss Configuration variables 180*0677dfd1SJulio MerinoThe test case has read-only access to the current configuration variables 181*0677dfd1SJulio Merinothrough the 182*0677dfd1SJulio Merino.Nm atf_config_has 183*0677dfd1SJulio Merinoand 184*0677dfd1SJulio Merino.Nm atf_config_get 185*0677dfd1SJulio Merinomethods. 186*0677dfd1SJulio MerinoThe former takes a single parameter specifying a variable name and returns 187*0677dfd1SJulio Merinoa boolean indicating whether the variable is defined or not. 188*0677dfd1SJulio MerinoThe latter can take one or two parameters. 189*0677dfd1SJulio MerinoIf it takes only one, it specifies the variable from which to get the 190*0677dfd1SJulio Merinovalue, and this variable must be defined. 191*0677dfd1SJulio MerinoIf it takes two, the second one specifies a default value to be returned 192*0677dfd1SJulio Merinoif the variable is not available. 193*0677dfd1SJulio Merino.Ss Access to the source directory 194*0677dfd1SJulio MerinoIt is possible to get the path to the test case's source directory from 195*0677dfd1SJulio Merinoanywhere in the test program by using the 196*0677dfd1SJulio Merino.Nm atf_get_srcdir 197*0677dfd1SJulio Merinofunction. 198*0677dfd1SJulio MerinoIt is interesting to note that this can be used inside 199*0677dfd1SJulio Merino.Nm atf_init_test_cases 200*0677dfd1SJulio Merinoto silently include additional helper files from the source directory. 201*0677dfd1SJulio Merino.Ss Requiring programs 202*0677dfd1SJulio MerinoAside from the 203*0677dfd1SJulio Merino.Va require.progs 204*0677dfd1SJulio Merinometa-data variable available in the header only, one can also check for 205*0677dfd1SJulio Merinoadditional programs in the test case's body by using the 206*0677dfd1SJulio Merino.Nm atf_require_prog 207*0677dfd1SJulio Merinofunction, which takes the base name or full path of a single binary. 208*0677dfd1SJulio MerinoRelative paths are forbidden. 209*0677dfd1SJulio MerinoIf it is not found, the test case will be automatically skipped. 210*0677dfd1SJulio Merino.Ss Test case finalization 211*0677dfd1SJulio MerinoThe test case finalizes either when the body reaches its end, at which 212*0677dfd1SJulio Merinopoint the test is assumed to have 213*0677dfd1SJulio Merino.Em passed , 214*0677dfd1SJulio Merinoor at any explicit call to 215*0677dfd1SJulio Merino.Nm atf_pass , 216*0677dfd1SJulio Merino.Nm atf_fail 217*0677dfd1SJulio Merinoor 218*0677dfd1SJulio Merino.Nm atf_skip . 219*0677dfd1SJulio MerinoThese three functions terminate the execution of the test case immediately. 220*0677dfd1SJulio MerinoThe cleanup routine will be processed afterwards in a completely automated 221*0677dfd1SJulio Merinoway, regardless of the test case's termination reason. 222*0677dfd1SJulio Merino.Pp 223*0677dfd1SJulio Merino.Nm atf_pass 224*0677dfd1SJulio Merinodoes not take any parameters. 225*0677dfd1SJulio Merino.Nm atf_fail 226*0677dfd1SJulio Merinoand 227*0677dfd1SJulio Merino.Nm atf_skip 228*0677dfd1SJulio Merinotake a single string parameter that describes why the test case failed or 229*0677dfd1SJulio Merinowas skipped, respectively. 230*0677dfd1SJulio MerinoIt is very important to provide a clear error message in both cases so that 231*0677dfd1SJulio Merinothe user can quickly know why the test did not pass. 232*0677dfd1SJulio Merino.Ss Expectations 233*0677dfd1SJulio MerinoEverything explained in the previous section changes when the test case 234*0677dfd1SJulio Merinoexpectations are redefined by the programmer. 235*0677dfd1SJulio Merino.Pp 236*0677dfd1SJulio MerinoEach test case has an internal state called 237*0677dfd1SJulio Merino.Sq expect 238*0677dfd1SJulio Merinothat describes what the test case expectations are at any point in time. 239*0677dfd1SJulio MerinoThe value of this property can change during execution by any of: 240*0677dfd1SJulio Merino.Bl -tag -width indent 241*0677dfd1SJulio Merino.It Nm atf_expect_death Qo reason Qc Qo ... Qc 242*0677dfd1SJulio MerinoExpects the test case to exit prematurely regardless of the nature of the 243*0677dfd1SJulio Merinoexit. 244*0677dfd1SJulio Merino.It Nm atf_expect_exit Qo exitcode Qc Qo reason Qc Qo ... Qc 245*0677dfd1SJulio MerinoExpects the test case to exit cleanly. 246*0677dfd1SJulio MerinoIf 247*0677dfd1SJulio Merino.Va exitcode 248*0677dfd1SJulio Merinois not 249*0677dfd1SJulio Merino.Sq -1 , 250*0677dfd1SJulio Merinothe runtime engine will validate that the exit code of the test case 251*0677dfd1SJulio Merinomatches the one provided in this call. 252*0677dfd1SJulio MerinoOtherwise, the exact value will be ignored. 253*0677dfd1SJulio Merino.It Nm atf_expect_fail Qo reason Qc 254*0677dfd1SJulio MerinoAny failure raised in this mode is recorded, but such failures do not report 255*0677dfd1SJulio Merinothe test case as failed; instead, the test case finalizes cleanly and is 256*0677dfd1SJulio Merinoreported as 257*0677dfd1SJulio Merino.Sq expected failure ; 258*0677dfd1SJulio Merinothis report includes the provided 259*0677dfd1SJulio Merino.Fa reason 260*0677dfd1SJulio Merinoas part of it. 261*0677dfd1SJulio MerinoIf no error is raised while running in this mode, then the test case is 262*0677dfd1SJulio Merinoreported as 263*0677dfd1SJulio Merino.Sq failed . 264*0677dfd1SJulio Merino.Pp 265*0677dfd1SJulio MerinoThis mode is useful to reproduce actual known bugs in tests. 266*0677dfd1SJulio MerinoWhenever the developer fixes the bug later on, the test case will start 267*0677dfd1SJulio Merinoreporting a failure, signaling the developer that the test case must be 268*0677dfd1SJulio Merinoadjusted to the new conditions. 269*0677dfd1SJulio MerinoIn this situation, it is useful, for example, to set 270*0677dfd1SJulio Merino.Fa reason 271*0677dfd1SJulio Merinoas the bug number for tracking purposes. 272*0677dfd1SJulio Merino.It Nm atf_expect_pass 273*0677dfd1SJulio MerinoThis is the normal mode of execution. 274*0677dfd1SJulio MerinoIn this mode, any failure is reported as such to the user and the test case 275*0677dfd1SJulio Merinois marked as 276*0677dfd1SJulio Merino.Sq failed . 277*0677dfd1SJulio Merino.It Nm atf_expect_signal Qo signo Qc Qo reason Qc Qo ... Qc 278*0677dfd1SJulio MerinoExpects the test case to terminate due to the reception of a signal. 279*0677dfd1SJulio MerinoIf 280*0677dfd1SJulio Merino.Va signo 281*0677dfd1SJulio Merinois not 282*0677dfd1SJulio Merino.Sq -1 , 283*0677dfd1SJulio Merinothe runtime engine will validate that the signal that terminated the test 284*0677dfd1SJulio Merinocase matches the one provided in this call. 285*0677dfd1SJulio MerinoOtherwise, the exact value will be ignored. 286*0677dfd1SJulio Merino.It Nm atf_expect_timeout Qo reason Qc Qo ... Qc 287*0677dfd1SJulio MerinoExpects the test case to execute for longer than its timeout. 288*0677dfd1SJulio Merino.El 289*0677dfd1SJulio Merino.Ss Helper functions for common checks 290*0677dfd1SJulio Merino.Bl -tag -width indent 291*0677dfd1SJulio Merino.It Nm atf_check Qo [options] Qc Qo command Qc Qo [args] Qc 292*0677dfd1SJulio MerinoExecutes a command, performs checks on its exit code and its output, and 293*0677dfd1SJulio Merinofails the test case if any of the checks is not successful. 294*0677dfd1SJulio MerinoThis function is particularly useful in integration tests that verify the 295*0677dfd1SJulio Merinocorrect functioning of a binary. 296*0677dfd1SJulio Merino.Pp 297*0677dfd1SJulio MerinoInternally, this function is just a wrapper over the 298*0677dfd1SJulio Merino.Xr atf-check 1 299*0677dfd1SJulio Merinotool (whose manual page provides all details on the calling syntax). 300*0677dfd1SJulio MerinoYou should always use the 301*0677dfd1SJulio Merino.Nm atf_check 302*0677dfd1SJulio Merinofunction instead of the 303*0677dfd1SJulio Merino.Xr atf-check 1 304*0677dfd1SJulio Merinotool in your scripts; the latter is not even in the path. 305*0677dfd1SJulio Merino.It Nm atf_check_equal Qo expected_expression Qc Qo actual_expression Qc 306*0677dfd1SJulio MerinoThis function takes two expressions, evaluates them and, if their 307*0677dfd1SJulio Merinoresults differ, aborts the test case with an appropriate failure message. 308*0677dfd1SJulio MerinoThe common style is to put the expected value in the first parameter and the 309*0677dfd1SJulio Merinoactual value in the second parameter. 310*0677dfd1SJulio Merino.El 311*0677dfd1SJulio Merino.Sh EXAMPLES 312*0677dfd1SJulio MerinoThe following shows a complete test program with a single test case that 313*0677dfd1SJulio Merinovalidates the addition operator: 314*0677dfd1SJulio Merino.Bd -literal -offset indent 315*0677dfd1SJulio Merinoatf_test_case addition 316*0677dfd1SJulio Merinoaddition_head() { 317*0677dfd1SJulio Merino atf_set "descr" "Sample tests for the addition operator" 318*0677dfd1SJulio Merino} 319*0677dfd1SJulio Merinoaddition_body() { 320*0677dfd1SJulio Merino atf_check_equal 0 $((0 + 0)) 321*0677dfd1SJulio Merino atf_check_equal 1 $((0 + 1)) 322*0677dfd1SJulio Merino atf_check_equal 1 $((1 + 0)) 323*0677dfd1SJulio Merino 324*0677dfd1SJulio Merino atf_check_equal 2 $((1 + 1)) 325*0677dfd1SJulio Merino 326*0677dfd1SJulio Merino atf_check_equal 300 $((100 + 200)) 327*0677dfd1SJulio Merino} 328*0677dfd1SJulio Merino 329*0677dfd1SJulio Merinoatf_init_test_cases() { 330*0677dfd1SJulio Merino atf_add_test_case addition 331*0677dfd1SJulio Merino} 332*0677dfd1SJulio Merino.Ed 333*0677dfd1SJulio Merino.Pp 334*0677dfd1SJulio MerinoThis other example shows how to include a file with extra helper functions 335*0677dfd1SJulio Merinoin the test program: 336*0677dfd1SJulio Merino.Bd -literal -offset indent 337*0677dfd1SJulio Merino.Ns ... definition of test cases ... 338*0677dfd1SJulio Merino 339*0677dfd1SJulio Merinoatf_init_test_cases() { 340*0677dfd1SJulio Merino . $(atf_get_srcdir)/helper_functions.sh 341*0677dfd1SJulio Merino 342*0677dfd1SJulio Merino atf_add_test_case foo1 343*0677dfd1SJulio Merino atf_add_test_case foo2 344*0677dfd1SJulio Merino} 345*0677dfd1SJulio Merino.Ed 346*0677dfd1SJulio Merino.Pp 347*0677dfd1SJulio MerinoThis example demonstrates the use of the very useful 348*0677dfd1SJulio Merino.Nm atf_check 349*0677dfd1SJulio Merinofunction: 350*0677dfd1SJulio Merino.Bd -literal -offset indent 351*0677dfd1SJulio Merino# Check for silent output 352*0677dfd1SJulio Merinoatf_check -s exit:0 -o empty -e empty 'true' 353*0677dfd1SJulio Merino 354*0677dfd1SJulio Merino# Check for silent output and failure 355*0677dfd1SJulio Merinoatf_check -s exit:1 -o empty -e empty 'false' 356*0677dfd1SJulio Merino 357*0677dfd1SJulio Merino# Check for known stdout and silent stderr 358*0677dfd1SJulio Merinoecho foo >expout 359*0677dfd1SJulio Merinoatf_check -s exit:0 -o file:expout -e empty 'echo foo' 360*0677dfd1SJulio Merino 361*0677dfd1SJulio Merino# Generate a file for later inspection 362*0677dfd1SJulio Merinoatf_check -s exit:0 -o save:stdout -e empty 'ls' 363*0677dfd1SJulio Merinogrep foo ls || atf_fail "foo file not found in listing" 364*0677dfd1SJulio Merino 365*0677dfd1SJulio Merino# Or just do the match along the way 366*0677dfd1SJulio Merinoatf_check -s exit:0 -o match:"^foo$" -e empty 'ls' 367*0677dfd1SJulio Merino.Ed 368*0677dfd1SJulio Merino.Sh SEE ALSO 369*0677dfd1SJulio Merino.Xr atf-check 1 , 370*0677dfd1SJulio Merino.Xr atf-sh 1 , 371*0677dfd1SJulio Merino.Xr atf-test-program 1 , 372*0677dfd1SJulio Merino.Xr atf-test-case 4 373