pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
pcmk__evaluate_rsc_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 resource expressions
27  .rsc_provider = "heartbeat",
28  .rsc_agent = "IPaddr2",
29 };
30 
38 static void
39 assert_rsc_expression(const char *xml_string, int reference_rc)
40 {
41  xmlNode *xml = pcmk__xml_parse(xml_string);
42 
43  assert_int_equal(pcmk__evaluate_rsc_expression(xml, &rule_input),
44  reference_rc);
45  pcmk__xml_free(xml);
46 }
47 
48 
49 /*
50  * Invalid arguments
51  */
52 
53 #define EXPR_ALL_MATCH \
54  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
55  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
56  PCMK_XA_PROVIDER "='heartbeat' " \
57  PCMK_XA_TYPE "='IPaddr2' />"
58 
59 static void
60 null_invalid(void **state)
61 {
62  xmlNode *xml = NULL;
63 
64  assert_int_equal(pcmk__evaluate_rsc_expression(NULL, NULL), EINVAL);
65 
67  assert_int_equal(pcmk__evaluate_rsc_expression(xml, NULL), EINVAL);
68  pcmk__xml_free(xml);
69 
70  assert_rsc_expression(NULL, EINVAL);
71 }
72 
73 
74 /*
75  * Test PCMK_XA_ID
76  */
77 
78 #define EXPR_ID_MISSING \
79  "<" PCMK_XE_RSC_EXPRESSION " " \
80  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
81  PCMK_XA_PROVIDER "='heartbeat' " \
82  PCMK_XA_TYPE "='IPaddr2' />"
83 
84 #define EXPR_ID_EMPTY \
85  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='' " \
86  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
87  PCMK_XA_PROVIDER "='heartbeat' " \
88  PCMK_XA_TYPE "='IPaddr2' />"
89 
90 static void
91 id_missing(void **state)
92 {
93  assert_rsc_expression(EXPR_ID_MISSING, pcmk_rc_unpack_error);
94  assert_rsc_expression(EXPR_ID_EMPTY, pcmk_rc_unpack_error);
95 }
96 
97 
98 /*
99  * Test standard, provider, and agent
100  */
101 
102 #define EXPR_FAIL_STANDARD \
103  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
104  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_LSB "' />"
105 
106 #define EXPR_EMPTY_STANDARD \
107  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
108  PCMK_XA_CLASS "='' />"
109 
110 static void
111 fail_standard(void **state)
112 {
113  assert_rsc_expression(EXPR_FAIL_STANDARD, pcmk_rc_op_unsatisfied);
114  assert_rsc_expression(EXPR_EMPTY_STANDARD, pcmk_rc_op_unsatisfied);
115 
116  rule_input.rsc_standard = NULL;
117  assert_rsc_expression(EXPR_FAIL_STANDARD, pcmk_rc_op_unsatisfied);
118  assert_rsc_expression(EXPR_EMPTY_STANDARD, pcmk_rc_op_unsatisfied);
120 }
121 
122 #define EXPR_FAIL_PROVIDER \
123  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
124  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
125  PCMK_XA_PROVIDER "='pacemaker' " \
126  PCMK_XA_TYPE "='IPaddr2' />"
127 
128 #define EXPR_EMPTY_PROVIDER \
129  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
130  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
131  PCMK_XA_PROVIDER "='' " PCMK_XA_TYPE "='IPaddr2' />"
132 
133 static void
134 fail_provider(void **state)
135 {
136  assert_rsc_expression(EXPR_FAIL_PROVIDER, pcmk_rc_op_unsatisfied);
137  assert_rsc_expression(EXPR_EMPTY_PROVIDER, pcmk_rc_op_unsatisfied);
138 
139  rule_input.rsc_provider = NULL;
140  assert_rsc_expression(EXPR_FAIL_PROVIDER, pcmk_rc_op_unsatisfied);
141  assert_rsc_expression(EXPR_EMPTY_PROVIDER, pcmk_rc_op_unsatisfied);
142  rule_input.rsc_provider = "heartbeat";
143 }
144 
145 #define EXPR_FAIL_AGENT \
146  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
147  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
148  PCMK_XA_PROVIDER "='heartbeat' " \
149  PCMK_XA_TYPE "='IPaddr3' />"
150 
151 #define EXPR_EMPTY_AGENT \
152  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
153  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
154  PCMK_XA_PROVIDER "='heartbeat' " PCMK_XA_TYPE "='' />"
155 
156 static void
157 fail_agent(void **state)
158 {
159  assert_rsc_expression(EXPR_FAIL_AGENT, pcmk_rc_op_unsatisfied);
160  assert_rsc_expression(EXPR_EMPTY_AGENT, pcmk_rc_op_unsatisfied);
161 
162  rule_input.rsc_agent = NULL;
163  assert_rsc_expression(EXPR_FAIL_AGENT, pcmk_rc_op_unsatisfied);
164  assert_rsc_expression(EXPR_EMPTY_AGENT, pcmk_rc_op_unsatisfied);
165  rule_input.rsc_agent = "IPaddr2";
166 }
167 
168 #define EXPR_NO_STANDARD_MATCHES \
169  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
170  PCMK_XA_PROVIDER "='heartbeat' " \
171  PCMK_XA_TYPE "='IPaddr2' />"
172 
173 static void
174 no_standard_matches(void **state)
175 {
176  assert_rsc_expression(EXPR_NO_STANDARD_MATCHES, pcmk_rc_ok);
177 }
178 
179 #define EXPR_NO_PROVIDER_MATCHES \
180  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
181  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
182  PCMK_XA_TYPE "='IPaddr2' />"
183 
184 static void
185 no_provider_matches(void **state)
186 {
187  assert_rsc_expression(EXPR_NO_PROVIDER_MATCHES, pcmk_rc_ok);
188 }
189 
190 #define EXPR_NO_AGENT_MATCHES \
191  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
192  PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
193  PCMK_XA_PROVIDER "='heartbeat' />"
194 
195 static void
196 no_agent_matches(void **state)
197 {
198  assert_rsc_expression(EXPR_NO_AGENT_MATCHES, pcmk_rc_ok);
199 }
200 
201 #define EXPR_NO_CRITERIA_MATCHES \
202  "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' />"
203 
204 static void
205 no_criteria_matches(void **state)
206 {
207  assert_rsc_expression(EXPR_NO_CRITERIA_MATCHES, pcmk_rc_ok);
208 }
209 
210 static void
211 all_match(void **state)
212 {
213  assert_rsc_expression(EXPR_ALL_MATCH, pcmk_rc_ok);
214 }
215 
217  cmocka_unit_test(null_invalid),
218  cmocka_unit_test(id_missing),
219  cmocka_unit_test(fail_standard),
220  cmocka_unit_test(fail_provider),
221  cmocka_unit_test(fail_agent),
222  cmocka_unit_test(no_standard_matches),
223  cmocka_unit_test(no_provider_matches),
224  cmocka_unit_test(no_agent_matches),
225  cmocka_unit_test(no_criteria_matches),
226  cmocka_unit_test(all_match))
#define EXPR_NO_STANDARD_MATCHES
Data used to evaluate a rule (any NULL items are ignored)
Definition: rules.h:57
const char * rsc_provider
Resource provider that rule applies to.
Definition: rules.h:63
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
#define PCMK_RESOURCE_CLASS_OCF
Definition: agents.h:27
#define EXPR_NO_PROVIDER_MATCHES
#define EXPR_NO_AGENT_MATCHES
const char * rsc_agent
Resource agent that rule applies to.
Definition: rules.h:64
void pcmk__xml_free(xmlNode *xml)
Definition: xml.c:789
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:85
Wrappers for and extensions to libxml2.
const char * rsc_standard
Resource standard that rule applies to.
Definition: rules.h:62
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_NO_CRITERIA_MATCHES
G_GNUC_INTERNAL int pcmk__evaluate_rsc_expression(const xmlNode *expr, const pcmk_rule_input_t *rule_input)
Definition: rules.c:1109