From 7041b065a5f9da9901dba4cd95c93eda1a7462eb Mon Sep 17 00:00:00 2001 From: zdenekc Date: Wed, 1 Jun 2011 09:41:28 +0000 Subject: [PATCH] * fix failed test exit in no-fork mode git-svn-id: https://check.svn.sourceforge.net/svnroot/check/trunk@603 64e312b2-a51f-0410-8e61-82d0ca0eb02a --- NEWS | 5 +++++ src/check.c | 2 ++ src/check_error.c | 6 ++++++ src/check_error.h | 4 ++++ src/check_run.c | 25 +++++++++++++++++++------ tests/Makefile.am | 5 +++++ tests/check_nofork.c | 37 +++++++++++++++++++++++++++++++++++++ tests/test_check_nofork.sh | 14 ++++++++++++++ 8 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 tests/check_nofork.c create mode 100755 tests/test_check_nofork.sh diff --git a/NEWS b/NEWS index ef52353fe2eb8214aeac87bbfd23dd349525761b..7aa15ee931c412c9ff027dbcb52068db57bee1da 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +In development. + +* Added longjmp to fail function to ensure that no code will be executed in test + function after failed assertion + Tue, Sep 22, 2009: Released Check 0.9.8 based on r559 (2009-09-23 21:00). diff --git a/src/check.c b/src/check.c index 41b9e793cd8c0e85261c1537bc10ad7aec7cb375..a8e8a983d20c18d7aec7ecad6cea2de37ecd2760 100644 --- a/src/check.c +++ b/src/check.c @@ -232,6 +232,8 @@ void _fail_unless (int result, const char *file, #ifdef _POSIX_VERSION exit(1); #endif /* _POSIX_VERSION */ + } else { + longjmp(error_jmp_buffer, 1); } } } diff --git a/src/check_error.c b/src/check_error.c index 5ed0c1d8ae48eb153ae6f929f48680f629de04f5..588f616ac0925fdf067b8572c45b13e4f7edec0f 100644 --- a/src/check_error.c +++ b/src/check_error.c @@ -25,9 +25,15 @@ #include #include #include +#include #include "check_error.h" +/** + * Storage for setjmp/longjmp context information used in NOFORK mode + */ +jmp_buf error_jmp_buffer; + /* FIXME: including a colon at the end is a bad way to indicate an error */ void eprintf (const char *fmt, const char *file, int line, ...) diff --git a/src/check_error.h b/src/check_error.h index 2e1e211bea24f364b085692d569bed7aa529204c..75be45db7b7c883ae886e272502d16177453bd33 100644 --- a/src/check_error.h +++ b/src/check_error.h @@ -21,6 +21,10 @@ #ifndef ERROR_H #define ERROR_H +#include + +extern jmp_buf error_jmp_buffer; + /* Include stdlib.h beforehand */ /* Print error message and die diff --git a/src/check_run.c b/src/check_run.c index 374bf4a0c7ad26402c21f480a02926a0373ec172..faa3ee16f81509c833ebf0d4d42182c11e209631 100644 --- a/src/check_run.c +++ b/src/check_run.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "check.h" #include "check_error.h" @@ -48,6 +49,7 @@ enum tf_type { CK_NOFORK_FIXTURE }; + /* all functions are defined in the same order they are declared. functions that depend on forking are gathered all together. non-static functions are at the end of the file. */ @@ -205,7 +207,10 @@ static int srunner_run_unchecked_setup (SRunner *sr, TCase *tc) for (list_front(l); !list_at_end(l); list_advance(l)) { send_ctx_info(CK_CTX_SETUP); f = list_val(l); - f->fun(); + + if ( 0 == setjmp(error_jmp_buffer) ) { + f->fun(); + } tr = receive_result_info_nofork (tc->name, "unchecked_setup", 0); @@ -229,18 +234,24 @@ static TestResult * tcase_run_checked_setup (SRunner *sr, TCase *tc) List *l; Fixture *f; enum fork_status fstat = srunner_fork_status(sr); - + l = tc->ch_sflst; if (fstat == CK_FORK) { send_ctx_info(CK_CTX_SETUP); } - + for (list_front(l); !list_at_end(l); list_advance(l)) { + f = list_val(l); + if (fstat == CK_NOFORK) { send_ctx_info(CK_CTX_SETUP); + + if ( 0 == setjmp(error_jmp_buffer) ) { + f->fun(); + } + } else { + f->fun(); } - f = list_val(l); - f->fun(); /* Stop the setup and return the failure if nofork mode. */ if (fstat == CK_NOFORK) { @@ -294,7 +305,9 @@ static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tfun, int tr = tcase_run_checked_setup(sr, tc); if (tr == NULL) { - tfun->fn(i); + if ( 0 == setjmp(error_jmp_buffer) ) { + tfun->fn(i); + } tcase_run_checked_teardown(tc); return receive_result_info_nofork(tc->name, tfun->name, i); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 0e8ddc70c0f7bccb24637f6f99ac1e6b2406a9cf..be00f040ed04daa07fca47230243dbb9f0f9c362 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,6 +4,7 @@ TESTS = \ check_check_export \ check_check \ test_output.sh \ + test_check_nofork.sh \ test_xml_output.sh \ test_log_output.sh @@ -20,6 +21,7 @@ noinst_PROGRAMS = \ check_check \ check_stress \ check_thread_stress \ + check_nofork \ ex_output \ ex_xml_output \ ex_log_output @@ -63,6 +65,9 @@ check_thread_stress_SOURCES = check_thread_stress.c check_thread_stress_LDADD = $(top_builddir)/src/libcheck.la $(top_builddir)/lib/libcompat.la @PTHREAD_LIBS@ check_thread_stress_CFLAGS = @PTHREAD_CFLAGS@ +check_nofork_SOURCES = check_nofork.c +check_nofork_LDADD = $(top_builddir)/src/libcheck.la $(top_builddir)/lib/libcompat.la + ex_output_SOURCES = ex_output.c ex_output_LDADD = $(top_builddir)/src/libcheck.la $(top_builddir)/lib/libcompat.la diff --git a/tests/check_nofork.c b/tests/check_nofork.c new file mode 100644 index 0000000000000000000000000000000000000000..f7310d7a3cf8c2c73f513b0b048ddef3aedb2639 --- /dev/null +++ b/tests/check_nofork.c @@ -0,0 +1,37 @@ +#include "../lib/libcompat.h" + +#include +#include +#include + + +Suite *s; +TCase *tc; +SRunner *sr; + +START_TEST(test_nofork_exit) +{ + char* s = NULL; + + ck_assert(NULL != s); + + /* this test should not crash in nofork mode */ + ck_assert_str_eq("test", s); +} +END_TEST + +int main(void) +{ + s = suite_create("NoFork"); + tc = tcase_create("Exit"); + sr = srunner_create(s); + + suite_add_tcase(s, tc); + tcase_add_test(tc, test_nofork_exit); + + srunner_set_fork_status(sr, CK_NOFORK); + srunner_run_all(sr, CK_MINIMAL); + srunner_free(sr); + + return 0; +} diff --git a/tests/test_check_nofork.sh b/tests/test_check_nofork.sh new file mode 100755 index 0000000000000000000000000000000000000000..62276e93541ffc1d683d9fbb40f55ef491d66ba8 --- /dev/null +++ b/tests/test_check_nofork.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +expected="Running suite(s): NoFork +0%: Checks: 1, Failures: 1, Errors: 0" + +actual=`./check_nofork 2>&1` +if [ x"${expected}" = x"${actual}" ]; then + exit 0 +else + echo "Problem with check_nofork" + echo "Expected: Failure" + echo "Got: Segmentation fault" + exit 1 +fi -- 1.7.10.1