pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
unittest_internal.h
Go to the documentation of this file.
1/*
2 * Copyright 2022-2025 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#ifndef PCMK__CRM_COMMON_UNITTEST_INTERNAL__H
11#define PCMK__CRM_COMMON_UNITTEST_INTERNAL__H
12
13#include <signal.h>
14#include <stdarg.h>
15#include <stdint.h>
16#include <setjmp.h>
17#include <sys/resource.h>
18#include <sys/types.h>
19#include <sys/wait.h>
20#include <unistd.h>
21
22#include <cmocka.h>
23
24#include <crm/common/xml.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/* internal unit testing related utilities */
31
32#if (PCMK__WITH_COVERAGE == 1)
33/* This function isn't exposed anywhere. The following prototype was taken from
34 * /usr/lib/gcc/x86_64-redhat-linux/??/include/gcov.h
35 */
36extern void __gcov_dump(void);
37#else
38#define __gcov_dump()
39#endif
40
54void pcmk__assert_validates(xmlNode *xml);
55
66int pcmk__xml_test_setup_group(void **state);
67
68int pcmk__xml_test_teardown_group(void **state);
69
86char *pcmk__cib_test_copy_cib(const char *in_file);
87
102void pcmk__cib_test_cleanup(char *out_path);
103
104void pcmk__test_init_logging(const char *name, const char *filename);
105
127#define pcmk__assert_asserts(stmt) \
128 do { \
129 pid_t p = fork(); \
130 if (p == 0) { \
131 struct rlimit cores = { 0, 0 }; \
132 setrlimit(RLIMIT_CORE, &cores); \
133 stmt; \
134 __gcov_dump(); \
135 _exit(0); \
136 } else if (p > 0) { \
137 int wstatus = 0; \
138 if (waitpid(p, &wstatus, 0) == -1) { \
139 fail_msg("waitpid failed"); \
140 } \
141 if (!(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGABRT)) { \
142 fail_msg("statement terminated in child without asserting"); \
143 } \
144 } else { \
145 fail_msg("unable to fork for assert test"); \
146 } \
147 } while (0);
148
156#define pcmk__assert_aborts(stmt) pcmk__assert_asserts(stmt)
157
173#define pcmk__assert_exits(rc, stmt) \
174 do { \
175 pid_t p = fork(); \
176 if (p == 0) { \
177 struct rlimit cores = { 0, 0 }; \
178 setrlimit(RLIMIT_CORE, &cores); \
179 stmt; \
180 __gcov_dump(); \
181 _exit(CRM_EX_NONE); \
182 } else if (p > 0) { \
183 int wstatus = 0; \
184 if (waitpid(p, &wstatus, 0) == -1) { \
185 fail_msg("waitpid failed"); \
186 } \
187 if (!WIFEXITED(wstatus)) { \
188 fail_msg("statement terminated abnormally"); \
189 } else if (WEXITSTATUS(wstatus) != rc) { \
190 fail_msg("statement exited with %d, not expected %d", WEXITSTATUS(wstatus), rc); \
191 } \
192 } else { \
193 fail_msg("unable to fork for assert test"); \
194 } \
195 } while (0);
196
197/* Generate the main function of most unit test files. Typically, group_setup
198 * and group_teardown will be NULL. The rest of the arguments are a list of
199 * calls to cmocka_unit_test or cmocka_unit_test_setup_teardown to run the
200 * individual unit tests.
201 */
202#define PCMK__UNIT_TEST(group_setup, group_teardown, ...) \
203int \
204main(int argc, char **argv) \
205{ \
206 const struct CMUnitTest t[] = { \
207 __VA_ARGS__ \
208 }; \
209 cmocka_set_message_output(CM_OUTPUT_TAP); \
210 return cmocka_run_group_tests(t, group_setup, group_teardown); \
211}
212
213#ifdef __cplusplus
214}
215#endif
216
217#endif // PCMK__CRM_COMMON_UNITTEST_INTERNAL__H
const char * name
Definition cib.c:26
void pcmk__test_init_logging(const char *name, const char *filename)
Definition unittest.c:165
void pcmk__cib_test_cleanup(char *out_path)
Definition unittest.c:148
int pcmk__xml_test_teardown_group(void **state)
Definition unittest.c:105
#define __gcov_dump()
int pcmk__xml_test_setup_group(void **state)
Definition unittest.c:87
void pcmk__assert_validates(xmlNode *xml)
Definition unittest.c:22
char * pcmk__cib_test_copy_cib(const char *in_file)
Definition unittest.c:113
Wrappers for and extensions to libxml2.