pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk__evaluate_condition_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
19/*
20 * Shared data
21 */
22
23static 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 * Test invalid arguments
34 */
35
36#define EXPR_ATTRIBUTE \
37 "<" PCMK_XE_EXPRESSION " " PCMK_XA_ID "='e' " \
38 PCMK_XA_ATTRIBUTE "='foo' " \
39 PCMK_XA_OPERATION "='" PCMK_VALUE_EQ "' " \
40 PCMK_XA_VALUE "='bar' />"
41
42static void
43null_invalid(void **state)
44{
45 xmlNode *xml = NULL;
46 crm_time_t *next_change = crm_time_new_undefined();
47
48 assert_int_equal(pcmk__evaluate_condition(NULL, NULL, next_change), EINVAL);
49
51 assert_int_equal(pcmk__evaluate_condition(xml, NULL, next_change), EINVAL);
52 pcmk__xml_free(xml);
53
54 assert_int_equal(pcmk__evaluate_condition(NULL, &rule_input, next_change),
55 EINVAL);
56
57 crm_time_free(next_change);
58}
59
60
61#define EXPR_INVALID "<not_an_expression " PCMK_XA_ID "='e' />"
62
63static void
64invalid_expression(void **state)
65{
66 xmlNode *xml = pcmk__xml_parse(EXPR_INVALID);
67 crm_time_t *next_change = crm_time_new_undefined();
68
69 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, next_change),
71
72 crm_time_free(next_change);
73 pcmk__xml_free(xml);
74}
75
76
77/* Each expression type function already has unit tests, so we just need to test
78 * that they are called correctly (essentially, one of each one's own tests).
79 */
80
81static void
82attribute_expression(void **state)
83{
84 xmlNode *xml = pcmk__xml_parse(EXPR_ATTRIBUTE);
85
86 rule_input.node_attrs = pcmk__strkey_table(free, free);
87 pcmk__insert_dup(rule_input.node_attrs, "foo", "bar");
88
89 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, NULL),
91
92 g_hash_table_destroy(rule_input.node_attrs);
93 rule_input.node_attrs = NULL;
94 pcmk__xml_free(xml);
95}
96
97#define EXPR_LOCATION \
98 "<" PCMK_XE_EXPRESSION " " PCMK_XA_ID "='e' " \
99 PCMK_XA_ATTRIBUTE "='" CRM_ATTR_UNAME "' " \
100 PCMK_XA_OPERATION "='" PCMK_VALUE_EQ "' " \
101 PCMK_XA_VALUE "='node1' />"
102
103static void
104location_expression(void **state)
105{
106 xmlNode *xml = pcmk__xml_parse(EXPR_LOCATION);
107
108 rule_input.node_attrs = pcmk__strkey_table(free, free);
109 pcmk__insert_dup(rule_input.node_attrs, CRM_ATTR_UNAME, "node1");
110
111 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, NULL),
112 pcmk_rc_ok);
113
114 g_hash_table_destroy(rule_input.node_attrs);
115 rule_input.node_attrs = NULL;
116 pcmk__xml_free(xml);
117}
118
119#define EXPR_DATE \
120 "<" PCMK_XE_DATE_EXPRESSION " " PCMK_XA_ID "='e' " \
121 PCMK_XA_OPERATION "='" PCMK_VALUE_IN_RANGE "' " \
122 PCMK_XA_START "='2024-02-01 12:00:00' " \
123 PCMK_XA_END "='2024-02-01 15:00:00' />"
124
125static void
126date_expression(void **state)
127{
128 xmlNode *xml = pcmk__xml_parse(EXPR_DATE);
129 crm_time_t *now = crm_time_new("2024-02-01 11:59:59");
130 crm_time_t *next_change = crm_time_new("2024-02-01 14:00:00");
131 crm_time_t *reference = crm_time_new("2024-02-01 12:00:00");
132
133 rule_input.now = now;
134 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, next_change),
136 assert_int_equal(crm_time_compare(next_change, reference), 0);
137 rule_input.now = NULL;
138
139 crm_time_free(reference);
140 crm_time_free(next_change);
141 crm_time_free(now);
142}
143
144#define EXPR_RESOURCE \
145 "<" PCMK_XE_RSC_EXPRESSION " " PCMK_XA_ID "='e' " \
146 PCMK_XA_CLASS "='" PCMK_RESOURCE_CLASS_OCF "' " \
147 PCMK_XA_TYPE "='IPaddr2' />"
148
149static void
150resource_expression(void **state)
151{
152 xmlNode *xml = pcmk__xml_parse(EXPR_RESOURCE);
153
154 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, NULL),
155 pcmk_rc_ok);
156 pcmk__xml_free(xml);
157}
158
159#define EXPR_OP \
160 "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
161 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
162 PCMK_XA_INTERVAL "='10s' />"
163
164static void
165op_expression(void **state)
166{
167 xmlNode *xml = pcmk__xml_parse(EXPR_OP);
168
169 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, NULL),
170 pcmk_rc_ok);
171 pcmk__xml_free(xml);
172}
173
174#define EXPR_SUBRULE \
175 "<" PCMK_XE_RULE " " PCMK_XA_ID "='r'> " \
176 "<" PCMK_XE_OP_EXPRESSION " " PCMK_XA_ID "='e' " \
177 PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "' " \
178 PCMK_XA_INTERVAL "='10s' /> " \
179 "</" PCMK_XE_RULE ">"
180
181static void
182subrule(void **state)
183{
184 xmlNode *xml = pcmk__xml_parse(EXPR_SUBRULE);
185 assert_int_equal(pcmk__evaluate_condition(xml, &rule_input, NULL),
186 pcmk_rc_ok);
187 pcmk__xml_free(xml);
188}
189
191 cmocka_unit_test(null_invalid),
192 cmocka_unit_test(invalid_expression),
193 cmocka_unit_test(attribute_expression),
194 cmocka_unit_test(location_expression),
195 cmocka_unit_test(date_expression),
196 cmocka_unit_test(resource_expression),
197 cmocka_unit_test(op_expression),
198 cmocka_unit_test(subrule))
#define PCMK_ACTION_MONITOR
Definition actions.h:51
#define PCMK_RESOURCE_CLASS_OCF
Definition agents.h:27
#define CRM_ATTR_UNAME
Definition crm.h:92
void crm_time_free(crm_time_t *dt)
Definition iso8601.c:150
crm_time_t * crm_time_new(const char *string)
Definition iso8601.c:112
crm_time_t * crm_time_new_undefined(void)
Allocate memory for an uninitialized time object.
Definition iso8601.c:129
struct crm_time_s crm_time_t
Definition iso8601.h:32
int crm_time_compare(const crm_time_t *a, const crm_time_t *b)
Definition iso8601.c:1736
#define EXPR_LOCATION
#define EXPR_INVALID
#define EXPR_RESOURCE
#define EXPR_ATTRIBUTE
@ pcmk_rc_before_range
Definition results.h:131
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_rc_unpack_error
Definition results.h:122
int pcmk__evaluate_condition(xmlNode *expr, const pcmk_rule_input_t *rule_input, crm_time_t *next_change)
Definition rules.c:1252
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
Definition strings.c:703
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition strings.c:685
Data used to evaluate a rule (any NULL items are ignored)
Definition rules.h:57
GHashTable * node_attrs
Definition rules.h:77
const crm_time_t * now
Current time for rule evaluation purposes.
Definition rules.h:59
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