xref: /minix3/external/bsd/dhcp/dist/doc/devel/atf.dox (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek/**
2*83ee113eSDavid van Moolenbroek@page tests Testing
3*83ee113eSDavid van Moolenbroek
4*83ee113eSDavid van Moolenbroek@section testsOverview Testing Overview
5*83ee113eSDavid van Moolenbroek
6*83ee113eSDavid van MoolenbroekIn DHCP, a unit test exercises a particular piece of code in
7*83ee113eSDavid van Moolenbroekisolation. There is a separate unit test per module or API. Each unit
8*83ee113eSDavid van Moolenbroektest lives in a directory beneath the code it is designed to exercise.
9*83ee113eSDavid van MoolenbroekSo, we (will eventually) have:
10*83ee113eSDavid van Moolenbroek
11*83ee113eSDavid van Moolenbroek@verbatim
12*83ee113eSDavid van Moolenbroekserver/tests/
13*83ee113eSDavid van Moolenbroekclient/tests/
14*83ee113eSDavid van Moolenbroekcommon/tests/
15*83ee113eSDavid van Moolenbroekdhcpctl/tests/
16*83ee113eSDavid van Moolenbroek...
17*83ee113eSDavid van Moolenbroek@endverbatim
18*83ee113eSDavid van Moolenbroek
19*83ee113eSDavid van MoolenbroekAnd so on.
20*83ee113eSDavid van Moolenbroek
21*83ee113eSDavid van MoolenbroekIdeally each function would be invoked with every possible type of input, and
22*83ee113eSDavid van Moolenbroekeach branch of every function would be checked. In practice we try to be a bit
23*83ee113eSDavid van Moolenbroekmore pragmatic, and target the most basic operations, as well tricky code, and
24*83ee113eSDavid van Moolenbroekareas we have seen bugs in the past.
25*83ee113eSDavid van Moolenbroek
26*83ee113eSDavid van MoolenbroekWe are using <a href="http://code.google.com/p/kyua/wiki/ATF">ATF (Automated
27*83ee113eSDavid van MoolenbroekTest Framework)</a> as a framework to run our unittests.
28*83ee113eSDavid van Moolenbroek
29*83ee113eSDavid van Moolenbroek@section testsAtf ATF unit-tests
30*83ee113eSDavid van Moolenbroek
31*83ee113eSDavid van MoolenbroekATF stands for Automated Test Framework, and is the framework used for unit
32*83ee113eSDavid van Moolenbroektests in ISC DHCP and BIND9. ATF sources can be downloaded from
33*83ee113eSDavid van Moolenbroekhttp://code.google.com/p/kyua/wiki/ATF . ATF itself must be configured, compiled
34*83ee113eSDavid van Moolenbroekand then installed to be available during the DHCP configure procedure.  Please
35*83ee113eSDavid van Moolenbroekfollow INSTALL file supplied with ATF sources (it's essentially the typical
36*83ee113eSDavid van Moolenbroek./configure && make && make install procedure).
37*83ee113eSDavid van Moolenbroek
38*83ee113eSDavid van MoolenbroekThe ATF successor, called Kyua, is being developed. As of August 2012, the
39*83ee113eSDavid van Moolenbroeklatest available release of Kyua is 0.5. It claims to offer feature parity with
40*83ee113eSDavid van MoolenbroekATF. Migration to Kyua may be planned some time in the future, but DHCP uses ATF
41*83ee113eSDavid van Moolenbroekfor now. Such an upgrade should be done in coordination with BIND. The latest
42*83ee113eSDavid van Moolenbroektested version of ATF that DHCP's unittests were run against is 0.15.
43*83ee113eSDavid van Moolenbroek
44*83ee113eSDavid van MoolenbroekTo build the unit-tests, use the following:
45*83ee113eSDavid van Moolenbroek
46*83ee113eSDavid van Moolenbroek@verbatim
47*83ee113eSDavid van Moolenbroek$ ./configure --with-atf
48*83ee113eSDavid van Moolenbroek$ make
49*83ee113eSDavid van Moolenbroek$ make check
50*83ee113eSDavid van Moolenbroek@endverbatim
51*83ee113eSDavid van Moolenbroek
52*83ee113eSDavid van MoolenbroekThe following syntax is supported as well:
53*83ee113eSDavid van Moolenbroek@verbatim
54*83ee113eSDavid van Moolenbroek$ ./configure --with-atf=/path/to/your/atf/install
55*83ee113eSDavid van Moolenbroek@endverbatim
56*83ee113eSDavid van Moolenbroek
57*83ee113eSDavid van Moolenbroekbut it seems to have troubles sometimes detecting ATF installation, at least
58*83ee113eSDavid van Moolenbroekwith ATF 0.14 and Mac OS X 10.6.8.
59*83ee113eSDavid van Moolenbroek
60*83ee113eSDavid van MoolenbroekEach code directory (e.g. server/) that has unit-tests has a sub-directory
61*83ee113eSDavid van Moolenbroeknamed tests (e.g. server/tests). You can execute "make check" in that
62*83ee113eSDavid van Moolenbroekdirectory to run specific subset of tests.
63*83ee113eSDavid van Moolenbroek
64*83ee113eSDavid van MoolenbroekUnit-tests are grouped into suites, each suite being a separate
65*83ee113eSDavid van Moolenbroekexecutable. The typical way to run tests is:
66*83ee113eSDavid van Moolenbroek
67*83ee113eSDavid van Moolenbroek@verbatim
68*83ee113eSDavid van Moolenbroek$ atf-run | atf-report
69*83ee113eSDavid van Moolenbroek@endverbatim
70*83ee113eSDavid van Moolenbroek
71*83ee113eSDavid van Moolenbroekatf-run will read the Atffile in the current directory and execute all the tests
72*83ee113eSDavid van Moolenbroekspecified in it. Using atf-run - rather than calling the test binary directly -
73*83ee113eSDavid van Moolenbroekhas several major benefits. The main one is that atf-run is able to recover from
74*83ee113eSDavid van Moolenbroektest segfault and continue execution from the next case onwards. Another is that
75*83ee113eSDavid van Moolenbroekit is possible to specify a timeout for a test. atf-run will kill the test in
76*83ee113eSDavid van Moolenbroekcase of any infinite loops and will continue running next tests.
77*83ee113eSDavid van Moolenbroek
78*83ee113eSDavid van MoolenbroekIt is possible to run atf-run without passing its output to atf-report, but its
79*83ee113eSDavid van Moolenbroekoutput is somewhat convoluted. That is useful in some situations, e.g. when one
80*83ee113eSDavid van Moolenbroekwants to see test output.
81*83ee113eSDavid van Moolenbroek
82*83ee113eSDavid van MoolenbroekIt is possible to run test binary directly. The only required parameter is the
83*83ee113eSDavid van Moolenbroektest case name. The binary will print out a warning that direct binary execution
84*83ee113eSDavid van Moolenbroekis not recommended as it won't be able to recover from crash.  However, such an
85*83ee113eSDavid van Moolenbroekapproach is convenient for running the test under the debugger.
86*83ee113eSDavid van Moolenbroek
87*83ee113eSDavid van Moolenbroek@section testsAtfAdding Adding new unit-tests
88*83ee113eSDavid van Moolenbroek
89*83ee113eSDavid van MoolenbroekThere are a small number of unit-tests that are not ATF based. They will be
90*83ee113eSDavid van Moolenbroekconverted to ATF soon. Please do not use any other frameworks.
91*83ee113eSDavid van Moolenbroek
92*83ee113eSDavid van MoolenbroekSadly, the DHCP code was not written with unit-testing in mind: often a
93*83ee113eSDavid van Moolenbroeknon-standard approach is required for writing unit-tests. The existing code
94*83ee113eSDavid van Moolenbroekoften has many dependencies that make testing a single piece of code awkward to
95*83ee113eSDavid van Moolenbroekunit test.  For example, to test hash tables, one needs to also include the
96*83ee113eSDavid van MoolenbroekOMAPI code. Rather than significantly refactoring the code (a huge task that
97*83ee113eSDavid van Moolenbroekcould take months), we decided to link whatever is needed in the tests. If
98*83ee113eSDavid van Moolenbroekdeveloping new test suite, it is recommended that you take a look at existing
99*83ee113eSDavid van Moolenbroektests and just copy them as a starting point.
100*83ee113eSDavid van Moolenbroek
101*83ee113eSDavid van Moolenbroek
102*83ee113eSDavid van MoolenbroekIn particular, the following
103*83ee113eSDavid van Moolenbroekthings should be done for adding new tests:
104*83ee113eSDavid van Moolenbroek
105*83ee113eSDavid van Moolenbroek<b>1. Tests directory.</b> For each code component (server, client, common,
106*83ee113eSDavid van Moolenbroeketc.) there should be a tests subdirectory. If it isn't there yet, then it must
107*83ee113eSDavid van Moolenbroekbe created. This can be done by:
108*83ee113eSDavid van Moolenbroek
109*83ee113eSDavid van Moolenbroeka). Creating the directory:
110*83ee113eSDavid van Moolenbroek
111*83ee113eSDavid van Moolenbroek@verbatim
112*83ee113eSDavid van Moolenbroek    $ mkdir $subdir/tests
113*83ee113eSDavid van Moolenbroek    $ cvs add tests
114*83ee113eSDavid van Moolenbroek@endverbatim
115*83ee113eSDavid van Moolenbroek
116*83ee113eSDavid van Moolenbroekb). Adding the subdirectory to the build system:
117*83ee113eSDavid van Moolenbroek
118*83ee113eSDavid van Moolenbroek    Add to $subdir/Makefile.am:
119*83ee113eSDavid van Moolenbroek
120*83ee113eSDavid van Moolenbroek@verbatim
121*83ee113eSDavid van Moolenbroek    SUBDIRS = tests
122*83ee113eSDavid van Moolenbroek@endverbatim
123*83ee113eSDavid van Moolenbroek
124*83ee113eSDavid van Moolenbroek    Add to the AC_OUTPUT macro in configure.ac:
125*83ee113eSDavid van Moolenbroek
126*83ee113eSDavid van Moolenbroek@verbatim
127*83ee113eSDavid van Moolenbroek    subdir/tests/Makefile
128*83ee113eSDavid van Moolenbroek@endverbatim
129*83ee113eSDavid van Moolenbroek
130*83ee113eSDavid van Moolenbroekc. Create a Makefile.am in the new directory, something similar to this:
131*83ee113eSDavid van Moolenbroek
132*83ee113eSDavid van Moolenbroek@verbatim
133*83ee113eSDavid van Moolenbroek    AM_CPPFLAGS = -I../..
134*83ee113eSDavid van Moolenbroek
135*83ee113eSDavid van Moolenbroek    check_PROGRAMS = test_foo
136*83ee113eSDavid van Moolenbroek
137*83ee113eSDavid van Moolenbroek    TESTS = test_foo
138*83ee113eSDavid van Moolenbroek
139*83ee113eSDavid van Moolenbroek    test_foo_SOURCES = test_foo.c
140*83ee113eSDavid van Moolenbroek    test_foo_LDADD = ../../tests/libt_api.a     # plus others...
141*83ee113eSDavid van Moolenbroek@endverbatim
142*83ee113eSDavid van Moolenbroek
143*83ee113eSDavid van MoolenbroekSee existing Makefile.am for examples, and the Automake documentation:
144*83ee113eSDavid van Moolenbroek
145*83ee113eSDavid van Moolenbroek    http://www.gnu.org/software/automake/manual/html_node/Tests.html
146*83ee113eSDavid van Moolenbroek
147*83ee113eSDavid van Moolenbroek<b>2. Implement the test.</b> That typically means that you create a new file that will
148*83ee113eSDavid van Moolenbroekhold test code. It is recommended you name it (tested_feature_name)_unittest.c
149*83ee113eSDavid van Moolenbroekand put the file in specified tests directory.  For example tests related to
150*83ee113eSDavid van Moolenbroekhash tables used on the server side should be named
151*83ee113eSDavid van Moolenbroekserver/tests/hash_unittest.c. If in doubt, it is convenient to name the test
152*83ee113eSDavid van Moolenbroekcode after the file that holds tested code, e.g. server/mdb6.c is tested in
153*83ee113eSDavid van Moolenbroekserver/tests/mdb6_unittest.c.
154*83ee113eSDavid van Moolenbroek
155*83ee113eSDavid van MoolenbroekThe file server/tests/simple_unittest.c holds a template explaining the basic
156*83ee113eSDavid van Moolenbroeklayout of the ATF tests.  There may be many test cases in a single *_unittest.c
157*83ee113eSDavid van Moolenbroekfile. Make sure that you register all your test cases using ATF_TP_ADD_TC()
158*83ee113eSDavid van Moolenbroekmacro, and try to minimize modifications to the tested code if possible. Keep in
159*83ee113eSDavid van Moolenbroekmind that we are using modernized \ref codingGuidelines for test
160*83ee113eSDavid van Moolenbroekdevelopment. You are advised to also look at atf-c-api(3) man page.
161*83ee113eSDavid van Moolenbroek
162*83ee113eSDavid van MoolenbroekTo add a new test, such as when a new module is added or when you want to start
163*83ee113eSDavid van Moolenbroektesting existing code, you can copy the server/tests/simple_unittest.c as a new
164*83ee113eSDavid van Moolenbroeknew file, add the new file as a target in Makefile.am, and begin adding
165*83ee113eSDavid van Moolenbroektests. Reviewing that file is a good idea, even if you decide to write your test
166*83ee113eSDavid van Moolenbroekfrom scratch, as it give you quick overview of the essential capabilities of the
167*83ee113eSDavid van MoolenbroekATF framework (how to write test, how to make checks, pass or fail test
168*83ee113eSDavid van Moolenbroeketc.). Do not forget to add your new file to git via "git add
169*83ee113eSDavid van Moolenbroekyourtest_unittest.c".
170*83ee113eSDavid van Moolenbroek
171*83ee113eSDavid van Moolenbroek<b>3. Extend Makefile.am</b> to build your test. In particular, add your binary
172*83ee113eSDavid van Moolenbroekname to ATF_TESTS. The tests directory will be built only in case where
173*83ee113eSDavid van MoolenbroekATF is enabled, using --with-atf during configure phase.
174*83ee113eSDavid van Moolenbroek
175*83ee113eSDavid van Moolenbroek<b>4. Modify Atffile to include your new test</b>, if needed. Tests in the
176*83ee113eSDavid van Moolenbroekspecified directory must be registered in Atffile. See server/tests/Atffile for
177*83ee113eSDavid van Moolenbroekan example. Currently every executable with name of the form *_unittest will be
178*83ee113eSDavid van Moolenbroekexecuted automatically. If you followed naming convention proposed in a previous
179*83ee113eSDavid van Moolenbroekstep, your test will be included and will be included automatically.
180*83ee113eSDavid van Moolenbroek
181*83ee113eSDavid van Moolenbroek<b>5. Enjoy your improved confidence in the code</b>, as you can run the tests after
182*83ee113eSDavid van Moolenbroekany change you may want to do:
183*83ee113eSDavid van Moolenbroek
184*83ee113eSDavid van Moolenbroek@verbatim
185*83ee113eSDavid van Moolenbroek$ make check
186*83ee113eSDavid van Moolenbroek@endverbatim
187*83ee113eSDavid van Moolenbroek
188*83ee113eSDavid van Moolenbroekto run all tests for all components. See \ref atfTests section for more details
189*83ee113eSDavid van Moolenbroekon running tests.
190*83ee113eSDavid van Moolenbroek
191*83ee113eSDavid van Moolenbroek@section testsAtfCoding ATF Coding Guidelines
192*83ee113eSDavid van Moolenbroek
193*83ee113eSDavid van MoolenbroekAs the unit-test code creates an evironment that works under a different
194*83ee113eSDavid van Moolenbroekregime than the production code, there are slight differences to standard
195*83ee113eSDavid van Moolenbroekcoding guidelines. In particular:
196*83ee113eSDavid van Moolenbroek
197*83ee113eSDavid van Moolenbroek- The code is written using C99. Double slash comments are allowed.
198*83ee113eSDavid van Moolenbroek- Please do not use tabs. Use 4 spaces for each indent level.
199*83ee113eSDavid van Moolenbroek
200*83ee113eSDavid van Moolenbroek*/
201