]> granicus.if.org Git - check/commitdiff
Added support for testing on expected signals.
authorhugo303 <hugo303@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Mon, 8 Nov 2004 14:40:05 +0000 (14:40 +0000)
committerhugo303 <hugo303@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Mon, 8 Nov 2004 14:40:05 +0000 (14:40 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@196 64e312b2-a51f-0410-8e61-82d0ca0eb02a

check/ChangeLog
check/src/check.c
check/src/check.h.in
check/src/check_impl.h
check/src/check_run.c

index 6f9a66cf832c1afb6383901d799f9c8900962014..09c26c33faa18a5a27ca0f24709be3023dd8391f 100644 (file)
@@ -1,3 +1,11 @@
+2004-11-08 hugo303
+
+       * src/check.c, src/check.h.in, src/check_impl.h, src/check_run.c,
+       tests/check_check_master.c, tests/check_check_sub.c:
+       Added support for testing on expected signals. Implementation
+       courtesy of Lucas Di Pentima and Cesar Ballardini. Also cleaned
+       up the test verification to simplify merging of new tests.
+
 2004-11-04 hugo303
 
         * src/check.c, src/check_list.c, src/check_list.h, src/check_log.c,
index 57939c78c630dbb40a7274fb77339046a8caeb9a..ade673d60908b3031998113e83117503be696ca5 100644 (file)
@@ -108,13 +108,14 @@ void suite_add_tcase (Suite *s, TCase *tc)
   list_add_end (s->tclst, tc);
 }
 
-void _tcase_add_test (TCase *tc, TFun fn, const char *name)
+void _tcase_add_test (TCase *tc, TFun fn, const char *name, int signal)
 {
   TF * tf;
   if (tc == NULL || fn == NULL || name == NULL)
     return;
   tf = emalloc (sizeof(TF)); /* freed in tcase_free */
   tf->fn = fn;
+  tf->signal = signal; /* 0 means no signal expected */
   tf->name = name;
   list_add_end (tc->tflst, tf);
 }
index 07c893b077353abb98675972aab250c6efe0ca19..d96091b4820440f6329b488e076e9502a8724e24 100644 (file)
@@ -101,11 +101,14 @@ TCase *tcase_create (const char *name);
 
 /* Add a test function to a test case
   (macro version) */
-#define tcase_add_test(tc,tf) _tcase_add_test(tc,tf,"" # tf "")
+#define tcase_add_test(tc,tf) tcase_add_test_raise_signal(tc,tf,0)
+
+#define tcase_add_test_raise_signal(tc,tf,signal) \
+   _tcase_add_test((tc),(tf),"" # tf "",(signal))
 
 /* Add a test function to a test case
   (function version -- use this when the macro won't work */
-void _tcase_add_test (TCase *tc, TFun tf, const char *fname);
+void _tcase_add_test (TCase *tc, TFun tf, const char *fname, int signal);
 
 /* Add unchecked fixture setup/teardown functions to a test case
 
@@ -183,7 +186,8 @@ void _mark_point (const char *file, int line);
 enum test_result {
   CK_PASS, /* Test passed*/
   CK_FAILURE, /* Test completed but failed */
-  CK_ERROR /* Test failed to complete (signal or non-zero early exit) */
+  CK_ERROR /* Test failed to complete
+             (unexpected signal or non-zero early exit) */ 
 };
 
 /* Specifies the how much output an SRunner should produce */
index 9f19c093a75799f287dd94605f5ce235af888b13..6cab6552964fd94cd459fa1028a8ad90a080c031 100644 (file)
@@ -36,6 +36,7 @@
 typedef struct TF {
   TFun fn;
   const char *name;
+  int signal;
 } TF;
 
 struct Suite {
index 31ca4ee510b78c8873ce31e107636f3c4a78228b..f49eb3954b4b58ce62d44f8bdebef36ace6b3b29 100644 (file)
@@ -64,15 +64,17 @@ static void srunner_add_failure (SRunner *sr, TestResult *tf);
 static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tf);
 static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tf);
 static TestResult *receive_result_info_fork (const char *tcname,
-                                             const char *tname, int status);
+                                             const char *tname,
+                                            int status, int expected_signal);
 static TestResult *receive_result_info_nofork (const char *tcname,
                                                const char *tname);
-static void set_fork_info (TestResult *tr, int status);
+static void set_fork_info (TestResult *tr, int status, int expected_signal);
 static void set_nofork_info (TestResult *tr);
 static char *signal_msg (int sig);
+static char *signal_error_msg (int signal_received, int signal_expected);
 static char *pass_msg (void);
 static char *exit_msg (int exitstatus);
-static int waserror (int status);
+static int waserror (int status, int expected_signal);
 
 #define MSG_LEN 100
 
