1
=== added file 'tests/test_vars.in'
2
--- tests/test_vars.in 1970-01-01 00:00:00 +0000
3
+++ tests/test_vars.in 2007-04-21 06:59:27 +0000
5
+# defined to 1 if subunit is enabled
6
+export ENABLE_SUBUNIT=@ENABLE_SUBUNIT@
8
=== modified file 'AUTHORS'
9
--- AUTHORS 2006-12-12 19:11:09 +0000
10
+++ AUTHORS 2007-04-21 03:18:23 +0000
12
Robert Lemmen (gcov description in manual)
13
Loic Martin (AM_PATH_CHECK patch)
14
Ross Burton (pkg-config patch)
15
+ Robert Collins (subunit support)
17
Anybody who has contributed code to Check or Check's build system is
18
considered an author. Send patches to this file to
20
=== modified file 'NEWS'
21
--- NEWS 2006-11-21 23:56:21 +0000
22
+++ NEWS 2007-04-21 03:18:23 +0000
26
+* Added CK_SUBUNIT support for outputting test information in the subunit wire
27
+ protocol. See the check manual for more information. (Contributed by Robert
30
Tue, Nov 21, 2006: Released Check 0.9.5
32
* Fixed code coverage support to work with gcc4 and buggy libtool.
34
=== modified file 'configure.ac'
35
--- configure.ac 2006-12-12 19:11:09 +0000
36
+++ configure.ac 2007-04-21 06:59:27 +0000
39
AM_CONDITIONAL(NO_TIMEOUT_TESTS, test x"$enable_timeout_tests" = "xfalse")
41
+AC_ARG_ENABLE(subunit,
42
+AC_HELP_STRING([--enable-subunit],
43
+ [enable support for the subunit test protocol @<:@default=autodetect@:>@]),
44
+[case "${enableval}" in
47
+ echo "Enabled subunit support"
50
+ enable_subunit=false
51
+ echoo "Disabled subunit support"
54
+ echo "Subunit support will enable automatically."
56
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-subunit) ;;
58
+[echo "Subunit support will enable automatically."
59
+ enable_subunit=autodetect])
61
# Checks for programs.
66
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h])
68
+if test xfalse != x"$enable_subunit"; then
69
+AC_CHECK_LIB(subunit, subunit_test_start, ,
70
+[case "$enable_subunit" in
72
+ enable_subunit=false
75
+ AC_MSG_ERROR([libunit is required for subunit protocol support. The homepage for subunit is https://launchpad.net/subunit/])
80
+if test xfalse != x"$enable_subunit"; then
81
+AC_CHECK_HEADER([subunit/child.h], ,
82
+[case "$enable_subunit" in
84
+ enable_subunit=false
87
+ AC_MSG_ERROR([The header subunit/child.h could not be succesfully included and is required for subunit protocol support. The homepage for subunit is https://launchpad.net/subunit/])
92
+if test xfalse = x"$enable_subunit"; then
97
+AC_SUBST(ENABLE_SUBUNIT)
98
+AC_DEFINE_UNQUOTED(ENABLE_SUBUNIT, $ENABLE_SUBUNIT, [Subunit protocol result output])
100
+AM_CONDITIONAL(SUBUNIT, test x"$enable_subunit" != "xfalse")
104
# Checks for typedefs, structures, and compiler characteristics.
117
=== modified file 'doc/check.texi'
118
--- doc/check.texi 2007-01-16 21:57:52 +0000
119
+++ doc/check.texi 2007-04-21 03:18:23 +0000
121
@author Chris Pickett
122
@author Fredrik Hugosson
123
@author Robert Lemmen
124
+@author Robert Collins
126
@c The following two commands start the copyright page.
130
* Determining Test Coverage::
137
which can have the values "silent", "minimal", "normal", "verbose". If
138
the variable is not found or the value is not recognized, the print
139
mode is set to @code{CK_NORMAL}.
143
+Prints running progress through the @uref{https://launchpad.net/subunit/,
144
+subunit} test runner protocol. See 'subunit support' under the Advanced Features section for more information.
147
With the @code{CK_NORMAL} flag specified in our @code{main()}, let's
150
* Determining Test Coverage::
155
@node Running Multiple Cases, No Fork Mode, Advanced Features, Advanced Features
156
@@ -1147,7 +1155,7 @@
157
you. For more information or help with other compilers, please refer
158
to the relevant manuals.
160
-@node Test Logging, , Determining Test Coverage, Advanced Features
161
+@node Test Logging, Subunit Support, Determining Test Coverage, Advanced Features
162
@section Test Logging
164
@findex srunner_set_log()
165
@@ -1250,6 +1258,50 @@
169
+@node Subunit Support, , Test Logging, Advanced Features
170
+@section Subunit Support
172
+Check supports running test suites with subunit output. This can be useful to
173
+combine test results from multiple languages, or to perform programmatic
174
+analysis on the results of multiple check test suites or otherise handle test
175
+results in a programmatic manner. Using subunit with check is very straight
176
+forward. There are two steps:
177
+1) In your check test suite driver pass 'CK_SUBUNIT' as the output mode
182
+sr = srunner_create (make_s1_suite ());
183
+srunner_add_suite (sr, make_s2_suite ());
184
+srunner_run_all (sr, CK_SUBUNIT);
187
+2) Setup your main language test runner to run your check based test
188
+executable. For instance using python:
194
+class ShellTests(subunit.ExecTestCase):
195
+ """Run some tests from the C codebase."""
197
+ def test_group_one(self):
198
+ """./foo/check_driver"""
200
+ def test_group_two(self):
201
+ """./foo/other_driver"""
205
+In this example, running the test suite ShellTests in python (using any test
206
+runner - unittest.py, tribunal, trial, nose or others) will run
207
+./foo/check_driver and ./foo/other_driver and report on their result.
209
+Subunit is hosted on launchpad - the @uref{https://launchpad.net/subunit/,
210
+subunit} project there contains bug tracker, future plans, and source code
213
@node Conclusion and References, AM_PATH_CHECK, Advanced Features, Top
214
@chapter Conclusion and References
215
The tutorial and description of advanced features has provided an
217
=== modified file 'src/check.h.in'
218
--- src/check.h.in 2006-12-08 17:47:49 +0000
219
+++ src/check.h.in 2007-04-21 06:59:27 +0000
221
CK_NORMAL, /* All failed tests */
222
CK_VERBOSE, /* All tests */
223
CK_ENV, /* Look at environment var */
224
+#if @ENABLE_SUBUNIT@
225
+ CK_SUBUNIT, /* Run as a subunit child process */
231
=== modified file 'src/check_impl.h'
232
--- src/check_impl.h 2006-10-13 00:24:56 +0000
233
+++ src/check_impl.h 2007-04-21 01:55:36 +0000
238
+ CLSTART_T, /* A test case is about to run */
243
=== modified file 'src/check_log.c'
244
--- src/check_log.c 2006-10-13 04:10:50 +0000
245
+++ src/check_log.c 2007-04-21 06:59:27 +0000
247
#include <sys/time.h>
250
+#if HAVE_SUBUNIT_CHILD_H
251
+#include <subunit/child.h>
254
#include "check_error.h"
255
#include "check_list.h"
256
#include "check_impl.h"
257
#include "check_log.h"
258
#include "check_print.h"
259
+#include "check_str.h"
262
static void srunner_send_evt (SRunner *sr, void *obj, enum cl_event evt);
264
srunner_send_evt (sr, s, CLEND_S);
267
+void log_test_start (SRunner *sr, TCase * tc, TF * tfun)
270
+ snprintf(buffer, 99, "%s:%s", tc->name, tfun->name);
271
+ srunner_send_evt (sr, buffer, CLSTART_T);
274
void log_test_end (SRunner *sr, TestResult *tr)
276
srunner_send_evt (sr, tr, CLEND_T);
278
void stdout_lfun (SRunner *sr, FILE *file, enum print_output printmode,
279
void *obj, enum cl_event evt)
284
if (printmode == CK_ENV) {
295
eprintf("Bad event type received in stdout_lfun", __FILE__, __LINE__);
296
@@ -197,12 +208,14 @@
304
tr_fprint(file, tr, CK_VERBOSE);
307
- eprintf("Bad event type received in stdout_lfun", __FILE__, __LINE__);
308
+ eprintf("Bad event type received in lfile_lfun", __FILE__, __LINE__);
313
fprintf(file, " </suite>\n");
320
tr_xmlprint(file, tr, CK_VERBOSE);
326
+void subunit_lfun (SRunner *sr, FILE *file, enum print_output printmode,
327
+ void *obj, enum cl_event evt)
333
+ /* assert(printmode == CK_SUBUNIT); */
346
+ if (printmode > CK_SILENT) {
347
+ fprintf (file, "\n");
348
+ srunner_fprint (file, sr, printmode);
356
+ subunit_test_start(name);
361
+ char *name = ck_strdup_printf ("%s:%s", tr->tcname, tr->tname);
362
+ char *msg = tr_short_str (tr);
363
+ switch (tr->rtype) {
365
+ subunit_test_pass(name);
368
+ subunit_test_fail(name, msg);
371
+ subunit_test_error(name, msg);
374
+ eprintf("Bad result type in subunit_lfun", __FILE__, __LINE__);
381
+ eprintf("Bad event type received in subunit_lfun", __FILE__, __LINE__);
386
FILE *srunner_open_lfile (SRunner *sr)
391
sr->loglst = check_list_create();
392
- srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
394
+ if (print_mode != CK_SUBUNIT)
396
+ srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
399
+ srunner_register_lfun (sr, stdout, 0, subunit_lfun, print_mode);
401
f = srunner_open_lfile (sr);
403
srunner_register_lfun (sr, f, 1, lfile_lfun, print_mode);
405
=== modified file 'src/check_log.h'
406
--- src/check_log.h 2006-10-13 00:24:56 +0000
407
+++ src/check_log.h 2007-04-21 01:55:36 +0000
409
void log_suite_start (SRunner *sr, Suite *s);
410
void log_suite_end (SRunner *sr, Suite *s);
411
void log_test_end (SRunner *sr, TestResult *tr);
412
+void log_test_start (SRunner *sr, TCase *tc, TF *tfun);
414
void stdout_lfun (SRunner *sr, FILE *file, enum print_output,
415
void *obj, enum cl_event evt);
417
void xml_lfun (SRunner *sr, FILE *file, enum print_output,
418
void *obj, enum cl_event evt);
420
+void subunit_lfun (SRunner *sr, FILE *file, enum print_output,
421
+ void *obj, enum cl_event evt);
423
void srunner_register_lfun (SRunner *sr, FILE *lfile, int close,
424
LFun lfun, enum print_output);
427
=== modified file 'src/check_print.c'
428
--- src/check_print.c 2006-10-13 00:24:56 +0000
429
+++ src/check_print.c 2007-04-21 06:59:27 +0000
431
static void srunner_fprint_summary (FILE *file, SRunner *sr,
432
enum print_output print_mode)
435
+ if (print_mode == CK_SUBUNIT)
439
if (print_mode >= CK_MINIMAL) {
443
enum print_output print_mode)
448
+ if (print_mode == CK_SUBUNIT)
452
resultlst = sr->resultlst;
455
=== modified file 'src/check_run.c'
456
--- src/check_run.c 2006-11-18 01:02:13 +0000
457
+++ src/check_run.c 2007-04-21 01:55:36 +0000
460
for (i = tfun->loop_start; i < tfun->loop_end; i++)
462
+ log_test_start (sr, tc, tfun);
463
switch (srunner_fork_status(sr)) {
465
tr = tcase_run_tfun_fork (sr, tc, tfun, i);
467
=== modified file 'src/check_str.c'
468
--- src/check_str.c 2006-10-13 00:24:56 +0000
469
+++ src/check_str.c 2007-04-21 01:55:36 +0000
474
+char *tr_short_str (TestResult *tr)
476
+ const char *exact_msg;
479
+ exact_msg = (tr->rtype == CK_ERROR) ? "(after this point) ": "";
481
+ rstr = ck_strdup_printf ("%s:%d: %s%s",
482
+ tr->file, tr->line,
483
+ exact_msg, tr->msg);
488
char *sr_stat_str (SRunner *sr)
492
=== modified file 'src/check_str.h'
493
--- src/check_str.h 2006-10-13 00:24:56 +0000
494
+++ src/check_str.h 2007-04-21 01:55:36 +0000
496
value has been malloc'd, and must be freed by the caller */
497
char *tr_str (TestResult *tr);
499
+/* Return a string representation of the given TestResult message
500
+ without the test id or result type. This is suitable for separate
501
+ formatting of the test and the message. Return value has been
502
+ malloc'd, and must be freed by the caller */
503
+char *tr_short_str (TestResult *tr);
505
/* Return a string representation of the given SRunner's run
506
statistics (% passed, num run, passed, errors, failures). Return
507
value has been malloc'd, and must be freed by the caller
509
=== modified file 'tests/Makefile.am'
510
--- tests/Makefile.am 2006-11-17 08:56:43 +0000
511
+++ tests/Makefile.am 2007-04-21 06:59:27 +0000
516
-EXTRA_DIST = test_output.sh test_log_output.sh test_xml_output.sh
517
+EXTRA_DIST = test_output.sh test_log_output.sh test_vars.in test_xml_output.sh
520
check_check_CFLAGS = -DTIMEOUT_TESTS_ENABLED=0
522
=== modified file 'tests/check_check_log.c'
523
--- tests/check_check_log.c 2006-10-13 00:24:56 +0000
524
+++ tests/check_check_log.c 2007-04-21 06:59:27 +0000
529
+#include <check_list.h>
530
+#include <check_impl.h>
531
+#include <check_log.h>
532
#include "check_check.h"
540
+START_TEST(test_init_logging_subunit)
542
+ /* init_logging with CK_SUBUNIT sets stdout
543
+ * to a subunit function, not any log.
545
+ Log * first_log = NULL;
546
+ Suite *s = suite_create("Suite");
547
+ SRunner *sr = srunner_create(s);
548
+ srunner_init_logging(sr, CK_SUBUNIT);
549
+ list_front (sr->loglst);
550
+ fail_if (list_at_end(sr->loglst), "No entries in log list");
551
+ first_log = list_val(sr->loglst);
552
+ fail_if (first_log == NULL, "log is NULL");
553
+ list_advance(sr->loglst);
554
+ fail_unless(list_at_end(sr->loglst), "More than one entry in log list");
555
+ fail_unless(first_log->lfun == subunit_lfun,
556
+ "Log function is not the subunit lfun.");
557
+ srunner_end_logging(sr);
563
Suite *make_log_suite(void)
567
- TCase *tc_core, *tc_core_xml;
568
+ TCase *tc_core, *tc_core_xml, *tc_core_subunit;
570
s = suite_create("Log");
571
tc_core = tcase_create("Core");
572
tc_core_xml = tcase_create("Core XML");
573
+ tc_core_subunit = tcase_create("Core SubUnit");
575
suite_add_tcase(s, tc_core);
576
tcase_add_test(tc_core, test_set_log);
578
tcase_add_test(tc_core_xml, test_no_set_xml);
579
tcase_add_test(tc_core_xml, test_double_set_xml);
582
+ suite_add_tcase(s, tc_core_subunit);
583
+ tcase_add_test(tc_core_subunit, test_init_logging_subunit);
590
=== modified file 'tests/ex_output.c'
591
--- tests/ex_output.c 2006-10-13 00:24:56 +0000
592
+++ tests/ex_output.c 2007-04-21 06:59:27 +0000
599
START_TEST(test_pass)
605
+static void print_usage(void)
607
+ printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE");
609
+ printf (" | CK_SUBUNIT");
614
int main (int argc, char **argv)
618
- printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE)\n");
624
run_tests(CK_NORMAL);
625
else if (strcmp (argv[1], "CK_VERBOSE") == 0)
626
run_tests(CK_VERBOSE);
628
+ else if (strcmp (argv[1], "CK_SUBUNIT") == 0)
629
+ run_tests(CK_SUBUNIT);
632
- printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE)\n");
638
=== modified file 'tests/test_output.sh'
639
--- tests/test_output.sh 2006-10-13 00:24:56 +0000
640
+++ tests/test_output.sh 2007-04-21 06:59:27 +0000
644
+. "${srcdir}/"test_vars
646
if [ "${srcdir}" = "." ]; then
650
${lsrc}ex_output.c:8:P:Core:test_pass:0: Passed
651
${lsrc}ex_output.c:14:F:Core:test_fail:0: Failure
652
${lsrc}ex_output.c:18:E:Core:test_exit:0: (after this point) Early exit with return value 1"
653
+t4="xtest: Core:test_pass
654
+success: Core:test_pass
655
+test: Core:test_fail
656
+failure: Core:test_fail [
657
+${lsrc}ex_output.c:14: Failure
659
+test: Core:test_exit
660
+error: Core:test_exit [
661
+${lsrc}ex_output.c:18: (after this point) Early exit with return value 1
664
op0=`./ex_output CK_SILENT`
665
op1=`./ex_output CK_MINIMAL`
666
op2=`./ex_output CK_NORMAL`
667
op3=`./ex_output CK_VERBOSE`
669
+if test 1 -eq $ENABLE_SUBUNIT; then
670
+op4=`./ex_output CK_SUBUNIT`
674
if [ "${1}" != "${2}" ]; then
676
test_output "$t1" x"$op1" "CK_MINIMAL";
677
test_output "$t2" x"$op2" "CK_NORMAL";
678
test_output "$t3" x"$op3" "CK_VERBOSE";
679
+if test 1 -eq $ENABLE_SUBUNIT; then
680
+test_output "$t4" x"$op4" "CK_SUBUNIT";