pacemaker  2.1.7-0f7f88312f
Scalable High-Availability cluster resource manager
pcmk__xe_foreach_child_test.c
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 General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
14 
15 static int compare_name_handler(xmlNode *xml, void *userdata) {
16  function_called();
17  assert_string_equal((char *) userdata, (const char *) xml->name);
18  return pcmk_rc_ok;
19 }
20 
21 const 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 
37 static void
38 bad_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 
46 static void
47 name_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 
59 static void
60 no_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 
72 static void
73 name_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 
79 const 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 
101 static void
102 multiple_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 
113 static void
114 multiple_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 
125 const 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 
141 static int any_of_handler(xmlNode *xml, void *userdata) {
142  function_called();
143  assert_true(pcmk__str_any_of((const char *) xml->name,
144  "node1", "node2", "node3", NULL));
145  return pcmk_rc_ok;
146 }
147 
148 static void
149 any_of_test(void **state) {
150  xmlNode *xml = string2xml(str3);
151 
152  /* The handler should be called once for every <nodeX> node. */
153  expect_function_call(any_of_handler);
154  expect_function_call(any_of_handler);
155  expect_function_call(any_of_handler);
156 
157  pcmk__xe_foreach_child(xml, NULL, any_of_handler, NULL);
158  free_xml(xml);
159 }
160 
161 static int stops_on_first_handler(xmlNode *xml, void *userdata) {
162  function_called();
163 
164  if (pcmk__xe_is(xml, "node1")) {
165  return pcmk_rc_error;
166  } else {
167  return pcmk_rc_ok;
168  }
169 }
170 
171 static int stops_on_second_handler(xmlNode *xml, void *userdata) {
172  function_called();
173 
174  if (pcmk__xe_is(xml, "node2")) {
175  return pcmk_rc_error;
176  } else {
177  return pcmk_rc_ok;
178  }
179 }
180 
181 static int stops_on_third_handler(xmlNode *xml, void *userdata) {
182  function_called();
183 
184  if (pcmk__xe_is(xml, "node3")) {
185  return pcmk_rc_error;
186  } else {
187  return pcmk_rc_ok;
188  }
189 }
190 
191 static void
192 one_of_test(void **state) {
193  xmlNode *xml = string2xml(str3);
194 
195  /* The handler should be called once. */
196  expect_function_call(stops_on_first_handler);
197  assert_int_equal(pcmk__xe_foreach_child(xml, "node1", stops_on_first_handler, NULL), pcmk_rc_error);
198 
199  expect_function_call(stops_on_second_handler);
200  assert_int_equal(pcmk__xe_foreach_child(xml, "node2", stops_on_second_handler, NULL), pcmk_rc_error);
201 
202  expect_function_call(stops_on_third_handler);
203  assert_int_equal(pcmk__xe_foreach_child(xml, "node3", stops_on_third_handler, NULL), pcmk_rc_error);
204 
205  free_xml(xml);
206 }
207 
208 PCMK__UNIT_TEST(NULL, NULL,
209  cmocka_unit_test(bad_input),
210  cmocka_unit_test(name_given_test),
211  cmocka_unit_test(no_name_given_test),
212  cmocka_unit_test(name_doesnt_exist_test),
213  cmocka_unit_test(multiple_levels_test),
214  cmocka_unit_test(multiple_levels_no_name_test),
215  cmocka_unit_test(any_of_test),
216  cmocka_unit_test(one_of_test))
PCMK__UNIT_TEST(NULL, NULL, cmocka_unit_test(bad_input), cmocka_unit_test(not_found), cmocka_unit_test(find_attrB), cmocka_unit_test(find_attrA_matching))
xmlNode * string2xml(const char *input)
Definition: xml.c:800
#define pcmk__assert_asserts(stmt)
void free_xml(xmlNode *child)
Definition: xml.c:783
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:957
const char * str3
int pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name, int(*handler)(xmlNode *xml, void *userdata), void *userdata)
Definition: xml.c:2663
const char * str1
const char * str2