xref: /netbsd-src/external/bsd/atf/dist/atf-sh/atf-sh-api.3 (revision 7f0357d3ca8d67ce8c4a975dd152ea499195e78e)
1.\"
2.\" Automated Testing Framework (atf)
3.\"
4.\" Copyright (c) 2008 The NetBSD Foundation, Inc.
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in the
14.\"    documentation and/or other materials provided with the distribution.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.\"
29.Dd May 15, 2017
30.Dt ATF-SH-API 3
31.Os
32.Sh NAME
33.Nm atf_add_test_case ,
34.Nm atf_check ,
35.Nm atf_check_equal ,
36.Nm atf_config_get ,
37.Nm atf_config_has ,
38.Nm atf_expect_death ,
39.Nm atf_expect_exit ,
40.Nm atf_expect_fail ,
41.Nm atf_expect_pass ,
42.Nm atf_expect_signal ,
43.Nm atf_expect_timeout ,
44.Nm atf_fail ,
45.Nm atf_get ,
46.Nm atf_get_srcdir ,
47.Nm atf_pass ,
48.Nm atf_require_prog ,
49.Nm atf_set ,
50.Nm atf_skip ,
51.Nm atf_test_case
52.Nd POSIX shell API to write ATF-based test programs
53.Sh SYNOPSIS
54.Ic atf_add_test_case Dq name
55.br
56.Ic atf_check Dq command
57.br
58.Ic atf_check_equal Do expr1 Dc Dq expr2
59.br
60.Ic atf_config_get Dq var_name
61.br
62.Ic atf_config_has Dq var_name
63.br
64.Ic atf_expect_death Do reason Dc Dq \&...
65.br
66.Ic atf_expect_exit Do exitcode Dc Do reason Dc Dq \&...
67.br
68.Ic atf_expect_fail Do reason Dc Dq \&...
69.br
70.Ic atf_expect_pass
71.br
72.Ic atf_expect_signal Do signo Dc Do reason Dc Dq \&...
73.br
74.Ic atf_expect_timeout Do reason Dc Dq \&...
75.br
76.Ic atf_fail Dq reason
77.br
78.Ic atf_get Dq var_name
79.br
80.Ic atf_get_srcdir
81.br
82.Ic atf_pass
83.br
84.Ic atf_require_prog Dq prog_name
85.br
86.Ic atf_set Do var_name Dc Dq value
87.br
88.Ic atf_skip Dq reason
89.br
90.Ic atf_test_case Do name Dc Dq cleanup
91.br
92.Sh DESCRIPTION
93ATF
94provides a simple but powerful interface to easily write test programs in
95the POSIX shell language.
96These are extremely helpful given that they are trivial to write due to the
97language simplicity and the great deal of available external tools, so they
98are often ideal to test other applications at the user level.
99.Pp
100Test programs written using this library must be run using the
101.Xr atf-sh 1
102interpreter by putting the following on their very first line:
103.Bd -literal -offset indent
104#! /usr/bin/env atf-sh
105.Ed
106.Pp
107Shell-based test programs always follow this template:
108.Bd -literal -offset indent
109atf_test_case tc1
110tc1_head() {
111    ... first test case's header ...
112}
113tc1_body() {
114    ... first test case's body ...
115}
116
117atf_test_case tc2 cleanup
118tc2_head() {
119    ... second test case's header ...
120}
121tc2_body() {
122    ... second test case's body ...
123}
124tc2_cleanup() {
125    ... second test case's cleanup ...
126}
127
128.Ns ... additional test cases ...
129
130atf_init_test_cases() {
131    atf_add_test_case tc1
132    atf_add_test_case tc2
133    ... add additional test cases ...
134}
135.Ed
136.Pp
137All of these functions are required to return with an exit-status of
138zero, or ATF will determine that the test is faulty.
139In particular, this means that none may end with a conditional like:
140.Bd -literal -offset indent
141atf_sh_function() {
142    ... appropriate code here ...
143    condition-test && {
144	... more code here ...
145    }
146}
147.Ed
148.Pp
149as if condition-test fails
150the return code from atf_sh_function will not be 0.
151This can be corrected by adding
152.Bd -literal -offset indent
153    return 0
154.Ed
155.Pp
156before the end of the function, or by writing it as
157.Bd -literal -offset indent
158atf_sh_function() {
159    ... appropriate code here ...
160    if condition-test
161    then
162	... more code here ...
163    fi
164}
165.Ed
166.Ss Definition of test cases
167Test cases have an identifier and are composed of three different parts:
168the header, the body and an optional cleanup routine, all of which are
169described in
170.Xr atf-test-case 4 .
171To define test cases, one can use the
172.Ic atf_test_case
173function, which takes a first parameter specifiying the test case's
174name and instructs the library to set things up to accept it as a valid
175test case.
176The second parameter is optional and, if provided, must be
177.Sq cleanup ;
178providing this parameter allows defining a cleanup routine for the test
179case.
180It is important to note that this function
181.Em does not
182set the test case up for execution when the program is run.
183In order to do so, a later registration is needed through the
184.Ic atf_add_test_case
185function detailed in
186.Sx Program initialization .
187.Pp
188Later on, one must define the three parts of the body by providing two
189or three functions (remember that the cleanup routine is optional).
190These functions are named after the test case's identifier, and are
191.Ic <id>_head ,
192.Ic <id>_body
193and
194.Ic <id>_cleanup.
195None of these take parameters when executed.
196.Ss Program initialization
197The test program must define an
198.Ic atf_init_test_cases
199function, which is in charge of registering the test cases that will be
200executed at run time by using the
201.Ic atf_add_test_case
202function, which takes the name of a test case as its single parameter.
203This main function should not do anything else, except maybe sourcing
204auxiliary source files that define extra variables and functions,
205or perhaps running simple tests to determine which test cases to add.
206.Ss Configuration variables
207The test case has read-only access to the current configuration variables
208through the
209.Ic atf_config_has
210and
211.Ic atf_config_get
212methods.
213The former takes a single parameter specifying a variable name and returns
214a boolean indicating whether the variable is defined or not.
215The latter can take one or two parameters.
216If it takes only one, it specifies the variable from which to get the
217value, and this variable must be defined.
218If it takes two, the second one specifies a default value to be returned
219if the variable is not available.
220.Ss Access to the source directory
221It is possible to get the path to the test case's source directory from
222anywhere in the test program by using the
223.Ic atf_get_srcdir
224function.
225It is interesting to note that this can be used inside
226.Ic atf_init_test_cases
227to silently include additional helper files from the source directory.
228.Ss Requiring programs
229Aside from the
230.Va require.progs
231meta-data variable available in the header only, one can also check for
232additional programs in the test case's body by using the
233.Ic atf_require_prog
234function, which takes the base name or full path of a single binary.
235Relative paths are forbidden.
236If it is not found, the test case will be automatically skipped.
237.Ss Test case finalization
238The test case finalizes either when the body reaches its end, at which
239point the test is assumed to have
240.Em passed ,
241or at any explicit call to
242.Ic atf_pass ,
243.Ic atf_fail
244.Ic atf_skip .
245These three functions terminate the execution of the test case immediately.
246The cleanup routine will be processed afterwards in a completely automated
247way, regardless of the test case's termination reason.
248.Pp
249.Fn atf_pass
250does not take any parameters.
251.Fn atf_fail
252and
253.Fn atf_skip
254take a single string parameter that describes why the test case failed or
255was skipped, respectively.
256It is very important to provide a clear error message in both cases so that
257the user can quickly know why the test did not pass.
258This message must be a single line (no embedded newline characers.)
259.Ss Expectations
260Everything explained in the previous section changes when the test case
261expectations are redefined by the programmer.
262.Pp
263Each test case has an internal state called
264.Sq expect
265that describes what the test case expectations are at any point in time.
266The value of this property can change during execution by any of:
267.Bl -tag -width indent
268.It Ic atf_expect_death Do reason Dc Dq \&...
269Expects the test case to exit prematurely regardless of the nature of the
270exit.
271.It Ic atf_expect_exit Do exitcode Dc Do reason Dc Dq \&...
272Expects the test case to exit cleanly.
273If
274.Va exitcode
275is not
276.Sq \-1 ,
277.Xr atf-run 1
278will validate that the exit code of the test case matches the one provided
279in this call.
280Otherwise, the exact value will be ignored.
281.It Ic atf_expect_fail Dq reason
282Any failure raised in this mode is recorded, but such failures do not report
283the test case as failed; instead, the test case finalizes cleanly and is
284reported as
285.Sq expected failure ;
286this report includes the provided
287.Fa reason
288as part of it.
289If no error is raised while running in this mode, then the test case is
290reported as
291.Sq failed .
292.Pp
293This mode is useful to reproduce actual known bugs in tests.
294Whenever the developer fixes the bug later on, the test case will start
295reporting a failure, signaling the developer that the test case must be
296adjusted to the new conditions.
297In this situation, it is useful, for example, to set
298.Va reason
299as the bug number for tracking purposes.
300.It Ic atf_expect_pass
301This is the normal mode of execution.
302In this mode, any failure is reported as such to the user and the test case
303is marked as
304.Sq failed .
305.It Ic atf_expect_signal Do signo Dc Do reason Dc Dq \&...
306Expects the test case to terminate due to the reception of a signal.
307If
308.Va signo
309is not
310.Sq \-1 ,
311.Xr atf-run 1
312will validate that the signal that terminated the test case matches the one
313provided in this call.
314Otherwise, the exact value will be ignored.
315.It Ic atf_expect_timeout Do reason Dc Dq \&...
316Expects the test case to execute for longer than its timeout.
317.El
318.Ss Helper functions for common checks
319.Ic atf_check Oo options Oc command Op args
320.Pp
321This function wraps the execution of the
322.Nm atf-check
323tool and makes the test case fail if the tool reports failure.
324You should always use this function instead of the tool in your scripts.
325For more details on the parameters of this function, refer to
326.Xr atf-check 1 .
327.Pp
328.Ic atf_check_equal expr1 expr2
329.Pp
330This function takes two expressions, evaluates them and, if their
331results differ, aborts the test case with an appropriate failure message.
332.Sh EXAMPLES
333The following shows a complete test program with a single test case that
334validates the addition operator:
335.Bd -literal -offset indent
336atf_test_case addition
337addition_head() {
338    atf_set "descr" "Sample tests for the addition operator"
339}
340addition_body() {
341    atf_check_equal $((0 + 0)) 0
342    atf_check_equal $((0 + 1)) 1
343    atf_check_equal $((1 + 0)) 0
344
345    atf_check_equal $((1 + 1)) 2
346
347    atf_check_equal $((100 + 200)) 300
348}
349
350atf_init_test_cases() {
351    atf_add_test_case addition
352}
353.Ed
354.Pp
355This other example shows how to include a file with extra helper functions
356in the test program:
357.Bd -literal -offset indent
358.Ns ... definition of test cases ...
359
360atf_init_test_cases() {
361    . $(atf_get_srcdir)/helper_functions.sh
362
363    atf_add_test_case foo1
364    atf_add_test_case foo2
365}
366.Ed
367.Pp
368This example demonstrates the use of the very useful
369.Fn atf_check
370function:
371.Bd -literal -offset indent
372# Check for silent output
373atf_check -s exit:0 -o empty -e empty 'true'
374
375# Check for silent output and failure
376atf_check -s exit:1 -o empty -e empty 'false'
377
378# Check for known stdout and silent stderr
379echo foo >expout
380atf_check -s exit:0 -o file:expout -e empty 'echo foo'
381
382# Generate a file for later inspection
383atf_check -s exit:0 -o save:stdout -e empty 'ls'
384grep foo ls || atf_fail "foo file not found in listing"
385
386# Or just do the match along the way
387atf_check -s exit:0 -o match:"^foo$" -e empty 'ls'
388.Ed
389.Sh SEE ALSO
390.Xr atf-sh 1 ,
391.Xr atf-test-program 1 ,
392.Xr atf-test-case 4 ,
393.Xr atf 7
394