list_add_end (s->tclst, tc);
}
-void _tcase_add_test (TCase *tc, TFun fn, const char *name, int _signal, int start, int end)
+void _tcase_add_test (TCase *tc, TFun fn, const char *name, int _signal, int allowed_exit_value, int start, int end)
{
TF * tf;
if (tc == NULL || fn == NULL || name == NULL)
tf->loop_start = start;
tf->loop_end = end;
tf->signal = _signal; /* 0 means no signal expected */
+ tf->allowed_exit_value = allowed_exit_value; /* 0 is default successful exit */
tf->name = name;
list_add_end (tc->tflst, tf);
}
/* Add a test function with signal handling to a test case (macro version) */
#define tcase_add_test_raise_signal(tc,tf,signal) \
- _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 1)
+ _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 0, 1)
+
+/* Add a test function with an expected exit value to a test case (macro version) */
+#define tcase_add_exit_test(tc, tf, expected_exit_value) \
+ _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),0,1)
/* Add a looping test function to a test case (macro version)
available in the test.
*/
#define tcase_add_loop_test(tc,tf,s,e) \
- _tcase_add_test((tc),(tf),"" # tf "",0,(s),(e))
+ _tcase_add_test((tc),(tf),"" # tf "",0,0,(s),(e))
/* Signal version of loop test.
FIXME: add a test case; this is untested as part of Check's tests.
*/
#define tcase_add_loop_test_raise_signal(tc,tf,signal,s,e) \
- _tcase_add_test((tc),(tf),"" # tf "",(signal),(s),(e))
+ _tcase_add_test((tc),(tf),"" # tf "",(signal),0,(s),(e))
+
+/* allowed exit value version of loop test. */
+#define tcase_add_loop_exit_test(tc,tf,expected_exit_value,s,e) \
+ _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),(s),(e))
/* Add a test function to a test case
(function version -- use this when the macro won't work
*/
-void CK_EXPORT _tcase_add_test (TCase *tc, TFun tf, const char *fname, int _signal, int start, int end);
+void CK_EXPORT _tcase_add_test (TCase *tc, TFun tf, const char *fname, int _signal, int allowed_exit_value, int start, int end);
/* Add unchecked fixture setup/teardown functions to a test case
int loop_end;
const char *name;
int signal;
+ unsigned char allowed_exit_value;
} TF;
struct Suite {
static TestResult *receive_result_info_fork (const char *tcname,
const char *tname,
int iter,
- int status, int expected_signal);
-static void set_fork_info (TestResult *tr, int status, int expected_signal);
+ int status, int expected_signal,
+ unsigned char allowed_exit_value);
+static void set_fork_info (TestResult *tr, int status, int expected_signal,
+ unsigned char allowed_exit_value);
static char *signal_msg (int sig);
static char *signal_error_msg (int signal_received, int signal_expected);
static char *exit_msg (int exitstatus);
killpg(pid, SIGKILL); /* Kill remaining processes. */
- return receive_result_info_fork(tc->name, tfun->name, i, status, tfun->signal);
+ return receive_result_info_fork(tc->name, tfun->name, i, status, tfun->signal, tfun->allowed_exit_value);
}
static TestResult *receive_result_info_fork (const char *tcname,
const char *tname,
int iter,
- int status, int expected_signal)
+ int status, int expected_signal,
+ unsigned char allowed_exit_value)
{
TestResult *tr;
tr->tcname = tcname;
tr->tname = tname;
tr->iter = iter;
- set_fork_info(tr, status, expected_signal);
+ set_fork_info(tr, status, expected_signal, allowed_exit_value);
return tr;
}
-static void set_fork_info (TestResult *tr, int status, int signal_expected)
+static void set_fork_info (TestResult *tr, int status, int signal_expected, unsigned char allowed_exit_value)
{
int was_sig = WIFSIGNALED(status);
int was_exit = WIFEXITED(status);
tr->msg = signal_msg(signal_received);
}
} else if (signal_expected == 0) {
- if (was_exit && exit_status == 0) {
+ if (was_exit && exit_status == allowed_exit_value) {
tr->rtype = CK_PASS;
tr->msg = pass_msg();
- } else if (was_exit && exit_status != 0) {
+ } else if (was_exit && exit_status != allowed_exit_value) {
if (tr->msg == NULL) { /* early exit */
tr->rtype = CK_ERROR;
tr->msg = exit_msg(exit_status);
} else { /* a signal was expected and none raised */
if (was_exit) {
tr->msg = exit_msg(exit_status);
- if (exit_status == 0)
+ if (exit_status == allowed_exit_value)
tr->rtype = CK_FAILURE; /* normal exit status */
else
tr->rtype = CK_FAILURE; /* early exit */
check_check_fork.c \
check_check_fixture.c \
check_check_pack.c \
+ check_check_exit.c \
check_check_main.c
check_check_LDADD = $(top_builddir)/src/libcheckinternal.la $(top_builddir)/lib/libcompat.la
Suite *make_fork_suite(void);
Suite *make_fixture_suite(void);
Suite *make_pack_suite(void);
+Suite *make_exit_suite(void);
extern int master_tests_lineno[];
void init_master_tests_lineno(void);
srunner_add_suite(sr, make_fork_suite());
srunner_add_suite(sr, make_fixture_suite());
srunner_add_suite(sr, make_pack_suite());
+ srunner_add_suite(sr, make_exit_suite());
printf ("Ran %d tests in subordinate suite\n", sub_ntests);
srunner_run_all (sr, CK_VERBOSE);