From e41a0e1821cf7631188b120df6be799b864bd1b7 Mon Sep 17 00:00:00 2001 From: hugo303 Date: Fri, 30 Sep 2005 11:43:03 +0000 Subject: [PATCH] Looping tests added git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@252 64e312b2-a51f-0410-8e61-82d0ca0eb02a --- check/ChangeLog | 14 ++++++++ check/NEWS | 23 ++++++++++-- check/src/check.c | 4 ++- check/src/check.h.in | 17 ++++++--- check/src/check_impl.h | 3 ++ check/src/check_print.c | 1 + check/src/check_run.c | 60 ++++++++++++++++++------------- check/src/check_str.c | 4 +-- check/tests/Makefile.am | 2 +- check/tests/check_check_fixture.c | 10 +++--- check/tests/check_check_master.c | 14 ++++---- check/tests/ex_xml_output.c | 7 ++++ check/tests/test_log_output.sh | 8 ++--- check/tests/test_output.sh | 10 +++--- check/tests/test_xml_output.sh | 25 +++++++++++++ 15 files changed, 145 insertions(+), 57 deletions(-) diff --git a/check/ChangeLog b/check/ChangeLog index c420383..97337bf 100644 --- a/check/ChangeLog +++ b/check/ChangeLog @@ -1,3 +1,17 @@ +2005-09-30 hugo303 + + * src/check.c, src/check.h.in, src/check_impl.h, src/check_print.c, + src/check_run.c, src/check_str.c, tests/Makefile.am, + tests/check_check_fixture.c, tests/check_check_master.c, + tests/ex_xml_output.c, tests/test_log_output.sh, tests/test_output.sh, + tests/test_xml_output.sh: + + Added a new kind of test, looping tests, which are called with a new + context for each loop iteration. This makes them ideal for table based + tests. Previously, with the loop in the test itself, only the first + error was caught and then the test would exit. Now all errors are + shown at once which should help in debugging. + 2005-09-15 hugo303 * configure.in, tests/check_check_sub.c, tests/check_check.h, diff --git a/check/NEWS b/check/NEWS index 3552b72..da01400 100644 --- a/check/NEWS +++ b/check/NEWS @@ -1,11 +1,30 @@ +Added a new kind of test, looping tests, which are called with a new +context for each loop iteration. This makes them ideal for table based +tests. Previously, with the loop in the test itself, only the first +error was caught and then the test would exit. Now all errors are +shown at once which should help in debugging + +Added possibility to turn off timeout tests in check's own unit tests +through configure option --enable-timeout-tests=no. + +Added coverage analysis for check's own unit tests. + + Thu, Aug 25, 2005: Released Check 0.9.3 Applied debian patches from debian maintainer. + Fixed documentation bug #1216502. + gcc 2.95.3 compatibility fixed (patch #1161654, bug #1211672). -Messaging refactored to make it work with forking tests, and also with threading tests on linux 2.4. Added check_fork and check_waitpid_and_exit to be used for forking tests. (bug # 1233585) + +Messaging refactored to make it work with forking tests, and also with +threading tests on linux 2.4. Added check_fork and check_waitpid_and_exit +to be used for forking tests. (bug # 1233585) + Timeout error message changed (feature request #1121452, bug #1160305). -fix check.spec for fc3 x86_64 (patch #1111782) + +Fix check.spec for fc3 x86_64 (patch #1111782) Fri, Nov 12, 2004: Released Check 0.9.2 diff --git a/check/src/check.c b/check/src/check.c index b973b55..59d7492 100644 --- a/check/src/check.c +++ b/check/src/check.c @@ -124,13 +124,15 @@ 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, int signal) +void _tcase_add_test (TCase *tc, TFun fn, const char *name, int signal, int start, int end) { TF * tf; if (tc == NULL || fn == NULL || name == NULL) return; tf = emalloc (sizeof(TF)); /* freed in tcase_free */ tf->fn = fn; + tf->loop_start = start; + tf->loop_end = end; tf->signal = signal; /* 0 means no signal expected */ tf->name = name; list_add_end (tc->tflst, tf); diff --git a/check/src/check.h.in b/check/src/check.h.in index de20af3..341f586 100644 --- a/check/src/check.h.in +++ b/check/src/check.h.in @@ -86,7 +86,7 @@ extern int check_micro_version; typedef struct TCase TCase; /* type for a test function */ -typedef void (*TFun) (void); +typedef void (*TFun) (int); /* type for a setup/teardown function */ typedef void (*SFun) (void); @@ -108,12 +108,21 @@ TCase *tcase_create (const char *name); /* 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)) + _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 1) +/* Add a looping test function to a test case (macro version) + + The test will be called in a for(i = s; i < e; i++) loop with each + iteration being executed in a new context. The loop variable 'i' is + available in the test. + */ +#define tcase_add_loop_test(tc,tf,s,e) \ + _tcase_add_test((tc),(tf),"" # tf "",0,(s),(e)) + /* 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, int signal); +void _tcase_add_test (TCase *tc, TFun tf, const char *fname, int signal, int start, int end); /* Add unchecked fixture setup/teardown functions to a test case @@ -159,7 +168,7 @@ void tcase_fn_start (const char *fname, const char *file, int line); One must use braces within a START_/END_ pair to declare new variables */ #define START_TEST(__testname)\ -static void __testname (void)\ +static void __testname (int i)\ {\ tcase_fn_start (""# __testname, __FILE__, __LINE__); diff --git a/check/src/check_impl.h b/check/src/check_impl.h index 12329c8..2a0dde9 100644 --- a/check/src/check_impl.h +++ b/check/src/check_impl.h @@ -35,6 +35,8 @@ typedef struct TF { TFun fn; + int loop_start; + int loop_end; const char *name; int signal; } TF; @@ -71,6 +73,7 @@ struct TestResult { enum ck_result_ctx ctx; /* When the result occurred */ char *file; /* File where the test occured */ int line; /* Line number where the test occurred */ + int iter; /* The iteration value for looping tests */ const char *tcname; /* Test case that generated the result */ const char *tname; /* Test that generated the result */ char *msg; /* Failure message */ diff --git a/check/src/check_print.c b/check/src/check_print.c index 1c50e3f..3e011ea 100644 --- a/check/src/check_print.c +++ b/check/src/check_print.c @@ -126,6 +126,7 @@ void tr_xmlprint (FILE *file, TestResult *tr, enum print_output print_mode) fprintf(file, " %s\n", path_name); fprintf(file, " %s:%d\n", file_name, tr->line); fprintf(file, " %s\n", tr->tname); + fprintf(file, " %d\n", tr->iter); fprintf(file, " %s\n", tr->tcname); fprintf(file, " %s\n", tr->msg); fprintf(file, " \n"); diff --git a/check/src/check_run.c b/check/src/check_run.c index b0e99a1..72942ad 100644 --- a/check/src/check_run.c +++ b/check/src/check_run.c @@ -63,13 +63,15 @@ static TestResult * tcase_run_checked_setup (SRunner *sr, TCase *tc); static void tcase_run_checked_teardown (TCase *tc); static void srunner_iterate_tcase_tfuns (SRunner *sr, TCase *tc); 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 *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tf, int i); +static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tf, int i); static TestResult *receive_result_info_fork (const char *tcname, const char *tname, + int iter, int status, int expected_signal); static TestResult *receive_result_info_nofork (const char *tcname, - const char *tname); + const char *tname, + int iter); 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); @@ -180,19 +182,24 @@ static void srunner_iterate_tcase_tfuns (SRunner *sr, TCase *tc) tfl = tc->tflst; for (list_front(tfl); !list_at_end (tfl); list_advance (tfl)) { + int i; tfun = list_val (tfl); - switch (srunner_fork_status(sr)) { - case CK_FORK: - tr = tcase_run_tfun_fork (sr, tc, tfun); - break; - case CK_NOFORK: - tr = tcase_run_tfun_nofork (sr, tc, tfun); - break; - default: - eprintf("Bad fork status in SRunner", __FILE__, __LINE__); + + for (i = tfun->loop_start; i < tfun->loop_end; i++) + { + switch (srunner_fork_status(sr)) { + case CK_FORK: + tr = tcase_run_tfun_fork (sr, tc, tfun, i); + break; + case CK_NOFORK: + tr = tcase_run_tfun_nofork (sr, tc, tfun, i); + break; + default: + eprintf("Bad fork status in SRunner", __FILE__, __LINE__); + } + srunner_add_failure (sr, tr); + log_test_end(sr, tr); } - srunner_add_failure (sr, tr); - log_test_end(sr, tr); } } @@ -212,7 +219,7 @@ static int srunner_run_unchecked_setup (SRunner *sr, TCase *tc) f = list_val(l); f->fun(); - tr = receive_result_info_nofork (tc->name, "unchecked_setup"); + tr = receive_result_info_nofork (tc->name, "unchecked_setup", 0); if (tr->rtype != CK_PASS) { srunner_add_failure(sr, tr); @@ -249,7 +256,7 @@ static TestResult * tcase_run_checked_setup (SRunner *sr, TCase *tc) /* Stop the setup and return the failure if nofork mode. */ if (fstat == CK_NOFORK) { - tr = receive_result_info_nofork (tc->name, "checked_setup"); + tr = receive_result_info_nofork (tc->name, "checked_setup", 0); if (tr->rtype != CK_PASS) { break; } @@ -306,6 +313,7 @@ static void srunner_run_tcase (SRunner *sr, TCase *tc) static TestResult *receive_result_info_fork (const char *tcname, const char *tname, + int iter, int status, int expected_signal) { TestResult *tr; @@ -315,13 +323,15 @@ static TestResult *receive_result_info_fork (const char *tcname, eprintf("Failed to receive test result", __FILE__, __LINE__); tr->tcname = tcname; tr->tname = tname; + tr->iter = iter; set_fork_info(tr, status, expected_signal); return tr; } static TestResult *receive_result_info_nofork (const char *tcname, - const char *tname) + const char *tname, + int iter) { TestResult *tr; @@ -330,6 +340,7 @@ static TestResult *receive_result_info_nofork (const char *tcname, eprintf("Failed to receive test result", __FILE__, __LINE__); tr->tcname = tcname; tr->tname = tname; + tr->iter = iter; set_nofork_info(tr); return tr; @@ -394,35 +405,34 @@ static void set_nofork_info (TestResult *tr) } } -static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tfun) +static TestResult *tcase_run_tfun_nofork (SRunner *sr, TCase *tc, TF *tfun, int i) { TestResult *tr; tr = tcase_run_checked_setup(sr, tc); if (tr == NULL) { - tfun->fn(); + tfun->fn(i); tcase_run_checked_teardown(tc); - return receive_result_info_nofork(tc->name, tfun->name); + return receive_result_info_nofork(tc->name, tfun->name, i); } return tr; } -static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun) +static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun, int i) { pid_t pid_w; pid_t pid; int status = 0; - pid = fork(); if (pid == -1) - eprintf("Unable to fork:",__FILE__,__LINE__); + eprintf("Unable to fork:",__FILE__,__LINE__); if (pid == 0) { setpgid(0, 0); group_pid = getpgid(0); tcase_run_checked_setup(sr, tc); - tfun->fn(); + tfun->fn(i); tcase_run_checked_teardown(tc); exit(EXIT_SUCCESS); } else { @@ -437,7 +447,7 @@ static TestResult *tcase_run_tfun_fork (SRunner *sr, TCase *tc, TF *tfun) killpg(pid, SIGKILL); /* Kill remaining processes. */ - return receive_result_info_fork(tc->name, tfun->name, status, tfun->signal); + return receive_result_info_fork(tc->name, tfun->name, i, status, tfun->signal); } static char *signal_error_msg (int signal_received, int signal_expected) diff --git a/check/src/check_str.c b/check/src/check_str.c index 0fc60f2..4d3b456 100644 --- a/check/src/check_str.c +++ b/check/src/check_str.c @@ -39,9 +39,9 @@ char *tr_str (TestResult *tr) exact_msg = (tr->rtype == CK_ERROR) ? "(after this point) ": ""; - rstr = ck_strdup_printf ("%s:%d:%s:%s:%s: %s%s", + rstr = ck_strdup_printf ("%s:%d:%s:%s:%s:%d: %s%s", tr->file, tr->line, - tr_type_str(tr), tr->tcname, tr->tname, + tr_type_str(tr), tr->tcname, tr->tname, tr->iter, exact_msg, tr->msg); return rstr; diff --git a/check/tests/Makefile.am b/check/tests/Makefile.am index 319764c..ce51c2b 100644 --- a/check/tests/Makefile.am +++ b/check/tests/Makefile.am @@ -42,7 +42,7 @@ LIBCHECK_A=../src/libcheck.a INCLUDES = -I$(srcdir)/../src LDADD = $(LIBCHECK_A) -CLEANFILES = *~ *.log test_logfile +CLEANFILES = *~ *.log *.xml test_logfile $(LIBCHECK_A): $(MAKE) -C ../src diff --git a/check/tests/check_check_fixture.c b/check/tests/check_check_fixture.c index 81304b9..66d66cb 100644 --- a/check/tests/check_check_fixture.c +++ b/check/tests/check_check_fixture.c @@ -61,7 +61,7 @@ START_TEST(test_setup_failure_msg) { TestResult **tra; char *trm; - const char *trmexp = "check_check_fixture.c:14:S:Core:unchecked_setup: Test failure in fixture"; + const char *trmexp = "check_check_fixture.c:14:S:Core:unchecked_setup:0: Test failure in fixture"; tra = srunner_failures(fixture_sr); trm = tr_str(tra[0]); @@ -187,7 +187,7 @@ START_TEST(test_ch_setup_fail) trm = tr_str(srunner_failures(sr)[0]); if (strstr(trm, - "check_check_fixture.c:127:S:Core:test_sub_fail: Failed setup") + "check_check_fixture.c:127:S:Core:test_sub_fail:0: Failed setup") == 0) { snprintf(errm, sizeof(errm), "Bad failed checked setup tr msg (%s)", trm); @@ -297,7 +297,7 @@ START_TEST(test_ch_setup_sig) trm = tr_str(srunner_failures(sr)[0]); if (strstr(trm, - "check_check_fixture.c:137:S:Core:test_sub_fail: " + "check_check_fixture.c:137:S:Core:test_sub_fail:0: " "(after this point) Received signal 8") == 0) { snprintf(errm, sizeof(errm), @@ -339,7 +339,7 @@ START_TEST(test_ch_teardown_fail) trm = tr_str(srunner_failures(sr)[0]); if (strstr(trm, - "check_check_fixture.c:132:S:Core:test_sub_pass: Failed teardown") + "check_check_fixture.c:132:S:Core:test_sub_pass:0: Failed teardown") == 0) { snprintf(errm, sizeof(errm), "Bad failed checked teardown tr msg (%s)", trm); @@ -381,7 +381,7 @@ START_TEST(test_ch_teardown_sig) trm = tr_str(srunner_failures(sr)[0]); if (strstr(trm, - "check_check_fixture.c:143:S:Core:test_sub_pass: " + "check_check_fixture.c:143:S:Core:test_sub_pass:0: " "(after this point) Received signal 8") == 0) { snprintf(errm, sizeof(errm), diff --git a/check/tests/check_check_master.c b/check/tests/check_check_master.c index fd10d59..f4bd0e3 100644 --- a/check/tests/check_check_master.c +++ b/check/tests/check_check_master.c @@ -76,13 +76,14 @@ static master_test_t master_tests[] = { { "Core", -1, CK_FAILURE, "We failed" } }; +static int nr_of_master_tests = sizeof master_tests /sizeof master_tests[0]; START_TEST(test_check_nfailures) { int i; int failed = 0; - for (i = 0; i < sizeof master_tests /sizeof master_tests[0]; i++) { + for (i = 0; i < nr_of_master_tests; i++) { if (master_tests[i].failure_type != CK_PASS) { failed++; } @@ -95,7 +96,7 @@ END_TEST START_TEST(test_check_ntests_run) { - fail_unless (sub_ntests == (sizeof master_tests /sizeof master_tests[0]), + fail_unless (sub_ntests == nr_of_master_tests, "Unexpected number of tests run, %d.", sub_ntests); } END_TEST @@ -231,11 +232,8 @@ END_TEST START_TEST(test_check_all_ftypes) { - int i; - for (i = 0; i < sub_ntests; i++) { - fail_unless(master_tests[i].failure_type == tr_rtype(tr_all_array[i]), - "Failure type wrong for test %d", i); - } + fail_unless(master_tests[i].failure_type == tr_rtype(tr_all_array[i]), + "Failure type wrong for test %d", i); } END_TEST @@ -285,7 +283,7 @@ Suite *make_master_suite (void) tcase_add_test (tc_core, test_check_failure_lfiles); tcase_add_test (tc_core, test_check_tcnames); tcase_add_test (tc_core, test_check_all_msgs); - tcase_add_test (tc_core, test_check_all_ftypes); + tcase_add_loop_test (tc_core, test_check_all_ftypes, 0, nr_of_master_tests); tcase_add_unchecked_fixture(tc_fixture, test_fixture_setup, test_fixture_teardown); /* add the test 3 times to make sure we adequately test diff --git a/check/tests/ex_xml_output.c b/check/tests/ex_xml_output.c index 394b827..487469f 100644 --- a/check/tests/ex_xml_output.c +++ b/check/tests/ex_xml_output.c @@ -27,6 +27,12 @@ START_TEST(test_pass2) } END_TEST +START_TEST(test_loop) +{ + fail_unless (i==1, "Iteration %d failed", i); +} +END_TEST + static Suite *make_s1_suite (void) { Suite *s; @@ -51,6 +57,7 @@ static Suite *make_s2_suite (void) tc = tcase_create ("Core"); suite_add_tcase(s, tc); tcase_add_test (tc, test_pass2); + tcase_add_loop_test(tc, test_loop, 0, 3); return s; } diff --git a/check/tests/test_log_output.sh b/check/tests/test_log_output.sh index 961d6fb..d96b860 100755 --- a/check/tests/test_log_output.sh +++ b/check/tests/test_log_output.sh @@ -7,11 +7,11 @@ else fi expected="Running suite S1 -${lsrc}ex_log_output.c:8:P:Core:test_pass: Passed -${lsrc}ex_log_output.c:14:F:Core:test_fail: Failure -${lsrc}ex_log_output.c:18:E:Core:test_exit: (after this point) Early exit with return value 1 +${lsrc}ex_log_output.c:8:P:Core:test_pass:0: Passed +${lsrc}ex_log_output.c:14:F:Core:test_fail:0: Failure +${lsrc}ex_log_output.c:18:E:Core:test_exit:0: (after this point) Early exit with return value 1 Running suite S2 -${lsrc}ex_log_output.c:26:P:Core:test_pass2: Passed +${lsrc}ex_log_output.c:26:P:Core:test_pass2:0: Passed Results for all suites run: 50%: Checks: 4, Failures: 1, Errors: 1" diff --git a/check/tests/test_output.sh b/check/tests/test_output.sh index 85abe6e..f6f93f5 100755 --- a/check/tests/test_output.sh +++ b/check/tests/test_output.sh @@ -11,13 +11,13 @@ t1="xRunning suite(s): Master 33%: Checks: 3, Failures: 1, Errors: 1" t2="xRunning suite(s): Master 33%: Checks: 3, Failures: 1, Errors: 1 -${lsrc}ex_output.c:14:F:Core:test_fail: Failure -${lsrc}ex_output.c:18:E:Core:test_exit: (after this point) Early exit with return value 1" +${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" t3="xRunning suite(s): Master 33%: Checks: 3, Failures: 1, Errors: 1 -${lsrc}ex_output.c:8:P:Core:test_pass: Passed -${lsrc}ex_output.c:14:F:Core:test_fail: Failure -${lsrc}ex_output.c:18:E:Core:test_exit: (after this point) Early exit with return value 1" +${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" op0=`./ex_output CK_SILENT` op1=`./ex_output CK_MINIMAL` diff --git a/check/tests/test_xml_output.sh b/check/tests/test_xml_output.sh index e1fce7f..595e9f0 100755 --- a/check/tests/test_xml_output.sh +++ b/check/tests/test_xml_output.sh @@ -13,18 +13,21 @@ expected=" ex_xml_output.c:8 test_pass + 0 Core Passed ex_xml_output.c:14 test_fail + 0 Core Failure ex_xml_output.c:18 test_exit + 0 Core Early exit with return value 1 @@ -34,9 +37,31 @@ expected=" ex_xml_output.c:26 test_pass2 + 0 Core Passed + + ex_xml_output.c:32 + test_loop + 0 + Core + Iteration 0 failed + + + ex_xml_output.c:32 + test_loop + 1 + Core + Passed + + + ex_xml_output.c:32 + test_loop + 2 + Core + Iteration 2 failed + " -- 2.49.0