summaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2007-04-21 17:10:18 +1000
committerRobert Collins <robertc@robertcollins.net>2007-04-21 17:10:18 +1000
commit632755acd911e3149501d7e36a0c3426947ab918 (patch)
tree6ceaf3b28e574153bea6a75abb2a5a52cea3f372 /c
parent71019c2d416fb927685604ef1f58f074cbc214ff (diff)
downloadsubunit-git-632755acd911e3149501d7e36a0c3426947ab918.tar.gz
Update the check patch to be more accceptable to upstream, include documentation, and apply to check 0.9.5.
Diffstat (limited to 'c')
-rw-r--r--c/README7
-rw-r--r--c/check-subunit-0.9.5.patch683
2 files changed, 687 insertions, 3 deletions
diff --git a/c/README b/c/README
index 1fce98f..89e6b58 100644
--- a/c/README
+++ b/c/README
@@ -35,9 +35,10 @@ instance] managing assertions, cleaning up on errors etc. You can look at
'check' (http://check.sourceforge.net/) or
'gunit' (https://garage.maemo.org/projects/gunit) for C unit test
frameworks. I plan to write ui layers for both of these that use the subunit
-bindings for reporting. There is a patch for 'check' (check-subunit-patch-0.9.3)
-in this source tree. Its also available as request ID #1470750 in the sourceforge
-request tracker http://sourceforge.net/tracker/index.php.
+bindings for reporting. There is a patch for 'check'
+(check-subunit-0.9.3.patch, and check-subunit-0.9.5.patch) in this source tree.
+Its also available as request ID #1470750 in the sourceforge request tracker
+http://sourceforge.net/tracker/index.php.
If you are a test environment maintainer - either homegrown, or 'check' or
'gunit' or some other, you will to know how the subunit calls should be used.
diff --git a/c/check-subunit-0.9.5.patch b/c/check-subunit-0.9.5.patch
new file mode 100644
index 0000000..53f192e
--- /dev/null
+++ b/c/check-subunit-0.9.5.patch
@@ -0,0 +1,683 @@
+=== added file 'tests/test_vars.in'
+--- tests/test_vars.in 1970-01-01 00:00:00 +0000
++++ tests/test_vars.in 2007-04-21 06:59:27 +0000
+@@ -0,0 +1,2 @@
++# defined to 1 if subunit is enabled
++export ENABLE_SUBUNIT=@ENABLE_SUBUNIT@
+
+=== modified file 'AUTHORS'
+--- AUTHORS 2006-12-12 19:11:09 +0000
++++ AUTHORS 2007-04-21 03:18:23 +0000
+@@ -14,6 +14,7 @@
+ Robert Lemmen (gcov description in manual)
+ Loic Martin (AM_PATH_CHECK patch)
+ Ross Burton (pkg-config patch)
++ Robert Collins (subunit support)
+
+ Anybody who has contributed code to Check or Check's build system is
+ considered an author. Send patches to this file to
+
+=== modified file 'NEWS'
+--- NEWS 2006-11-21 23:56:21 +0000
++++ NEWS 2007-04-21 03:18:23 +0000
+@@ -1,3 +1,9 @@
++In development:
++
++* Added CK_SUBUNIT support for outputting test information in the subunit wire
++ protocol. See the check manual for more information. (Contributed by Robert
++ Collins).
++
+ Tue, Nov 21, 2006: Released Check 0.9.5
+
+ * Fixed code coverage support to work with gcc4 and buggy libtool.
+
+=== modified file 'configure.ac'
+--- configure.ac 2006-12-12 19:11:09 +0000
++++ configure.ac 2007-04-21 06:59:27 +0000
+@@ -65,6 +65,26 @@
+
+ AM_CONDITIONAL(NO_TIMEOUT_TESTS, test x"$enable_timeout_tests" = "xfalse")
+
++AC_ARG_ENABLE(subunit,
++AC_HELP_STRING([--enable-subunit],
++ [enable support for the subunit test protocol @<:@default=autodetect@:>@]),
++[case "${enableval}" in
++ yes)
++ enable_subunit=true
++ echo "Enabled subunit support"
++ ;;
++ no)
++ enable_subunit=false
++ echoo "Disabled subunit support"
++ ;;
++ autodetect)
++ echo "Subunit support will enable automatically."
++ ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for --enable-subunit) ;;
++esac],
++[echo "Subunit support will enable automatically."
++ enable_subunit=autodetect])
++
+ # Checks for programs.
+ AC_PROG_AWK
+ AC_PROG_CC
+@@ -85,6 +105,42 @@
+ AC_HEADER_SYS_WAIT
+ AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h])
+
++if test xfalse != x"$enable_subunit"; then
++AC_CHECK_LIB(subunit, subunit_test_start, ,
++[case "$enable_subunit" in
++ autodetect)
++ enable_subunit=false
++ ;;
++ true)
++ AC_MSG_ERROR([libunit is required for subunit protocol support. The homepage for subunit is https://launchpad.net/subunit/])
++ ;;
++ esac
++])
++fi
++if test xfalse != x"$enable_subunit"; then
++AC_CHECK_HEADER([subunit/child.h], ,
++[case "$enable_subunit" in
++ autodetect)
++ enable_subunit=false
++ ;;
++ true)
++ 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/])
++ ;;
++ esac
++])
++fi
++if test xfalse = x"$enable_subunit"; then
++ENABLE_SUBUNIT="0"
++else
++ENABLE_SUBUNIT="1"
++fi
++AC_SUBST(ENABLE_SUBUNIT)
++AC_DEFINE_UNQUOTED(ENABLE_SUBUNIT, $ENABLE_SUBUNIT, [Subunit protocol result output])
++
++AM_CONDITIONAL(SUBUNIT, test x"$enable_subunit" != "xfalse")
++
++
++
+ # Checks for typedefs, structures, and compiler characteristics.
+ AC_C_CONST
+ AC_TYPE_PID_T
+@@ -112,6 +168,7 @@
+ doc/Makefile
+ src/check.h
+ src/Makefile
+- tests/Makefile])
++ tests/Makefile
++ tests/test_vars])
+
+ AC_OUTPUT
+
+=== modified file 'doc/check.texi'
+--- doc/check.texi 2007-01-16 21:57:52 +0000
++++ doc/check.texi 2007-04-21 03:18:23 +0000
+@@ -39,6 +39,7 @@
+ @author Chris Pickett
+ @author Fredrik Hugosson
+ @author Robert Lemmen
++@author Robert Collins
+
+ @c The following two commands start the copyright page.
+ @page
+@@ -98,6 +99,7 @@
+ * Test Timeouts::
+ * Determining Test Coverage::
+ * Test Logging::
++* Subunit Support::
+
+ Test Fixtures
+
+@@ -672,6 +674,11 @@
+ which can have the values "silent", "minimal", "normal", "verbose". If
+ the variable is not found or the value is not recognized, the print
+ mode is set to @code{CK_NORMAL}.
++
++@vindex CK_SUBUNIT
++@item CK_SUBUNIT
++Prints running progress through the @uref{https://launchpad.net/subunit/,
++subunit} test runner protocol. See 'subunit support' under the Advanced Features section for more information.
+ @end table
+
+ With the @code{CK_NORMAL} flag specified in our @code{main()}, let's
+@@ -766,6 +773,7 @@
+ * Test Timeouts::
+ * Determining Test Coverage::
+ * Test Logging::
++* Subunit Support::
+ @end menu
+
+ @node Running Multiple Cases, No Fork Mode, Advanced Features, Advanced Features
+@@ -1147,7 +1155,7 @@
+ you. For more information or help with other compilers, please refer
+ to the relevant manuals.
+
+-@node Test Logging, , Determining Test Coverage, Advanced Features
++@node Test Logging, Subunit Support, Determining Test Coverage, Advanced Features
+ @section Test Logging
+
+ @findex srunner_set_log()
+@@ -1250,6 +1258,50 @@
+ @end verbatim
+ @end example
+
++@node Subunit Support, , Test Logging, Advanced Features
++@section Subunit Support
++
++Check supports running test suites with subunit output. This can be useful to
++combine test results from multiple languages, or to perform programmatic
++analysis on the results of multiple check test suites or otherise handle test
++results in a programmatic manner. Using subunit with check is very straight
++forward. There are two steps:
++1) In your check test suite driver pass 'CK_SUBUNIT' as the output mode
++for your srunner.
++@example
++@verbatim
++SRunner *sr;
++sr = srunner_create (make_s1_suite ());
++srunner_add_suite (sr, make_s2_suite ());
++srunner_run_all (sr, CK_SUBUNIT);
++@end verbatim
++@end example
++2) Setup your main language test runner to run your check based test
++executable. For instance using python:
++@example
++@verbatim
++
++import subunit
++
++class ShellTests(subunit.ExecTestCase):
++ """Run some tests from the C codebase."""
++
++ def test_group_one(self):
++ """./foo/check_driver"""
++
++ def test_group_two(self):
++ """./foo/other_driver"""
++@end verbatim
++@end example
++
++In this example, running the test suite ShellTests in python (using any test
++runner - unittest.py, tribunal, trial, nose or others) will run
++./foo/check_driver and ./foo/other_driver and report on their result.
++
++Subunit is hosted on launchpad - the @uref{https://launchpad.net/subunit/,
++subunit} project there contains bug tracker, future plans, and source code
++control details.
++
+ @node Conclusion and References, AM_PATH_CHECK, Advanced Features, Top
+ @chapter Conclusion and References
+ The tutorial and description of advanced features has provided an
+
+=== modified file 'src/check.h.in'
+--- src/check.h.in 2006-12-08 17:47:49 +0000
++++ src/check.h.in 2007-04-21 06:59:27 +0000
+@@ -257,6 +257,9 @@
+ CK_NORMAL, /* All failed tests */
+ CK_VERBOSE, /* All tests */
+ CK_ENV, /* Look at environment var */
++#if @ENABLE_SUBUNIT@
++ CK_SUBUNIT, /* Run as a subunit child process */
++#endif
+ CK_LAST
+ };
+
+
+=== modified file 'src/check_impl.h'
+--- src/check_impl.h 2006-10-13 00:24:56 +0000
++++ src/check_impl.h 2007-04-21 01:55:36 +0000
+@@ -89,6 +89,7 @@
+ CLSTART_S,
+ CLEND_SR,
+ CLEND_S,
++ CLSTART_T, /* A test case is about to run */
+ CLEND_T
+ };
+
+
+=== modified file 'src/check_log.c'
+--- src/check_log.c 2006-10-13 04:10:50 +0000
++++ src/check_log.c 2007-04-21 06:59:27 +0000
+@@ -25,12 +25,16 @@
+ #include <sys/time.h>
+ #include <time.h>
+ #include <check.h>
++#if HAVE_SUBUNIT_CHILD_H
++#include <subunit/child.h>
++#endif
+
+ #include "check_error.h"
+ #include "check_list.h"
+ #include "check_impl.h"
+ #include "check_log.h"
+ #include "check_print.h"
++#include "check_str.h"
+
+
+ static void srunner_send_evt (SRunner *sr, void *obj, enum cl_event evt);
+@@ -107,6 +111,13 @@
+ srunner_send_evt (sr, s, CLEND_S);
+ }
+
++void log_test_start (SRunner *sr, TCase * tc, TF * tfun)
++{
++ char buffer[100];
++ snprintf(buffer, 99, "%s:%s", tc->name, tfun->name);
++ srunner_send_evt (sr, buffer, CLSTART_T);
++}
++
+ void log_test_end (SRunner *sr, TestResult *tr)
+ {
+ srunner_send_evt (sr, tr, CLEND_T);
+@@ -128,7 +139,6 @@
+ void stdout_lfun (SRunner *sr, FILE *file, enum print_output printmode,
+ void *obj, enum cl_event evt)
+ {
+- TestResult *tr;
+ Suite *s;
+
+ if (printmode == CK_ENV) {
+@@ -163,8 +173,9 @@
+ case CLEND_S:
+ s = obj;
+ break;
++ case CLSTART_T:
++ break;
+ case CLEND_T:
+- tr = obj;
+ break;
+ default:
+ eprintf("Bad event type received in stdout_lfun", __FILE__, __LINE__);
+@@ -197,12 +208,14 @@
+ case CLEND_S:
+ s = obj;
+ break;
++ case CLSTART_T:
++ break;
+ case CLEND_T:
+ tr = obj;
+ tr_fprint(file, tr, CK_VERBOSE);
+ break;
+ default:
+- eprintf("Bad event type received in stdout_lfun", __FILE__, __LINE__);
++ eprintf("Bad event type received in lfile_lfun", __FILE__, __LINE__);
+ }
+
+
+@@ -250,6 +263,8 @@
+ fprintf(file, " </suite>\n");
+ s = obj;
+ break;
++ case CLSTART_T:
++ break;
+ case CLEND_T:
+ tr = obj;
+ tr_xmlprint(file, tr, CK_VERBOSE);
+@@ -260,6 +275,66 @@
+
+ }
+
++#if ENABLE_SUBUNIT
++void subunit_lfun (SRunner *sr, FILE *file, enum print_output printmode,
++ void *obj, enum cl_event evt)
++{
++ TestResult *tr;
++ Suite *s;
++ char const * name;
++
++ /* assert(printmode == CK_SUBUNIT); */
++
++ switch (evt) {
++ case CLINITLOG_SR:
++ break;
++ case CLENDLOG_SR:
++ break;
++ case CLSTART_SR:
++ break;
++ case CLSTART_S:
++ s = obj;
++ break;
++ case CLEND_SR:
++ if (printmode > CK_SILENT) {
++ fprintf (file, "\n");
++ srunner_fprint (file, sr, printmode);
++ }
++ break;
++ case CLEND_S:
++ s = obj;
++ break;
++ case CLSTART_T:
++ name = obj;
++ subunit_test_start(name);
++ break;
++ case CLEND_T:
++ tr = obj;
++ {
++ char *name = ck_strdup_printf ("%s:%s", tr->tcname, tr->tname);
++ char *msg = tr_short_str (tr);
++ switch (tr->rtype) {
++ case CK_PASS:
++ subunit_test_pass(name);
++ break;
++ case CK_FAILURE:
++ subunit_test_fail(name, msg);
++ break;
++ case CK_ERROR:
++ subunit_test_error(name, msg);
++ break;
++ default:
++ eprintf("Bad result type in subunit_lfun", __FILE__, __LINE__);
++ free(name);
++ free(msg);
++ }
++ }
++ break;
++ default:
++ eprintf("Bad event type received in subunit_lfun", __FILE__, __LINE__);
++ }
++}
++#endif
+
+ FILE *srunner_open_lfile (SRunner *sr)
+ {
+@@ -289,7 +364,14 @@
+ {
+ FILE *f;
+ sr->loglst = check_list_create();
+- srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
++#if ENABLE_SUBUNIT
++ if (print_mode != CK_SUBUNIT)
++#endif
++ srunner_register_lfun (sr, stdout, 0, stdout_lfun, print_mode);
++#if ENABLE_SUBUNIT
++ else
++ srunner_register_lfun (sr, stdout, 0, subunit_lfun, print_mode);
++#endif
+ f = srunner_open_lfile (sr);
+ if (f) {
+ srunner_register_lfun (sr, f, 1, lfile_lfun, print_mode);
+
+=== modified file 'src/check_log.h'
+--- src/check_log.h 2006-10-13 00:24:56 +0000
++++ src/check_log.h 2007-04-21 01:55:36 +0000
+@@ -26,6 +26,7 @@
+ void log_suite_start (SRunner *sr, Suite *s);
+ void log_suite_end (SRunner *sr, Suite *s);
+ void log_test_end (SRunner *sr, TestResult *tr);
++void log_test_start (SRunner *sr, TCase *tc, TF *tfun);
+
+ void stdout_lfun (SRunner *sr, FILE *file, enum print_output,
+ void *obj, enum cl_event evt);
+@@ -36,6 +37,9 @@
+ void xml_lfun (SRunner *sr, FILE *file, enum print_output,
+ void *obj, enum cl_event evt);
+
++void subunit_lfun (SRunner *sr, FILE *file, enum print_output,
++ void *obj, enum cl_event evt);
++
+ void srunner_register_lfun (SRunner *sr, FILE *lfile, int close,
+ LFun lfun, enum print_output);
+
+
+=== modified file 'src/check_print.c'
+--- src/check_print.c 2006-10-13 00:24:56 +0000
++++ src/check_print.c 2007-04-21 06:59:27 +0000
+@@ -54,6 +54,11 @@
+ static void srunner_fprint_summary (FILE *file, SRunner *sr,
+ enum print_output print_mode)
+ {
++#if ENABLE_SUBUNIT
++ if (print_mode == CK_SUBUNIT)
++ return;
++#endif
++
+ if (print_mode >= CK_MINIMAL) {
+ char *str;
+
+@@ -68,6 +73,11 @@
+ enum print_output print_mode)
+ {
+ List *resultlst;
++
++#if ENABLE_SUBUNIT
++ if (print_mode == CK_SUBUNIT)
++ return;
++#endif
+
+ resultlst = sr->resultlst;
+
+
+=== modified file 'src/check_run.c'
+--- src/check_run.c 2006-11-18 01:02:13 +0000
++++ src/check_run.c 2007-04-21 01:55:36 +0000
+@@ -188,6 +188,7 @@
+
+ for (i = tfun->loop_start; i < tfun->loop_end; i++)
+ {
++ log_test_start (sr, tc, tfun);
+ switch (srunner_fork_status(sr)) {
+ case CK_FORK:
+ tr = tcase_run_tfun_fork (sr, tc, tfun, i);
+
+=== modified file 'src/check_str.c'
+--- src/check_str.c 2006-10-13 00:24:56 +0000
++++ src/check_str.c 2007-04-21 01:55:36 +0000
+@@ -47,6 +47,20 @@
+ return rstr;
+ }
+
++char *tr_short_str (TestResult *tr)
++{
++ const char *exact_msg;
++ char *rstr;
++
++ exact_msg = (tr->rtype == CK_ERROR) ? "(after this point) ": "";
++
++ rstr = ck_strdup_printf ("%s:%d: %s%s",
++ tr->file, tr->line,
++ exact_msg, tr->msg);
++
++ return rstr;
++}
++
+ char *sr_stat_str (SRunner *sr)
+ {
+ char *str;
+
+=== modified file 'src/check_str.h'
+--- src/check_str.h 2006-10-13 00:24:56 +0000
++++ src/check_str.h 2007-04-21 01:55:36 +0000
+@@ -25,6 +25,12 @@
+ value has been malloc'd, and must be freed by the caller */
+ char *tr_str (TestResult *tr);
+
++/* Return a string representation of the given TestResult message
++ without the test id or result type. This is suitable for separate
++ formatting of the test and the message. Return value has been
++ malloc'd, and must be freed by the caller */
++char *tr_short_str (TestResult *tr);
++
+ /* Return a string representation of the given SRunner's run
+ statistics (% passed, num run, passed, errors, failures). Return
+ value has been malloc'd, and must be freed by the caller
+
+=== modified file 'tests/Makefile.am'
+--- tests/Makefile.am 2006-11-17 08:56:43 +0000
++++ tests/Makefile.am 2007-04-21 06:59:27 +0000
+@@ -15,7 +15,7 @@
+ ex_xml_output \
+ ex_log_output
+
+-EXTRA_DIST = test_output.sh test_log_output.sh test_xml_output.sh
++EXTRA_DIST = test_output.sh test_log_output.sh test_vars.in test_xml_output.sh
+
+ if NO_TIMEOUT_TESTS
+ check_check_CFLAGS = -DTIMEOUT_TESTS_ENABLED=0
+
+=== modified file 'tests/check_check_log.c'
+--- tests/check_check_log.c 2006-10-13 00:24:56 +0000
++++ tests/check_check_log.c 2007-04-21 06:59:27 +0000
+@@ -2,6 +2,9 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <check.h>
++#include <check_list.h>
++#include <check_impl.h>
++#include <check_log.h>
+ #include "check_check.h"
+
+
+@@ -78,15 +81,40 @@
+ }
+ END_TEST
+
++#if ENABLE_SUBUNIT
++START_TEST(test_init_logging_subunit)
++{
++ /* init_logging with CK_SUBUNIT sets stdout
++ * to a subunit function, not any log.
++ */
++ Log * first_log = NULL;
++ Suite *s = suite_create("Suite");
++ SRunner *sr = srunner_create(s);
++ srunner_init_logging(sr, CK_SUBUNIT);
++ list_front (sr->loglst);
++ fail_if (list_at_end(sr->loglst), "No entries in log list");
++ first_log = list_val(sr->loglst);
++ fail_if (first_log == NULL, "log is NULL");
++ list_advance(sr->loglst);
++ fail_unless(list_at_end(sr->loglst), "More than one entry in log list");
++ fail_unless(first_log->lfun == subunit_lfun,
++ "Log function is not the subunit lfun.");
++ srunner_end_logging(sr);
++ srunner_free(sr);
++}
++END_TEST
++#endif
++
+ Suite *make_log_suite(void)
+ {
+
+ Suite *s;
+- TCase *tc_core, *tc_core_xml;
++ TCase *tc_core, *tc_core_xml, *tc_core_subunit;
+
+ s = suite_create("Log");
+ tc_core = tcase_create("Core");
+ tc_core_xml = tcase_create("Core XML");
++ tc_core_subunit = tcase_create("Core SubUnit");
+
+ suite_add_tcase(s, tc_core);
+ tcase_add_test(tc_core, test_set_log);
+@@ -98,6 +126,11 @@
+ tcase_add_test(tc_core_xml, test_no_set_xml);
+ tcase_add_test(tc_core_xml, test_double_set_xml);
+
++#if ENABLE_SUBUNIT
++ suite_add_tcase(s, tc_core_subunit);
++ tcase_add_test(tc_core_subunit, test_init_logging_subunit);
++#endif
++
+ return s;
+ }
+
+
+=== modified file 'tests/ex_output.c'
+--- tests/ex_output.c 2006-10-13 00:24:56 +0000
++++ tests/ex_output.c 2007-04-21 06:59:27 +0000
+@@ -2,6 +2,7 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <check.h>
++#include "config.h"
+
+ START_TEST(test_pass)
+ {
+@@ -47,11 +48,20 @@
+ srunner_free(sr);
+ }
+
++static void print_usage(void)
++{
++ printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE");
++#if ENABLE_SUBUNIT
++ printf (" | CK_SUBUNIT");
++#endif
++ printf (")\n");
++}
++
+ int main (int argc, char **argv)
+ {
+
+ if (argc != 2) {
+- printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE)\n");
++ print_usage();
+ return EXIT_FAILURE;
+ }
+
+@@ -63,8 +73,12 @@
+ run_tests(CK_NORMAL);
+ else if (strcmp (argv[1], "CK_VERBOSE") == 0)
+ run_tests(CK_VERBOSE);
++#if ENABLE_SUBUNIT
++ else if (strcmp (argv[1], "CK_SUBUNIT") == 0)
++ run_tests(CK_SUBUNIT);
++#endif
+ else {
+- printf ("Usage: ex_output (CK_SILENT | CK_MINIMAL | CK_NORMAL | CK_VERBOSE)\n");
++ print_usage();
+ return EXIT_FAILURE;
+ }
+
+
+=== modified file 'tests/test_output.sh'
+--- tests/test_output.sh 2006-10-13 00:24:56 +0000
++++ tests/test_output.sh 2007-04-21 06:59:27 +0000
+@@ -1,5 +1,7 @@
+ #!/bin/sh
+
++. "${srcdir}/"test_vars
++
+ if [ "${srcdir}" = "." ]; then
+ lsrc=""
+ else
+@@ -18,12 +20,24 @@
+ ${lsrc}ex_output.c:8:P:Core:test_pass:0: Passed
+ ${lsrc}ex_output.c:14:F:Core:test_fail:0: Failure
+ ${lsrc}ex_output.c:18:E:Core:test_exit:0: (after this point) Early exit with return value 1"
++t4="xtest: Core:test_pass
++success: Core:test_pass
++test: Core:test_fail
++failure: Core:test_fail [
++${lsrc}ex_output.c:14: Failure
++]
++test: Core:test_exit
++error: Core:test_exit [
++${lsrc}ex_output.c:18: (after this point) Early exit with return value 1
++]"
+
+ op0=`./ex_output CK_SILENT`
+ op1=`./ex_output CK_MINIMAL`
+ op2=`./ex_output CK_NORMAL`
+ op3=`./ex_output CK_VERBOSE`
+-
++if test 1 -eq $ENABLE_SUBUNIT; then
++op4=`./ex_output CK_SUBUNIT`
++fi
+
+ test_output ( ) {
+ if [ "${1}" != "${2}" ]; then
+@@ -41,4 +55,7 @@
+ test_output "$t1" x"$op1" "CK_MINIMAL";
+ test_output "$t2" x"$op2" "CK_NORMAL";
+ test_output "$t3" x"$op3" "CK_VERBOSE";
++if test 1 -eq $ENABLE_SUBUNIT; then
++test_output "$t4" x"$op4" "CK_SUBUNIT";
++fi
+ exit 0
+