Skip to content
This repository was archived by the owner on Jun 24, 2021. It is now read-only.

Commit 8fe5ef5

Browse files
committed
tests: add C TAP harness
1 parent 33ded5f commit 8fe5ef5

File tree

13 files changed

+3450
-0
lines changed

13 files changed

+3450
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
tags
22
Makefile
33
*~
4+
*.a
45
*.o
56
*.so
67
*.lo
@@ -55,6 +56,7 @@ ircd/version.c
5556
ircd/version.c.last
5657
ssld/ssld
5758
wsockd/wsockd
59+
tests/runtests
5860
testsuite/ircd.pid.*
5961
tools/charybdis-mkpasswd
6062
tools/charybdis-mkfingerprint

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ SUBDIRS += ircd \
1212
wsockd \
1313
authd \
1414
bandb \
15+
tests \
1516
tools \
1617
modules \
1718
extensions \

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@ AC_CONFIG_FILES( \
660660
extensions/Makefile \
661661
ircd/Makefile \
662662
modules/Makefile \
663+
tests/Makefile \
663664
tools/Makefile \
664665
tools/genssl \
665666
doc/Makefile \

tests/Makefile.am

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
check_PROGRAMS = runtests
2+
AM_CFLAGS=$(WARNFLAGS)
3+
AM_CPPFLAGS = $(DEFAULT_INCLUDES) -I../librb/include -I..
4+
AM_LDFLAGS = -no-install
5+
LDADD = tap/libtap.a ../librb/src/librb.la ../ircd/libircd.la
6+
7+
# Override -rpath or programs will be linked to installed libraries
8+
libdir=$(abs_top_builddir)
9+
10+
runtests_CPPFLAGS = -DC_TAP_SOURCE='"$(abs_top_srcdir)/tests"' \
11+
-DC_TAP_BUILD='"$(abs_top_builddir)/tests"'
12+
check_LIBRARIES = tap/libtap.a
13+
tap_libtap_a_SOURCES = tap/basic.c tap/basic.h \
14+
tap/float.c tap/float.h tap/macros.h
15+
16+
check-local: $(check_PROGRAMS)
17+
./runtests -l $(abs_top_srcdir)/tests/TESTS

tests/README

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
Writing TAP Tests
2+
3+
Introduction
4+
5+
This is a guide for users of the C TAP Harness package or similar
6+
TAP-based test harnesses explaining how to write tests. If your
7+
package uses C TAP Harness as the test suite driver, you may want to
8+
copy this document to an appropriate file name in your test suite as
9+
documentation for contributors.
10+
11+
About TAP
12+
13+
TAP is the Test Anything Protocol, a protocol for communication
14+
between test cases and a test harness. This is the protocol used by
15+
Perl for its internal test suite and for nearly all Perl modules,
16+
since it's the format used by the build tools for Perl modules to run
17+
tests and report their results.
18+
19+
A TAP-based test suite works with a somewhat different set of
20+
assumptions than an xUnit test suite. In TAP, each test case is a
21+
separate program. That program, when run, must produce output in the
22+
following format:
23+
24+
1..4
25+
ok 1 - the first test
26+
ok 2
27+
# a diagnostic, ignored by the harness
28+
not ok 3 - a failing test
29+
ok 4 # skip a skipped test
30+
31+
The output should all go to standard output. The first line specifies
32+
the number of tests to be run, and then each test produces output that
33+
looks like either "ok <n>" or "not ok <n>" depending on whether the
34+
test succeeded or failed. Additional information about the test can
35+
be provided after the "ok <n>" or "not ok <n>", but is optional.
36+
Additional diagnostics and information can be provided in lines
37+
beginning with a "#".
38+
39+
Processing directives are supported after the "ok <n>" or "not ok <n>"
40+
and start with a "#". The main one of interest is "# skip" which says
41+
that the test was skipped rather than successful and optionally gives
42+
the reason. Also supported is "# todo", which normally annotates a
43+
failing test and indicates that test is expected to fail, optionally
44+
providing a reason for why.
45+
46+
There are three more special cases. First, the initial line stating
47+
the number of tests to run, called the plan, may appear at the end of
48+
the output instead of the beginning. This can be useful if the number
49+
of tests to run is not known in advance. Second, a plan in the form:
50+
51+
1..0 # skip entire test case skipped
52+
53+
can be given instead, which indicates that this entire test case has
54+
been skipped (generally because it depends on facilities or optional
55+
configuration which is not present). Finally, if the test case
56+
encounters a fatal error, it should print the text:
57+
58+
Bail out!
59+
60+
on standard output, optionally followed by an error message, and then
61+
exit. This tells the harness that the test aborted unexpectedly.
62+
63+
The exit status of a successful test case should always be 0. The
64+
harness will report the test as "dubious" if all the tests appeared to
65+
succeed but it exited with a non-zero status.
66+
67+
Writing TAP Tests
68+
69+
Environment
70+
71+
One of the special features of C TAP Harness is the environment that
72+
it sets up for your test cases. If your test program is called under
73+
the runtests driver, the environment variables C_TAP_SOURCE and
74+
C_TAP_BUILD will be set to the top of the test directory in the source
75+
tree and the top of the build tree, respectively. You can use those
76+
environment variables to locate additional test data, programs and
77+
libraries built as part of your software build, and other supporting
78+
information needed by tests.
79+
80+
The C and shell TAP libraries support a test_file_path() function,
81+
which looks for a file under the build tree and then under the source
82+
tree, using the C_TAP_BUILD and C_TAP_SOURCE environment variables,
83+
and return the full path to the file. This can be used to locate
84+
supporting data files. They also support a test_tmpdir() function
85+
that returns a directory that can be used for temporary files during
86+
tests.
87+
88+
Perl
89+
90+
Since TAP is the native test framework for Perl, writing TAP tests in
91+
Perl is very easy and extremely well-supported. If you've never
92+
written tests in Perl before, start by reading the documentation for
93+
Test::Tutorial and Test::Simple, which walks you through the basics,
94+
including the TAP output syntax. Then, the best Perl module to use
95+
for serious testing is Test::More, which provides a lot of additional
96+
functions over Test::Simple including support for skipping tests,
97+
bailing out, and not planning tests in advance. See the documentation
98+
of Test::More for all the details and lots of examples.
99+
100+
C TAP Harness can run Perl test scripts directly and interpret the
101+
results correctly, and similarly the Perl Test::Harness module and
102+
prove command can run TAP tests written in other languages using, for
103+
example, the TAP library that comes with C TAP Harness. You can, if
104+
you wish, use the library that comes with C TAP Harness but use prove
105+
instead of runtests for running the test suite.
106+
107+
C
108+
109+
C TAP Harness provides a basic TAP library that takes away most of the
110+
pain of writing TAP test cases in C. A C test case should start with
111+
a call to plan(), passing in the number of tests to run. Then, each
112+
test should use is_int(), is_string(), is_double(), or is_hex() as
113+
appropriate to compare expected and seen values, or ok() to do a
114+
simpler boolean test. The is_*() functions take expected and seen
115+
values and then a printf-style format string explaining the test
116+
(which may be NULL). ok() takes a boolean and then the printf-style
117+
string.
118+
119+
Here's a complete example test program that uses the C TAP library:
120+
121+
#include <stddef.h>
122+
#include <tap/basic.h>
123+
124+
int
125+
main(void)
126+
{
127+
plan(4);
128+
129+
ok(1, "the first test");
130+
is_int(42, 42, NULL);
131+
diag("a diagnostic, ignored by the harness");
132+
ok(0, "a failing test");
133+
skip("a skipped test");
134+
135+
return 0;
136+
}
137+
138+
This test program produces the output shown above in the section on
139+
TAP and demonstrates most of the functions. The other functions of
140+
interest are sysdiag() (like diag() but adds strerror() results),
141+
bail() and sysbail() for fatal errors, skip_block() to skip a whole
142+
block of tests, and skip_all() which is called instead of plan() to
143+
skip an entire test case.
144+
145+
The C TAP library also provides plan_lazy(), which can be called
146+
instead of plan(). If plan_lazy() is called, the library will keep
147+
track of how many test results are reported and will print out the
148+
plan at the end of execution of the program. This should normally be
149+
avoided since the test may appear to be successful even if it exits
150+
prematurely, but it can make writing tests easier in some
151+
circumstances.
152+
153+
Complete API documentation for the basic C TAP library that comes with
154+
C TAP Harness is available at:
155+
156+
<https://www.eyrie.org/~eagle/software/c-tap-harness/>
157+
158+
It's common to need additional test functions and utility functions
159+
for your C tests, particularly if you have to set up and tear down a
160+
test environment for your test programs, and it's useful to have them
161+
all in the libtap library so that you only have to link your test
162+
programs with one library. Rather than editing tap/basic.c and
163+
tap/basic.h to add those additional functions, add additional *.c and
164+
*.h files into the tap directory with the function implementations and
165+
prototypes, and then add those additional objects to the library.
166+
That way, you can update tap/basic.c and tap/basic.h from subsequent
167+
releases of C TAP Harness without having to merge changes with your
168+
own code.
169+
170+
Libraries of additional useful TAP test functions are available in
171+
rra-c-util at:
172+
173+
<https://www.eyrie.org/~eagle/software/rra-c-util/>
174+
175+
Some of the code there is particularly useful when testing programs
176+
that require Kerberos keys.
177+
178+
If you implement new test functions that compare an expected and seen
179+
value, it's best to name them is_<something> and take the expected
180+
value, the seen value, and then a printf-style format string and
181+
possible arguments to match the calling convention of the functions
182+
provided by C TAP Harness.
183+
184+
Shell
185+
186+
C TAP Harness provides a library of shell functions to make it easier
187+
to write TAP tests in shell. That library includes much of the same
188+
functionality as the C TAP library, but takes its parameters in a
189+
somewhat different order to make better use of shell features.
190+
191+
The libtap.sh file should be installed in a directory named tap in
192+
your test suite area. It can then be loaded by tests written in shell
193+
using the environment set up by runtests with:
194+
195+
. "$C_TAP_SOURCE"/tap/libtap.sh
196+
197+
Here is a complete test case written in shell which produces the same
198+
output as the TAP sample above:
199+
200+
#!/bin/sh
201+
202+
. "$C_TAP_SOURCE"/tap/libtap.sh
203+
cd "$C_TAP_BUILD"
204+
205+
plan 4
206+
ok 'the first test' true
207+
ok '' [ 42 -eq 42 ]
208+
diag a diagnostic, ignored by the harness
209+
ok '' false
210+
skip 'a skipped test'
211+
212+
The shell framework doesn't provide the is_* functions, so you'll use
213+
the ok function more. It takes a string describing the text and then
214+
treats all of its remaining arguments as a condition, evaluated the
215+
same way as the arguments to the "if" statement. If that condition
216+
evaluates to true, the test passes; otherwise, the test fails.
217+
218+
The plan, plan_lazy, diag, and bail functions work the same as with
219+
the C library. skip takes a string and skips the next test with that
220+
explanation. skip_block takes a count and a string and skips that
221+
many tests with that explanation. skip_all takes an optional reason
222+
and skips the entire test case.
223+
224+
Since it's common for shell programs to want to test the output of
225+
commands, there's an additional function ok_program provided by the
226+
shell test library. It takes the test description string, the
227+
expected exit status, the expected program output, and then treats the
228+
rest of its arguments as the program to run. That program is run with
229+
standard error and standard output combined, and then its exit status
230+
and output are tested against the provided values.
231+
232+
A utility function, strip_colon_error, is provided that runs the
233+
command given as its arguments and strips text following a colon and a
234+
space from the output (unless there is no whitespace on the line
235+
before the colon and the space, normally indicating a prefix of the
236+
program name). This function can be used to wrap commands that are
237+
expected to fail with output that has a system- or locale-specific
238+
error message appended, such as the output of strerror().
239+
240+
License
241+
242+
This file is part of the documentation of C TAP Harness, which can be
243+
found at <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
244+
245+
Copyright 2010, 2016 Russ Allbery <[email protected]>
246+
247+
Copying and distribution of this file, with or without modification,
248+
are permitted in any medium without royalty provided the copyright
249+
notice and this notice are preserved. This file is offered as-is,
250+
without any warranty.

tests/TESTS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#

0 commit comments

Comments
 (0)