pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
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
24static pcmk_rule_input_t rule_input = {
25 // These are the only members used to evaluate operation expressions
26 .op_name = PCMK_ACTION_MONITOR,
27 .op_interval_ms = 10000,
28};
29
37static void
38assert_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
57static void
58null_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
86static void
87id_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
102static void
103name_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
117static void
118input_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
131static void
132fail_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
155static void
156invalid_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
166static void
167default_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
177static void
178fail_interval(void **state)
179{
180 assert_op_expression(EXPR_FAIL_INTERVAL, pcmk_rc_op_unsatisfied);
181}
182
183
184static void
185match_both(void **state)
186{
187 assert_op_expression(EXPR_MATCH_BOTH, pcmk_rc_ok);
188}
189
190static void
191fail_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))
#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:1179
#define EXPR_DEFAULT_INTERVAL
#define EXPR_INVALID_INTERVAL
@ pcmk_rc_op_unsatisfied
Definition results.h:133
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_rc_unpack_error
Definition results.h:122
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
int pcmk__xml_test_teardown_group(void **state)
Definition unittest.c:105
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
int pcmk__xml_test_setup_group(void **state)
Definition unittest.c:87
Wrappers for and extensions to libxml2.
void pcmk__xml_free(xmlNode *xml)
Definition xml.c:816
xmlNode * pcmk__xml_parse(const char *input)
Definition xml_io.c:167