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 pcmk__xml_free(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 xmlNode *xml = pcmk__xml_parse(RULE_OP_MISSING_ID);
73 crm_time_t *next_change = crm_time_new_undefined();
74
75 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, next_change),
76 pcmk_rc_unpack_error);
77
78 crm_time_free(next_change);
79 pcmk__xml_free(xml);
80 }
81
82 #define RULE_IDREF_PARENT "<" PCMK_XE_CIB ">" RULE_OP "</" PCMK_XE_CIB ">"
83
84 static void
85 good_idref(void **state)
86 {
87 xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT);
88 xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE);
89 crm_time_t *next_change = crm_time_new_undefined();
90
91 crm_xml_add(rule_xml, PCMK_XA_ID_REF, "r");
92 assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change),
93 pcmk_rc_ok);
94
95 crm_time_free(next_change);
96 pcmk__xml_free(parent_xml);
97 }
98
99 static void
100 bad_idref(void **state)
101 {
102 xmlNode *parent_xml = pcmk__xml_parse(RULE_IDREF_PARENT);
103 xmlNode *rule_xml = pcmk__xe_create(parent_xml, PCMK_XE_RULE);
104 crm_time_t *next_change = crm_time_new_undefined();
105
106 crm_xml_add(rule_xml, PCMK_XA_ID_REF, "x");
107 assert_int_equal(pcmk_evaluate_rule(rule_xml, &rule_input, next_change),
108 pcmk_rc_unpack_error);
109
110 crm_time_free(next_change);
111 pcmk__xml_free(parent_xml);
112 }
113
114 #define RULE_EMPTY "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' />"
115
116 static void
117 empty_default(void **state)
118 {
119
120 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY);
121
122 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
123 pcmk_rc_ok);
124
125 pcmk__xml_free(xml);
126 }
127
128 #define RULE_EMPTY_AND \
129 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
130 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' />"
131
132 static void
133 empty_and(void **state)
134 {
135
136 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY_AND);
137
138 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
139 pcmk_rc_ok);
140
141 pcmk__xml_free(xml);
142 }
143
144 #define RULE_EMPTY_OR \
145 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
146 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' />"
147
148 static void
149 empty_or(void **state)
150 {
151 xmlNode *xml = pcmk__xml_parse(RULE_EMPTY_OR);
152
153 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
154 pcmk_rc_ok);
155
156 pcmk__xml_free(xml);
157 }
158
159 #define RULE_DEFAULT_BOOLEAN_OP \
160 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' >" \
161 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
162 PCMK_XA_TYPE "='Dummy' />" \
163 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
164 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
165 PCMK_XA_INTERVAL "='10s' />" \
166 "</" PCMK_XE_RULE ">"
167
168 static void
169 default_boolean_op(void **state)
170 {
171
172 xmlNode *xml = pcmk__xml_parse(RULE_DEFAULT_BOOLEAN_OP);
173
174 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
175 pcmk_rc_op_unsatisfied);
176
177 pcmk__xml_free(xml);
178 }
179
180 #define RULE_INVALID_BOOLEAN_OP \
181 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
182 PCMK_XA_BOOLEAN_OP "='not-an-op' >" \
183 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
184 PCMK_XA_TYPE "='Dummy' />" \
185 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
186 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
187 PCMK_XA_INTERVAL "='10s' />" \
188 "</" PCMK_XE_RULE ">"
189
190 static void
191 invalid_boolean_op(void **state)
192 {
193 xmlNode *xml = pcmk__xml_parse(RULE_INVALID_BOOLEAN_OP);
194
195 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
196 pcmk_rc_unpack_error);
197
198 pcmk__xml_free(xml);
199 }
200
201 #define RULE_AND_PASSES \
202 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
203 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
204 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
205 PCMK_XA_TYPE "='IPaddr2' />" \
206 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
207 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
208 PCMK_XA_INTERVAL "='10s' />" \
209 "</" PCMK_XE_RULE ">"
210
211 static void
212 and_passes(void **state)
213 {
214 xmlNode *xml = pcmk__xml_parse(RULE_AND_PASSES);
215
216 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
217
218 pcmk__xml_free(xml);
219 }
220
221 #define RULE_LONELY_AND \
222 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
223 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
224 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
225 PCMK_XA_TYPE "='IPaddr2' />" \
226 "</" PCMK_XE_RULE ">"
227
228 static void
229 lonely_and_passes(void **state)
230 {
231 xmlNode *xml = pcmk__xml_parse(RULE_LONELY_AND);
232
233 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
234
235 pcmk__xml_free(xml);
236 }
237
238 #define RULE_AND_ONE_FAILS \
239 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
240 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
241 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
242 PCMK_XA_TYPE "='Dummy' />" \
243 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
244 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
245 PCMK_XA_INTERVAL "='10s' />" \
246 "</" PCMK_XE_RULE ">"
247
248 static void
249 and_one_fails(void **state)
250 {
251 xmlNode *xml = pcmk__xml_parse(RULE_AND_ONE_FAILS);
252
253 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
254 pcmk_rc_op_unsatisfied);
255
256 pcmk__xml_free(xml);
257 }
258
259 #define RULE_AND_TWO_FAIL \
260 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
261 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_AND "' >" \
262 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
263 PCMK_XA_TYPE "='Dummy' />" \
264 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
265 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
266 PCMK_XA_INTERVAL "='9s' />" \
267 "</" PCMK_XE_RULE ">"
268
269 static void
270 and_two_fail(void **state)
271 {
272 xmlNode *xml = pcmk__xml_parse(RULE_AND_TWO_FAIL);
273
274 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
275 pcmk_rc_op_unsatisfied);
276
277 pcmk__xml_free(xml);
278 }
279
280 #define RULE_OR_ONE_PASSES \
281 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
282 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
283 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
284 PCMK_XA_TYPE "='Dummy' />" \
285 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
286 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
287 PCMK_XA_INTERVAL "='10s' />" \
288 "</" PCMK_XE_RULE ">"
289
290 static void
291 or_one_passes(void **state)
292 {
293 xmlNode *xml = pcmk__xml_parse(RULE_OR_ONE_PASSES);
294
295 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
296
297 pcmk__xml_free(xml);
298 }
299
300 #define RULE_OR_TWO_PASS \
301 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
302 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
303 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
304 PCMK_XA_TYPE "='IPAddr2' />" \
305 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
306 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
307 PCMK_XA_INTERVAL "='10s' />" \
308 "</" PCMK_XE_RULE ">"
309
310 static void
311 or_two_pass(void **state)
312 {
313 xmlNode *xml = pcmk__xml_parse(RULE_OR_TWO_PASS);
314
315 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
316
317 pcmk__xml_free(xml);
318 }
319
320 #define RULE_LONELY_OR \
321 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
322 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
323 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
324 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
325 PCMK_XA_INTERVAL "='10s' />" \
326 "</" PCMK_XE_RULE ">"
327
328 static void
329 lonely_or_passes(void **state)
330 {
331 xmlNode *xml = pcmk__xml_parse(RULE_LONELY_OR);
332
333 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL), pcmk_rc_ok);
334
335 pcmk__xml_free(xml);
336 }
337
338 #define RULE_OR_FAILS \
339 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r' " \
340 PCMK_XA_BOOLEAN_OP "='" PCMK_VALUE_OR "' >" \
341 " <" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e1' " \
342 PCMK_XA_TYPE "='Dummy' />" \
343 " <" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e2' " \
344 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
345 PCMK_XA_INTERVAL "='20s' />" \
346 "</" PCMK_XE_RULE ">"
347
348 static void
349 or_fails(void **state)
350 {
351 xmlNode *xml = pcmk__xml_parse(RULE_OR_FAILS);
352
353 assert_int_equal(pcmk_evaluate_rule(xml, &rule_input, NULL),
354 pcmk_rc_op_unsatisfied);
355
356 pcmk__xml_free(xml);
357 }
358
359 PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group,
360 cmocka_unit_test(null_invalid),
361 cmocka_unit_test(id_missing),
362 cmocka_unit_test(good_idref),
363 cmocka_unit_test(bad_idref),
364 cmocka_unit_test(empty_default),
365 cmocka_unit_test(empty_and),
366 cmocka_unit_test(empty_or),
367 cmocka_unit_test(default_boolean_op),
368 cmocka_unit_test(invalid_boolean_op),
369 cmocka_unit_test(and_passes),
370 cmocka_unit_test(lonely_and_passes),
371 cmocka_unit_test(and_one_fails),
372 cmocka_unit_test(and_two_fail),
373 cmocka_unit_test(or_one_passes),
374 cmocka_unit_test(or_two_pass),
375 cmocka_unit_test(lonely_or_passes),
376 cmocka_unit_test(or_fails))