#include "check_log.h"
+enum rinfo {
+ CK_R_SIG,
+ CK_R_PASS,
+ CK_R_EXIT,
+ CK_R_FAIL_TEST,
+ CK_R_FAIL_FIXTURE
+};
+
+enum tf_type {
+ CK_FORK_TEST,
+ CK_NOFORK_TEST,
+ CK_NOFORK_FIXTURE
+};
+
+
+static void receive_failure_info (MsgSys *msgsys,
+ TestResult *tr,
+ enum tf_type tf_type,
+ int status);
+
+
static void srunner_run_init (SRunner *sr, enum print_output print_mode);
static void srunner_run_end (SRunner *sr, enum print_output print_mode);
static void srunner_iterate_suites (SRunner *sr,
static int srunner_run_setup (SRunner *sr, TCase *tc, MsgSys *msgsys);
static void srunner_iterate_tcase_tfuns (SRunner *sr, TCase *tc);
static void srunner_add_failure (SRunner *sr, TestResult *tf);
-static TestResult *tfun_run (char *tcname, TF *tf);
+static TestResult *tfun_run_fork (char *tcname, TF *tf);
static TestResult *tfun_run_nofork (char *tcname, TF *tf);
-static TestResult *receive_result_info (MsgSys *msgsys, int status, char *tcname);
+static TestResult *receive_result_info (MsgSys *msgsys, char *tcname,
+ enum tf_type, int status);
static TestResult *receive_result_info_nofork (MsgSys *msgsys, char *tcname);
static TestResult *receive_result_info_setup (MsgSys *msgsys, char *tcname);
+static enum test_result result_info_rtype (enum rinfo rinfo);
+static enum rinfo result_info (enum tf_type tf_type, char *msg, int status);
+static char *result_info_msg (enum rinfo rinfo, char *fmsg, int status);
static void receive_last_loc_info (MsgSys *msgsys, TestResult *tr);
-static void receive_failure_info (MsgSys *msgsys, int status, TestResult *tr);
static char *signal_msg (int sig);
static char *exit_msg (int exitstatus);
tfun = list_val (tfl);
switch (srunner_fork_status(sr)) {
case CK_FORK:
- tr = tfun_run (tc->name, tfun);
+ tr = tfun_run_fork (tc->name, tfun);
break;
case CK_NOFORK:
tr = tfun_run_nofork (tc->name, tfun);
}
}
-static void receive_failure_info (MsgSys *msgsys, int status, TestResult *tr)
-{
- char *fmsg;
- if (WIFSIGNALED(status)) {
- tr->rtype = CK_ERROR;
- tr->msg = signal_msg (WTERMSIG(status));
- return;
- }
-
- if (WIFEXITED(status)) {
-
- if (WEXITSTATUS(status) == 0) {
- tr->rtype = CK_PASS;
- /* TODO: It would be cleaner to strdup this &
- not special case the free...*/
- tr->msg = "Test passed";
- }
- else {
-
- fmsg = receive_failure_msg (msgsys);
- if (fmsg == NULL) { /* implies early exit */
- tr->rtype = CK_ERROR;
- tr->msg = exit_msg (WEXITSTATUS(status));
- }
- else {
- tr->rtype = CK_FAILURE;
- tr->msg = emalloc(strlen(fmsg) + 1);
- strcpy (tr->msg, fmsg);
- free (fmsg);
- }
- }
- } else {
- eprintf ("Bad status from wait() call\n");
- }
-}
-
-static TestResult *receive_result_info (MsgSys *msgsys, int status, char *tcname)
+static TestResult *receive_result_info (MsgSys *msgsys, char *tcname,
+ enum tf_type tf_type, int status)
{
TestResult *tr = emalloc (sizeof(TestResult));
tr->tcname = tcname;
receive_last_loc_info (msgsys, tr);
- receive_failure_info (msgsys, status, tr);
+ receive_failure_info (msgsys, tr, tf_type, status);
return tr;
}
+static TestResult *receive_result_info_fork (MsgSys *msgsys, char *tcname,
+ int status)
+{
+ return receive_result_info (msgsys, tcname, CK_FORK_TEST, status);
+}
+
static TestResult *receive_result_info_nofork (MsgSys *msgsys, char *tcname)
{
- /*TODO: lots of overlap with receive_failure_info
- Find a way to generalize */
+ return receive_result_info (msgsys,tcname, CK_NOFORK_TEST, 0);
+}
- char *fmsg;
- TestResult *tr = emalloc (sizeof(TestResult));
- tr->tcname = tcname;
-
- receive_last_loc_info (msgsys, tr);
- fmsg = receive_failure_msg (msgsys);
+static TestResult *receive_result_info_setup (MsgSys *msgsys, char *tcname)
+{
+ return receive_result_info (msgsys,tcname, CK_NOFORK_FIXTURE, 0);
+}
+
+
+static enum rinfo result_info (enum tf_type tf_type, char *msg, int status)
+{
+ enum rinfo rinfo = -1;
- if (fmsg == NULL) { /* we got through the procedure */
- tr->rtype = CK_PASS;
- tr->msg = "Test passed";
+ if (tf_type == CK_FORK_TEST) {
+ int was_sig = WIFSIGNALED(status);
+ int was_exit = WIFEXITED(status);
+ int exit_status = WEXITSTATUS(status);
+
+ if (was_sig)
+ rinfo = CK_R_SIG;
+ else if (was_exit && exit_status == 0)
+ rinfo = CK_R_PASS;
+ else if (was_exit && exit_status != 0) {
+ if (msg == NULL) /* early exit */
+ rinfo = CK_R_EXIT;
+ else
+ rinfo = CK_R_FAIL_TEST;
+ } else
+ eprintf ("Bad status from wait() call\n");
+ } else {
+ if (msg == NULL)
+ rinfo = CK_R_PASS;
+ else if (tf_type == CK_NOFORK_FIXTURE)
+ rinfo = CK_R_FAIL_FIXTURE;
+ else
+ rinfo = CK_R_FAIL_TEST;
}
- else {
- tr->rtype = CK_FAILURE;
- tr->msg = emalloc(strlen(fmsg) + 1);
- strcpy (tr->msg, fmsg);
- free (fmsg);
+
+ return rinfo;
+}
+
+
+static enum test_result result_info_rtype (enum rinfo rinfo)
+{
+ enum test_result rtype = -1;
+ switch (rinfo) {
+ case CK_R_SIG:
+ rtype = CK_ERROR;
+ break;
+ case CK_R_PASS:
+ rtype = CK_PASS;
+ break;
+ case CK_R_EXIT:
+ rtype = CK_ERROR;
+ break;
+ case CK_R_FAIL_TEST:
+ rtype = CK_FAILURE;
+ break;
+ case CK_R_FAIL_FIXTURE:
+ rtype = CK_FIXTURE;
+ break;
+ default: eprintf ("Bad parameter value in result_info_rtype");
}
- return tr;
+ return rtype;
}
-static TestResult *receive_result_info_setup (MsgSys *msgsys, char *tcname)
+static char * result_info_msg (enum rinfo rinfo, char *fmsg, int status)
{
- /*TODO: lots of overlap with receive_failure_info
- Find a way to generalize */
+ char *msg = NULL;
+
+ switch (rinfo) {
+ case CK_R_SIG:
+ msg = signal_msg (WTERMSIG(status));
+ break;
+ case CK_R_PASS:
+ msg = emalloc (sizeof("Test passed"));
+ strcpy (msg,"Test passed");
+ break;
+ case CK_R_EXIT:
+ msg = exit_msg(WEXITSTATUS(status));
+ break;
+ case CK_R_FAIL_TEST: /* fall through */
+ case CK_R_FAIL_FIXTURE:
+ msg = emalloc(strlen(fmsg) + 1);
+ strcpy (msg, fmsg);
+ break;
+ default: eprintf ("Bad parameter value in result_info_rtype");
+ }
+
+ return msg;
+}
+static void receive_failure_info (MsgSys *msgsys,
+ TestResult *tr,
+ enum tf_type tf_type,
+ int status)
+{
char *fmsg;
- TestResult *tr = emalloc (sizeof(TestResult));
+ enum rinfo rinfo;
- tr->tcname = tcname;
-
- receive_last_loc_info (msgsys, tr);
fmsg = receive_failure_msg (msgsys);
+
+ rinfo = result_info (tf_type, fmsg, status);
+ tr->rtype = result_info_rtype (rinfo);
+ tr->msg = result_info_msg (rinfo, fmsg, status);
- if (fmsg == NULL) { /* we got through the procedure */
- tr->rtype = CK_PASS;
- tr->msg = "Test passed";
- }
- else {
- tr->rtype = CK_FIXTURE;
- tr->msg = emalloc(strlen(fmsg) + 1);
- strcpy (tr->msg, fmsg);
+ if (fmsg != NULL)
free (fmsg);
- }
- return tr;
-}
+}
static TestResult *tfun_run_nofork (char *tcname, TF *tfun)
{
}
-static TestResult *tfun_run (char *tcname, TF *tfun)
+static TestResult *tfun_run_fork (char *tcname, TF *tfun)
{
pid_t pid;
int status = 0;
_exit(EXIT_SUCCESS);
}
(void) wait(&status);
- return receive_result_info(msgsys, status, tcname);
+ return receive_result_info_fork (msgsys, tcname, status);
}
static char *signal_msg (int signal)