pacemaker  2.1.7-0f7f88312f
Scalable High-Availability cluster resource manager
unittest_internal.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022-2023 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <signal.h>
11 #include <stdarg.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <setjmp.h>
15 #include <sys/resource.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <unistd.h>
19 
20 #include <cmocka.h>
21 
22 #ifndef CRM_COMMON_UNITTEST_INTERNAL__H
23 #define CRM_COMMON_UNITTEST_INTERNAL__H
24 
25 /* internal unit testing related utilities */
26 
47 #define pcmk__assert_asserts(stmt) \
48  do { \
49  pid_t p = fork(); \
50  if (p == 0) { \
51  struct rlimit cores = { 0, 0 }; \
52  setrlimit(RLIMIT_CORE, &cores); \
53  stmt; \
54  _exit(0); \
55  } else if (p > 0) { \
56  int wstatus = 0; \
57  if (waitpid(p, &wstatus, 0) == -1) { \
58  fail_msg("waitpid failed"); \
59  } \
60  if (!(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGABRT)) { \
61  fail_msg("statement terminated in child without asserting"); \
62  } \
63  } else { \
64  fail_msg("unable to fork for assert test"); \
65  } \
66  } while (0);
67 
83 #define pcmk__assert_exits(rc, stmt) \
84  do { \
85  pid_t p = fork(); \
86  if (p == 0) { \
87  struct rlimit cores = { 0, 0 }; \
88  setrlimit(RLIMIT_CORE, &cores); \
89  stmt; \
90  _exit(CRM_EX_NONE); \
91  } else if (p > 0) { \
92  int wstatus = 0; \
93  if (waitpid(p, &wstatus, 0) == -1) { \
94  fail_msg("waitpid failed"); \
95  } \
96  if (!WIFEXITED(wstatus)) { \
97  fail_msg("statement terminated abnormally"); \
98  } else if (WEXITSTATUS(wstatus) != rc) { \
99  fail_msg("statement exited with %d, not expected %d", WEXITSTATUS(wstatus), rc); \
100  } \
101  } else { \
102  fail_msg("unable to fork for assert test"); \
103  } \
104  } while (0);
105 
106 /* Generate the main function of most unit test files. Typically, group_setup
107  * and group_teardown will be NULL. The rest of the arguments are a list of
108  * calls to cmocka_unit_test or cmocka_unit_test_setup_teardown to run the
109  * individual unit tests.
110  */
111 #define PCMK__UNIT_TEST(group_setup, group_teardown, ...) \
112 int \
113 main(int argc, char **argv) \
114 { \
115  const struct CMUnitTest t[] = { \
116  __VA_ARGS__ \
117  }; \
118  cmocka_set_message_output(CM_OUTPUT_TAP); \
119  return cmocka_run_group_tests(t, group_setup, group_teardown); \
120 }
121 
122 #endif /* CRM_COMMON_UNITTEST_INTERNAL__H */