@@ -271,26 +273,25 @@ static void srunner_run_unchecked_teardown (SRunner *sr, TCase *tc)
 
 static void srunner_run_tcase (SRunner *sr, TCase *tc)
 {
-  
-  if (srunner_run_unchecked_setup (sr,tc)) {  
-  
+  if (srunner_run_unchecked_setup(sr,tc)) {
     srunner_iterate_tcase_tfuns(sr,tc);
-  
-    srunner_run_unchecked_teardown (sr, tc);
+    srunner_run_unchecked_teardown(sr, tc);
   }
 }
 
 static TestResult *receive_result_info_fork (const char *tcname,
-                                             const char *tname, int status)
+                                             const char *tname,
+                                            int status, int expected_signal)
 {
   TestResult *tr;
 
-  tr = receive_test_result (get_recv_key(), waserror(status));
+  tr = receive_test_result(get_recv_key(),
+                           waserror(status, expected_signal));
   if (tr == NULL)
     eprintf("Failed to receive test result", __FILE__, __LINE__);
   tr->tcname = tcname;
   tr->tname = tname;
-  set_fork_info(tr, status);
+  set_fork_info(tr, status, expected_signal);
 
   return tr;
 }
@@ -310,24 +311,43 @@ static TestResult *receive_result_info_nofork (const char *tcname,
   return tr;
 }
 
-static void set_fork_info (TestResult *tr, int status)
+static void set_fork_info (TestResult *tr, int status, int signal_expected)
 {
   int was_sig = WIFSIGNALED(status);
   int was_exit = WIFEXITED(status);
   int exit_status = WEXITSTATUS(status);
+  int signal_received = WTERMSIG(status);
 
   if (was_sig) {
-    tr->rtype = CK_ERROR;
-    tr->msg = signal_msg(WTERMSIG(status));
-  } else if (was_exit && exit_status == 0) {
-    tr->rtype = CK_PASS;
-    tr->msg = pass_msg();
-  } else if (was_exit && exit_status != 0) {
-    if (tr->msg == NULL) { /* early exit */
+    if (signal_expected == signal_received) {
+      tr->rtype = CK_PASS;
+      tr->msg = pass_msg();
+    } else if (signal_expected != 0) { /* signal received, but no the expected one */
+      tr->rtype = CK_ERROR;
+      tr->msg = signal_error_msg(signal_received, signal_expected);
+    } else {                           /* signal received and none expected */
       tr->rtype = CK_ERROR;
+      tr->msg = signal_msg(signal_received);
+    }
+  } else if (signal_expected == 0) {
+    if (was_exit && exit_status == 0) {
+      tr->rtype = CK_PASS;
+      tr->msg = pass_msg();
+    } else if (was_exit && exit_status != 0) {
+      if (tr->msg == NULL) { /* early exit */
+        tr->rtype = CK_ERROR;
+        tr->msg = exit_msg(exit_status);
+      } else {
+        tr->rtype = CK_FAILURE;
+      }
+    }
+  } else { /* a signal was expected and none raised */
+    if (was_exit) {
       tr->msg = exit_msg(exit_status);
-    } else {
-      tr->rtype = CK_FAILURE;
+      if (exit_status == 0)
+       tr->rtype = CK_FAILURE; /* normal exit status */
+      else
+       tr->rtype = CK_FAILURE; /* early exit */
     }
   }
 }
@@ -364,15 +384,23 @@ static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun)
 
   pid = fork();
   if (pid == -1)
-     eprintf ("Unable to fork:",__FILE__,__LINE__);
+     eprintf("Unable to fork:",__FILE__,__LINE__);
   if (pid == 0) {
-    tcase_run_checked_setup (sr, tc);
+    tcase_run_checked_setup(sr, tc);
     tfun->fn();
-    tcase_run_checked_teardown (tc);
+    tcase_run_checked_teardown(tc);
     exit(EXIT_SUCCESS);
   }
   (void) wait(&status);
-  return receive_result_info_fork (tc->name, tfun->name, status);
+  return receive_result_info_fork(tc->name, tfun->name, status, tfun->signal);
+}
+
+static char *signal_error_msg (int signal_received, int signal_expected)
+{
+  char *msg = emalloc (MSG_LEN); /* free'd by caller */
+  snprintf (msg, MSG_LEN, "Error: Received signal %d, expected %d",
+            signal_received, signal_expected);
+  return msg;
 }
 
 static char *signal_msg (int signal)
@@ -416,11 +444,13 @@ void srunner_set_fork_status (SRunner *sr, enum fork_status fstat)
   sr->fstat = fstat;
 }
 
-static int waserror (int status)
+static int waserror (int status, int signal_expected)
 {
   int was_sig = WIFSIGNALED (status);
   int was_exit = WIFEXITED (status);
   int exit_status = WEXITSTATUS (status);
+  int signal_received = WTERMSIG(status);
 
-  return (was_sig || (was_exit && exit_status != 0));
+  return ((was_sig && (signal_received != signal_expected)) ||
+          (was_exit && exit_status != 0));
 }