pacemaker  2.1.6-802a72226b
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 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, crm_element_name(xml));
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(crm_element_name(xml), "node1", "node2", "node3", NULL));
144  return pcmk_rc_ok;
145 }
146 
147 static void
148 any_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 
160 static 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 
170 static 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 
180 static 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 
190 static void
191 one_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 
207 PCMK__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))
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:831
#define pcmk__assert_asserts(stmt)
void free_xml(xmlNode *child)
Definition: xml.c:813
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:2704
const char * str1
const char * str2