[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Test should not be run if setup function fails


ehlo,

Assertions are commonly used in setup function. If setup function fail
test should not be executed, because it may result into unexpected behaviour
(crash)

src/tests/cmocka/test_dp_opts.c:87: error: Failure!
[  FAILED  ] opt_test_getset_int_opt_test_getset_setup
[ RUN      ] opt_test_getset_int
Segmentation fault (core dumped)


There is a corner case:
    1. malloc in setup function
    2. setup function fail (assert)w
    3. teardown will not be called (there will be memory leak)

LS
From 1ccf2b89da6fe55d16ce198ccf4eaa3c43f2236d Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@xxxxxxxxxx>
Date: Wed, 26 Feb 2014 13:46:18 +0100
Subject: [PATCH 1/2] basic_test should be run with other CMOCKA_TESTS

---
 tests/CMakeLists.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b9c6db4e426d8bf6ce5e75ca8f3db0d6698ffc69..82cc046da1b7da21e0a2c8855dd510d5ca161797 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -10,7 +10,8 @@ set(CMOCKA_TESTS
     test_fixtures
     test_assert_macros
     test_assert_macros_fail
-    test_exception_handler)
+    test_exception_handler
+    test_basics)
 
 foreach(_CMOCKA_TEST ${CMOCKA_TESTS})
     add_cmocka_test(${_CMOCKA_TEST} ${_CMOCKA_TEST}.c ${CMOCKA_SHARED_LIBRARY})
-- 
1.8.5.3

From 5643f46e12cd93e217ab522d2c770919b390615e Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@xxxxxxxxxx>
Date: Wed, 26 Feb 2014 13:45:02 +0100
Subject: [PATCH 2/2] Test should not be run if setup function fails

Assertions are commonly used in setup function. If setup function fail
test should not be executed, because it may result into unexpected behaviour
(crash)
---
 src/cmocka.c            |  7 ++++++-
 tests/CMakeLists.txt    | 42 +++++++++++++++++++++++++++++++++++++++++-
 tests/test_setup_fail.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+), 2 deletions(-)
 create mode 100644 tests/test_setup_fail.c

diff --git a/src/cmocka.c b/src/cmocka.c
index 76cd7830b7694f9c7308bb4064151739d093d8d4..23abf7e23b7396d36476ae8e85c4caf0766520f6 100644
--- a/src/cmocka.c
+++ b/src/cmocka.c
@@ -1764,6 +1764,8 @@ int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
     int run_next_test = 1;
     /* Whether the previous test failed. */
     int previous_test_failed = 0;
+    /* Whether the previous setup failed. */
+    int previous_setup_failed = 0;
     /* Check point of the heap state. */
     const ListNode * const check_point = check_point_allocated_blocks();
     /* Current test being executed. */
@@ -1803,7 +1805,9 @@ int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
 
         switch (test->function_type) {
         case UNIT_TEST_FUNCTION_TYPE_TEST:
-            run_next_test = 1;
+            if (! previous_setup_failed) {
+                run_next_test = 1;
+            }
             break;
         case UNIT_TEST_FUNCTION_TYPE_SETUP: {
             /* Checkpoint the heap before the setup. */
@@ -1851,6 +1855,7 @@ int _run_tests(const UnitTest * const tests, const size_t number_of_tests) {
                     tests_executed ++;
                     /* Skip forward until the next test or setup function. */
                     run_next_test = 0;
+                    previous_setup_failed = 1;
                 }
                 previous_test_failed = 0;
                 break;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 82cc046da1b7da21e0a2c8855dd510d5ca161797..8287b61f9d218ea16892e25547737629cdd26da7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -11,7 +11,8 @@ set(CMOCKA_TESTS
     test_assert_macros
     test_assert_macros_fail
     test_exception_handler
-    test_basics)
+    test_basics
+    test_setup_fail)
 
 foreach(_CMOCKA_TEST ${CMOCKA_TESTS})
     add_cmocka_test(${_CMOCKA_TEST} ${_CMOCKA_TEST}.c ${CMOCKA_SHARED_LIBRARY})
@@ -34,3 +35,42 @@ set_tests_properties(
         PASS_REGULAR_EXPRESSION
         "Test failed with exception: (Segmentation fault|Segmentation Fault|11)"
 )
+
+set_tests_properties(
+    test_setup_fail
+        PROPERTIES
+        WILL_FAIL
+        1
+)
+
+add_test (test_setup_fail_1_failed test_setup_fail)
+set_tests_properties(
+    test_setup_fail_1_failed
+        PROPERTIES
+        PASS_REGULAR_EXPRESSION
+        "\\[  FAILED  \\] 1 test\\(s\\), listed below:"
+)
+
+add_test (test_setup_fail_1_passed test_setup_fail)
+set_tests_properties(
+    test_setup_fail_1_passed
+        PROPERTIES
+        PASS_REGULAR_EXPRESSION
+        "\\[  PASSED  \\] 1 test\\(s\\)."
+)
+
+add_test (test_setup_fail_match_failed test_setup_fail)
+set_tests_properties(
+    test_setup_fail_match_failed
+        PROPERTIES
+        PASS_REGULAR_EXPRESSION
+        "\\[  FAILED  \\] int_test_ignored_setup_fail"
+)
+
+add_test (test_setup_fail_match_passed test_setup_fail)
+set_tests_properties(
+    test_setup_fail_match_passed
+        PROPERTIES
+        PASS_REGULAR_EXPRESSION
+        "\\[       OK \\] int_test_success"
+)
diff --git a/tests/test_setup_fail.c b/tests/test_setup_fail.c
new file mode 100644
index 0000000000000000000000000000000000000000..923886ccbb730a1e85e5aa2adbd501888dd6fe59
--- /dev/null
+++ b/tests/test_setup_fail.c
@@ -0,0 +1,47 @@
+#define UNIT_TESTING 1
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+static void setup_fail(void **state) {
+    *state = NULL;
+
+    /* We need to fail in setup */
+    assert_non_null(NULL);
+}
+
+static void int_test_ignored(void **state) {
+    /* should not be called */
+    assert_non_null(*state);
+}
+
+static void setup_ok(void **state) {
+    int *answer = malloc(sizeof(int));
+
+    assert_non_null(answer);
+    *answer = 42;
+
+    *state = answer;
+}
+
+/* A test case that does check if an int is equal. */
+static void int_test_success(void **state) {
+    int *answer = *state;
+
+    assert_int_equal(*answer, 42);
+}
+
+static void teardown(void **state) {
+    free(*state);
+}
+
+int main(void) {
+    const UnitTest tests[] = {
+        unit_test_setup_teardown(int_test_ignored, setup_fail, teardown),
+        unit_test_setup_teardown(int_test_success, setup_ok, teardown),
+    };
+
+    return run_tests(tests);
+}
-- 
1.8.5.3