pacemaker 2.1.5-a3f44794f94
Scalable High-Availability cluster resource manager
pcmk__xe_foreach_child_test.c
Go to the documentation of this file.
1/*
2 * Copyright 2022 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 <crm_internal.h>
11
14
15static int compare_name_handler(xmlNode *xml, void *userdata) {
16 function_called();
17 assert_string_equal((char *) userdata, crm_element_name(xml));
18 return pcmk_rc_ok;
19}
20
21const char *str1 =
22 "<xml>\n"
23 " <!-- This is a level 1 node -->\n"
24 " <level1>\n"
25 " content\n"
26 " </level1>\n"
27 " <!-- This is a level 1 node -->\n"
28 " <level1>\n"
29 " content\n"
30 " </level1>\n"
31 " <!-- This is a level 1 node -->\n"
32 " <level1>\n"
33 " content\n"
34 " </level1>\n"
35 "</xml>";
36
37static void
38bad_input(void **state) {
39 xmlNode *xml = string2xml(str1);
40
41 pcmk__assert_asserts(pcmk__xe_foreach_child(xml, NULL, NULL, NULL));
42
43 free_xml(xml);
44}
45
46static void
47name_given_test(void **state) {
48 xmlNode *xml = string2xml(str1);
49
50 /* The handler should be called once for every <level1> node. */
51 expect_function_call(compare_name_handler);
52 expect_function_call(compare_name_handler);
53 expect_function_call(compare_name_handler);
54
55 pcmk__xe_foreach_child(xml, "level1", compare_name_handler, (void *) "level1");
56 free_xml(xml);
57}
58
59static void
60no_name_given_test(void **state) {
61 xmlNode *xml = string2xml(str1);
62
63 /* The handler should be called once for every <level1> node. */
64 expect_function_call(compare_name_handler);
65 expect_function_call(compare_name_handler);
66 expect_function_call(compare_name_handler);
67
68 pcmk__xe_foreach_child(xml, NULL, compare_name_handler, (void *) "level1");
69 free_xml(xml);
70}
71
72static void
73name_doesnt_exist_test(void **state) {
74 xmlNode *xml = string2xml(str1);
75 pcmk__xe_foreach_child(xml, "xxx", compare_name_handler, NULL);
76 free_xml(xml);
77}
78
79const char *str2 =
80 "<xml>\n"
81 " <level1>\n"
82 " <!-- Inside a level 1 node -->\n"
83 " <level2>\n"
84 " <!-- Inside a level 2 node -->\n"
85 " </level2>\n"
86 " </level1>\n"
87 " <level1>\n"
88 " <!-- Inside a level 1 node -->\n"
89 " <level2>\n"
90 " <!-- Inside a level 2 node -->\n"
91 " <level3>\n"
92 " <!-- Inside a level 3 node -->\n"
93 " </level3>\n"
94 " </level2>\n"
95 " <level2>\n"
96 " <!-- Inside a level 2 node -->\n"
97 " </level2>\n"
98 " </level1>\n"
99 "</xml>";
100
101static void
102multiple_levels_test(void **state) {
103 xmlNode *xml = string2xml(str2);
104
105 /* The handler should be called once for every <level1> node. */
106 expect_function_call(compare_name_handler);
107 expect_function_call(compare_name_handler);
108
109 pcmk__xe_foreach_child(xml, "level1", compare_name_handler, (void *) "level1");
110 free_xml(xml);
111}
112
113static void
114multiple_levels_no_name_test(void **state) {
115 xmlNode *xml = string2xml(str2);
116
117 /* The handler should be called once for every <level1> node. */
118 expect_function_call(compare_name_handler);
119 expect_function_call(compare_name_handler);
120
121 pcmk__xe_foreach_child(xml, NULL, compare_name_handler, (void *) "level1");
122 free_xml(xml);
123}
124
125const char *str3 =
126 "<xml>\n"
127 " <!-- This is node #1 -->\n"
128 " <node1>\n"
129 " content\n"
130 " </node1>\n"
131 " <!-- This is node #2 -->\n"
132 " <node2>\n"
133 " content\n"
134 " </node2>\n"
135 " <!-- This is node #3 -->\n"
136 " <node3>\n"
137 " content\n"
138 " </node3>\n"
139 "</xml>";
140
141static int any_of_handler(xmlNode *xml, void *userdata) {
142 function_called();
143 assert_true(pcmk__str_any_of(crm_element_name(xml), "node1", "node2", "node3", NULL));
144 return pcmk_rc_ok;
145}
146
147static void
148any_of_test(void **state) {
149 xmlNode *xml = string2xml(str3);
150
151 /* The handler should be called once for every <nodeX> node. */
152 expect_function_call(any_of_handler);
153 expect_function_call(any_of_handler);
154 expect_function_call(any_of_handler);
155
156 pcmk__xe_foreach_child(xml, NULL, any_of_handler, NULL);
157 free_xml(xml);
158}
159
160static int stops_on_first_handler(xmlNode *xml, void *userdata) {
161 function_called();
162
163 if (pcmk__str_eq(crm_element_name(xml), "node1", pcmk__str_none)) {
164 return pcmk_rc_error;
165 } else {
166 return pcmk_rc_ok;
167 }
168}
169
170static int stops_on_second_handler(xmlNode *xml, void *userdata) {
171 function_called();
172
173 if (pcmk__str_eq(crm_element_name(xml), "node2", pcmk__str_none)) {
174 return pcmk_rc_error;
175 } else {
176 return pcmk_rc_ok;
177 }
178}
179
180static int stops_on_third_handler(xmlNode *xml, void *userdata) {
181 function_called();
182
183 if (pcmk__str_eq(crm_element_name(xml), "node3", pcmk__str_none)) {
184 return pcmk_rc_error;
185 } else {
186 return pcmk_rc_ok;
187 }
188}
189
190static void
191one_of_test(void **state) {
192 xmlNode *xml = string2xml(str3);
193
194 /* The handler should be called once. */
195 expect_function_call(stops_on_first_handler);
196 assert_int_equal(pcmk__xe_foreach_child(xml, "node1", stops_on_first_handler, NULL), pcmk_rc_error);
197
198 expect_function_call(stops_on_second_handler);
199 assert_int_equal(pcmk__xe_foreach_child(xml, "node2", stops_on_second_handler, NULL), pcmk_rc_error);
200
201 expect_function_call(stops_on_third_handler);
202 assert_int_equal(pcmk__xe_foreach_child(xml, "node3", stops_on_third_handler, NULL), pcmk_rc_error);
203
204 free_xml(xml);
205}
206
207PCMK__UNIT_TEST(NULL, NULL,
208 cmocka_unit_test(bad_input),
209 cmocka_unit_test(name_given_test),
210 cmocka_unit_test(no_name_given_test),
211 cmocka_unit_test(name_doesnt_exist_test),
212 cmocka_unit_test(multiple_levels_test),
213 cmocka_unit_test(multiple_levels_no_name_test),
214 cmocka_unit_test(any_of_test),
215 cmocka_unit_test(one_of_test))
const char * str3
const char * str1
const char * str2
@ pcmk_rc_ok
Definition: results.h:148
@ pcmk_rc_error
Definition: results.h:144
@ pcmk__str_none
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:952
#define pcmk__assert_asserts(stmt)
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
xmlNode * string2xml(const char *input)
Definition: xml.c:930
void free_xml(xmlNode *child)
Definition: xml.c:885
int pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name, int(*handler)(xmlNode *xml, void *userdata), void *userdata)
Definition: xml.c:3112