This source file includes following definitions.
- null_invalid
- id_missing
- good_idref
- bad_idref
- empty_default
- empty_and
- empty_or
- default_boolean_op
- invalid_boolean_op
- and_passes
- lonely_and_passes
- and_one_fails
- and_two_fail
- or_one_passes
- or_two_pass
- lonely_or_passes
- or_fails
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <glib.h>
14
15 #include <crm/common/xml.h>
16 #include <crm/common/rules_internal.h>
17 #include <crm/common/unittest_internal.h>
18
19
20
21
22
23 static pcmk_rule_input_t rule_input = {
24 .rsc_standard = PCMK_RESOURCE_CLASS_OCF,
25 .rsc_provider = "heartbeat",
26 .rsc_agent = "IPaddr2",
27 .op_name = PCMK_ACTION_MONITOR,
28 .op_interval_ms = 10000,
29 };
30
31
32
33
34
35
36 #define RULE_OP \
37 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' > " \
38 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
39 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
40 PCMK_XA_INTERVAL "='10s' />" \
41 "</" PCMK_XE_RULE ">"
42
43 static void
44 null_invalid(void **state)
45 {
46 xmlNode *xml = NULL;
47 crm_time_t *next_change = crm_time_new_undefined();
48
49 assert_int_equal(pcmk_evaluate_rule(NULL, NULL, next_change),
50 EINVAL);
51
52 xml = pcmk__xml_parse(RULE_OP);
53 assert_int_equal(pcmk_evaluate_rule(xml, NULL, next_change), EINVAL);
54 free_xml(xml);
55
56 assert_int_equal(pcmk_evaluate_rule(NULL, &rule_input, next_change),
57 EINVAL);
58
59 crm_time_free(next_change);
60 }
61
62 #define RULE_OP_MISSING_ID \
63 "<" PCMK_XE_RULE "> " \
64 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
65 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
66 PCMK_XA_INTERVAL "='10s' />" \
67 "</" PCMK_XE_RULE ">"
68
69 static void
70 id_missing(void **state)
71 {
72
73 xmlNode *xml = pcmk__xml_parse(RULE_OP_MISSING_ID);
74 crm_time_t *next_change = crm_time_new_undefined();
75
76 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, next_change),
77 pcmk_rc_ok);
78
79 crm_time_free(next_change);
80 free_xml(xml);
81 }
82
83 #define RULE_IDREF_PARENT "<" PCMK_XE_CIB ">" RULE_OP "</" PCMK_XE_CIB ">"
84
85 static void
86 good_idref(void **state)
87 {
88 xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT);
89 xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE);
90 crm_time_t *next_change = crm_time_new_undefined();
91
92 crm_xml_add(rule_xml, PCMK_XA_ID_REF, "r");
93 assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change),
94 pcmk_rc_ok);
95
96 crm_time_free(next_change);
97 free_xml(parent_xml);
98 }
99
100 static void
101 bad_idref(void **state)
102 {
103 xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT);
104 xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE);
105 crm_time_t *next_change = crm_time_new_undefined();
106
107 crm_xml_add(rule_xml, PCMK_XA_ID_REF, "x");
108 assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change),
109 pcmk_rc_unpack_error);
110
111 crm_time_free(next_change);
112 free_xml(parent_xml);
113 }
114
115 #define RULE_EMPTY "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' />"
116
117 static void
118 empty_default(void **state)
119 {
120
121 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY);
122
123 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
124 pcmk_rc_ok);
125
126 free_xml(xml);
127 }
128
129 #define RULE_EMPTY_AND \
130 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
131 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' />"
132
133 static void
134 empty_and(void **state)
135 {
136
137 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY_AND);
138
139 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
140 pcmk_rc_ok);
141
142 free_xml(xml);
143 }
144
145 #define RULE_EMPTY_OR \
146 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
147 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' />"
148
149 static void
150 empty_or(void **state)
151 {
152
153 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY_OR);
154
155 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
156 pcmk_rc_op_unsatisfied);
157
158 free_xml(xml);
159 }
160
161 #define RULE_DEFAULT_BOOLEAN_OP \
162 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' >" \
163 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
164 PCMK_XA_TYPE "='Dummy' />" \
165 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
166 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
167 PCMK_XA_INTERVAL "='10s' />" \
168 "</" PCMK_XE_RULE ">"
169
170 static void
171 default_boolean_op(void **state)
172 {
173
174 xmlNode *xml = pcmk__xml_parse(RULE_DEFAULT_BOOLEAN_OP);
175
176 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
177 pcmk_rc_op_unsatisfied);
178
179 free_xml(xml);
180 }
181
182 #define RULE_INVALID_BOOLEAN_OP \
183 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
184 PCMK_XA_BOOLEAN_OP "='not-an-op' >" \
185 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
186 PCMK_XA_TYPE "='Dummy' />" \
187 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
188 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
189 PCMK_XA_INTERVAL "='10s' />" \
190 "</" PCMK_XE_RULE ">"
191
192 static void
193 invalid_boolean_op(void **state)
194 {
195
196 xmlNode *xml = pcmk__xml_parse(RULE_INVALID_BOOLEAN_OP);
197
198 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
199 pcmk_rc_op_unsatisfied);
200
201 free_xml(xml);
202 }
203
204 #define RULE_AND_PASSES \
205 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
206 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
207 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
208 PCMK_XA_TYPE "='IPaddr2' />" \
209 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
210 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
211 PCMK_XA_INTERVAL "='10s' />" \
212 "</" PCMK_XE_RULE ">"
213
214 static void
215 and_passes(void **state)
216 {
217 xmlNode *xml = pcmk__xml_parse(RULE_AND_PASSES);
218
219 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
220
221 free_xml(xml);
222 }
223
224 #define RULE_LONELY_AND \
225 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
226 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
227 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
228 PCMK_XA_TYPE "='IPaddr2' />" \
229 "</" PCMK_XE_RULE ">"
230
231 static void
232 lonely_and_passes(void **state)
233 {
234 xmlNode *xml = pcmk__xml_parse(RULE_LONELY_AND);
235
236 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
237
238 free_xml(xml);
239 }
240
241 #define RULE_AND_ONE_FAILS \
242 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
243 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
244 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
245 PCMK_XA_TYPE "='Dummy' />" \
246 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
247 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
248 PCMK_XA_INTERVAL "='10s' />" \
249 "</" PCMK_XE_RULE ">"
250
251 static void
252 and_one_fails(void **state)
253 {
254 xmlNode *xml = pcmk__xml_parse(RULE_AND_ONE_FAILS);
255
256 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
257 pcmk_rc_op_unsatisfied);
258
259 free_xml(xml);
260 }
261
262 #define RULE_AND_TWO_FAIL \
263 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
264 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
265 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
266 PCMK_XA_TYPE "='Dummy' />" \
267 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
268 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
269 PCMK_XA_INTERVAL "='9s' />" \
270 "</" PCMK_XE_RULE ">"
271
272 static void
273 and_two_fail(void **state)
274 {
275 xmlNode *xml = pcmk__xml_parse(RULE_AND_TWO_FAIL);
276
277 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
278 pcmk_rc_op_unsatisfied);
279
280 free_xml(xml);
281 }
282
283 #define RULE_OR_ONE_PASSES \
284 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
285 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
286 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
287 PCMK_XA_TYPE "='Dummy' />" \
288 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
289 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
290 PCMK_XA_INTERVAL "='10s' />" \
291 "</" PCMK_XE_RULE ">"
292
293 static void
294 or_one_passes(void **state)
295 {
296 xmlNode *xml = pcmk__xml_parse(RULE_OR_ONE_PASSES);
297
298 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
299
300 free_xml(xml);
301 }
302
303 #define RULE_OR_TWO_PASS \
304 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
305 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
306 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
307 PCMK_XA_TYPE "='IPAddr2' />" \
308 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
309 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
310 PCMK_XA_INTERVAL "='10s' />" \
311 "</" PCMK_XE_RULE ">"
312
313 static void
314 or_two_pass(void **state)
315 {
316 xmlNode *xml = pcmk__xml_parse(RULE_OR_TWO_PASS);
317
318 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
319
320 free_xml(xml);
321 }
322
323 #define RULE_LONELY_OR \
324 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
325 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
326 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
327 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
328 PCMK_XA_INTERVAL "='10s' />" \
329 "</" PCMK_XE_RULE ">"
330
331 static void
332 lonely_or_passes(void **state)
333 {
334 xmlNode *xml = pcmk__xml_parse(RULE_LONELY_OR);
335
336 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
337
338 free_xml(xml);
339 }
340
341 #define RULE_OR_FAILS \
342 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
343 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
344 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
345 PCMK_XA_TYPE "='Dummy' />" \
346 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
347 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
348 PCMK_XA_INTERVAL "='20s' />" \
349 "</" PCMK_XE_RULE ">"
350
351 static void
352 or_fails(void **state)
353 {
354 xmlNode *xml = pcmk__xml_parse(RULE_OR_FAILS);
355
356 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
357 pcmk_rc_op_unsatisfied);
358
359 free_xml(xml);
360 }
361
362 PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group,
363 cmocka_unit_test(null_invalid),
364 cmocka_unit_test(id_missing),
365 cmocka_unit_test(good_idref),
366 cmocka_unit_test(bad_idref),
367 cmocka_unit_test(empty_default),
368 cmocka_unit_test(empty_and),
369 cmocka_unit_test(empty_or),
370 cmocka_unit_test(default_boolean_op),
371 cmocka_unit_test(invalid_boolean_op),
372 cmocka_unit_test(and_passes),
373 cmocka_unit_test(lonely_and_passes),
374 cmocka_unit_test(and_one_fails),
375 cmocka_unit_test(and_two_fail),
376 cmocka_unit_test(or_one_passes),
377 cmocka_unit_test(or_two_pass),
378 cmocka_unit_test(lonely_or_passes),
379 cmocka_unit_test(or_fails))