pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
pcmk__evaluate_op_expression_test.c
Go to the documentation of this file.
1 /*
2  * Copyright 2024 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 
12 #include <stdio.h>
13 #include <glib.h>
14 
15 #include <crm/common/xml.h>
18 #include "crmcommon_private.h"
19 
20 /*
21  * Shared data
22  */
23 
24 static pcmk_rule_input_t rule_input = {
25  // These are the only members used to evaluate operation expressions
27  .op_interval_ms = 10000,
28 };
29 
37 static void
38 assert_op_expression(const char *xml_string, int reference_rc)
39 {
40  xmlNode *xml = pcmk__xml_parse(xml_string);
41 
42  assert_int_equal(pcmk__evaluate_op_expression(xml, &rule_input),
43  reference_rc);
44  pcmk__xml_free(xml);
45 }
46 
47 
48 /*
49  * Invalid arguments
50  */
51 
52 #define EXPR_FAIL_BOTH \
53  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
54  PCMK_XA_NAME "='" PCMK_ACTION_START "' " \
55  PCMK_XA_INTERVAL "='0' />"
56 
57 static void
58 null_invalid(void **state)
59 {
60  xmlNode *xml = NULL;
61 
62  assert_int_equal(pcmk__evaluate_op_expression(NULL, NULL), EINVAL);
63 
65  assert_int_equal(pcmk__evaluate_op_expression(xml, NULL), EINVAL);
66  pcmk__xml_free(xml);
67 
68  assert_op_expression(NULL, EINVAL);
69 }
70 
71 
72 /*
73  * Test PCMK_XA_ID
74  */
75 
76 #define EXPR_ID_MISSING \
77  "<" PCMK_XE_OP_EXPRESSION " " \
78  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
79  PCMK_XA_INTERVAL "='10s' />"
80 
81 #define EXPR_ID_EMPTY \
82  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='' " \
83  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
84  PCMK_XA_INTERVAL "='10s' />"
85 
86 static void
87 id_missing(void **state)
88 {
89  assert_op_expression(EXPR_ID_MISSING, pcmk_rc_unpack_error);
90  assert_op_expression(EXPR_ID_EMPTY, pcmk_rc_unpack_error);
91 }
92 
93 
94 /*
95  * Test PCMK_XA_NAME
96  */
97 
98 #define EXPR_NAME_MISSING \
99  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
100  PCMK_XA_INTERVAL "='10s' />"
101 
102 static void
103 name_missing(void **state)
104 {
105  assert_op_expression(EXPR_NAME_MISSING, pcmk_rc_unpack_error);
106 }
107 
108 #define EXPR_MATCH_BOTH \
109  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
110  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
111  PCMK_XA_INTERVAL "='10s' />"
112 
113 #define EXPR_EMPTY_NAME \
114  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
115  PCMK_XA_NAME "='' " PCMK_XA_INTERVAL "='10s' />"
116 
117 static void
118 input_name_missing(void **state)
119 {
120  rule_input.op_name = NULL;
121  assert_op_expression(EXPR_MATCH_BOTH, pcmk_rc_op_unsatisfied);
122  assert_op_expression(EXPR_EMPTY_NAME, pcmk_rc_op_unsatisfied);
123  rule_input.op_name = PCMK_ACTION_MONITOR;
124 }
125 
126 #define EXPR_FAIL_NAME \
127  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
128  PCMK_XA_NAME "='" PCMK_ACTION_START "' " \
129  PCMK_XA_INTERVAL "='10s' />"
130 
131 static void
132 fail_name(void **state)
133 {
134  assert_op_expression(EXPR_FAIL_NAME, pcmk_rc_op_unsatisfied);
135 
136  // An empty name is meaningless but accepted, so not an unpack error
137  assert_op_expression(EXPR_EMPTY_NAME, pcmk_rc_op_unsatisfied);
138 }
139 
140 
141 /*
142  * Test PCMK_XA_INTERVAL
143  */
144 
145 #define EXPR_EMPTY_INTERVAL \
146  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
147  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
148  PCMK_XA_INTERVAL "='' />"
149 
150 #define EXPR_INVALID_INTERVAL \
151  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
152  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
153  PCMK_XA_INTERVAL "='not-an-interval' />"
154 
155 static void
156 invalid_interval(void **state)
157 {
158  assert_op_expression(EXPR_EMPTY_INTERVAL, pcmk_rc_unpack_error);
159  assert_op_expression(EXPR_INVALID_INTERVAL, pcmk_rc_unpack_error);
160 }
161 
162 #define EXPR_DEFAULT_INTERVAL \
163  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
164  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' />"
165 
166 static void
167 default_interval(void **state)
168 {
169  assert_op_expression(EXPR_DEFAULT_INTERVAL, pcmk_rc_ok);
170 }
171 
172 #define EXPR_FAIL_INTERVAL \
173  "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
174  PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
175  PCMK_XA_INTERVAL "='9s' />"
176 
177 static void
178 fail_interval(void **state)
179 {
180  assert_op_expression(EXPR_FAIL_INTERVAL, pcmk_rc_op_unsatisfied);
181 }
182 
183 
184 static void
185 match_both(void **state)
186 {
187  assert_op_expression(EXPR_MATCH_BOTH, pcmk_rc_ok);
188 }
189 
190 static void
191 fail_both(void **state)
192 {
193  assert_op_expression(EXPR_FAIL_BOTH, pcmk_rc_op_unsatisfied);
194 }
195 
197  cmocka_unit_test(null_invalid),
198  cmocka_unit_test(id_missing),
199  cmocka_unit_test(name_missing),
200  cmocka_unit_test(input_name_missing),
201  cmocka_unit_test(fail_name),
202  cmocka_unit_test(invalid_interval),
203  cmocka_unit_test(default_interval),
204  cmocka_unit_test(fail_interval),
205  cmocka_unit_test(match_both),
206  cmocka_unit_test(fail_both))
Data used to evaluate a rule (any NULL items are ignored)
Definition: rules.h:57
const char * op_name
Operation name that rule applies to.
Definition: rules.h:67
#define PCMK_ACTION_MONITOR
Definition: actions.h:51
G_GNUC_INTERNAL int pcmk__evaluate_op_expression(const xmlNode *expr, const pcmk_rule_input_t *rule_input)
Definition: rules.c:1178
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
void pcmk__xml_free(xmlNode *xml)
Definition: xml.c:789
#define EXPR_NAME_MISSING
#define EXPR_DEFAULT_INTERVAL
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:85
Wrappers for and extensions to libxml2.
int pcmk__xml_test_teardown_group(void **state)
Definition: unittest.c:104
xmlNode * pcmk__xml_parse(const char *input)
Definition: xml_io.c:168
#define EXPR_FAIL_INTERVAL
#define EXPR_INVALID_INTERVAL
#define EXPR_EMPTY_INTERVAL