pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_ticket_set_attr_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 <crm/cib/internal.h>
14#include <crm/common/xml.h>
15#include <pacemaker.h>
16
17static char *cib_path = NULL;
18
19static void
20cib_not_connected(void **state)
21{
22 xmlNode *xml = NULL;
23
24 /* Without any special setup, cib_new() in pcmk_ticket_set_attr will use the
25 * native CIB which means IPC calls. But there's nothing listening for those
26 * calls, so signon() will return ENOTCONN. Check that we handle that.
27 */
28 assert_int_equal(pcmk_ticket_set_attr(&xml, NULL, NULL, false), ENOTCONN);
30 pcmk__xml_free(xml);
31}
32
33static int
34setup_test(void **state)
35{
36 cib_path = pcmk__cib_test_copy_cib("tickets.xml");
37
38 if (cib_path == NULL) {
39 return -1;
40 }
41
42 return 0;
43}
44
45static int
46teardown_test(void **state)
47{
48 pcmk__cib_test_cleanup(cib_path);
49 cib_path = NULL;
50 return 0;
51}
52
53static void
54bad_arguments(void **state)
55{
56 xmlNode *xml = NULL;
57
58 assert_int_equal(pcmk_ticket_set_attr(NULL, "ticketA", NULL, false), EINVAL);
59
60 assert_int_equal(pcmk_ticket_set_attr(&xml, NULL, NULL, false), EINVAL);
62 pcmk__xml_free(xml);
63}
64
65static void
66unknown_ticket_no_attrs(void **state)
67{
68 GHashTable *attrs = pcmk__strkey_table(free, free);
69 xmlNode *xml = NULL;
70 xmlNode *xml_search = NULL;
71 cib_t *cib = cib_new();
72
74
75 /* Setting no attributes on a ticket that doesn't exist is a no-op */
76 assert_int_equal(pcmk_ticket_set_attr(&xml, "XYZ", NULL, false), pcmk_rc_ok);
78 pcmk__xml_free(xml);
79 xml = NULL;
80
81 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"XYZ\"]",
82 &xml_search, cib_xpath);
83 assert_null(xml_search);
84
85 /* Another way of specifying no attributes */
86 assert_int_equal(pcmk_ticket_set_attr(&xml, "XYZ", attrs, false), pcmk_rc_ok);
88 pcmk__xml_free(xml);
89
90 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"XYZ\"]",
91 &xml_search, cib_xpath);
92 assert_null(xml_search);
93
94 g_hash_table_destroy(attrs);
96}
97
98static void
99unknown_ticket_with_attrs(void **state)
100{
101 GHashTable *attrs = pcmk__strkey_table(free, free);
102 xmlNode *xml = NULL;
103 xmlNode *xml_search = NULL;
104 cib_t *cib;
105
106 pcmk__insert_dup(attrs, "attrA", "123");
107 pcmk__insert_dup(attrs, "attrB", "456");
108
109 /* Setting attributes on a ticket that doesn't exist causes the ticket to
110 * be created with the given attributes
111 */
112 assert_int_equal(pcmk_ticket_set_attr(&xml, "XYZ", attrs, false), pcmk_rc_ok);
114 pcmk__xml_free(xml);
115
116 cib = cib_new();
118 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"XYZ\"]",
119 &xml_search, cib_xpath);
120
121 assert_string_equal("123", crm_element_value(xml_search, "attrA"));
122 assert_string_equal("456", crm_element_value(xml_search, "attrB"));
123
124 pcmk__xml_free(xml_search);
125 g_hash_table_destroy(attrs);
127}
128
129static void
130overwrite_existing_attr(void **state)
131{
132 GHashTable *attrs = pcmk__strkey_table(free, free);
133 xmlNode *xml = NULL;
134 xmlNode *xml_search = NULL;
135 cib_t *cib;
136
137 pcmk__insert_dup(attrs, "owner", "2");
138
139 assert_int_equal(pcmk_ticket_set_attr(&xml, "ticketA", attrs, false), pcmk_rc_ok);
141 pcmk__xml_free(xml);
142
143 cib = cib_new();
145 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
146 &xml_search, cib_xpath);
147
148 assert_string_equal("2", crm_element_value(xml_search, "owner"));
149
150 pcmk__xml_free(xml_search);
151 g_hash_table_destroy(attrs);
153}
154
155static void
156not_granted_to_granted_without_force(void **state)
157{
158 GHashTable *attrs = pcmk__strkey_table(free, free);
159 xmlNode *xml = NULL;
160 xmlNode *xml_search = NULL;
161 cib_t *cib;
162
163 pcmk__insert_dup(attrs, PCMK__XA_GRANTED, "true");
164
165 assert_int_equal(pcmk_ticket_set_attr(&xml, "ticketA", attrs, false), EACCES);
167 pcmk__xml_free(xml);
168
169 cib = cib_new();
171 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
172 &xml_search, cib_xpath);
173
174 assert_string_equal("false", crm_element_value(xml_search, PCMK__XA_GRANTED));
175 assert_null(crm_element_value(xml_search, PCMK_XA_LAST_GRANTED));
176
177 pcmk__xml_free(xml_search);
178 g_hash_table_destroy(attrs);
180}
181
182static void
183not_granted_to_granted_with_force(void **state)
184{
185 GHashTable *attrs = pcmk__strkey_table(free, free);
186 xmlNode *xml = NULL;
187 xmlNode *xml_search = NULL;
188 cib_t *cib;
189
190 pcmk__insert_dup(attrs, PCMK__XA_GRANTED, "true");
191
192 assert_int_equal(pcmk_ticket_set_attr(&xml, "ticketA", attrs, true), pcmk_rc_ok);
194 pcmk__xml_free(xml);
195
196 cib = cib_new();
198 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
199 &xml_search, cib_xpath);
200
201 assert_string_equal("true", crm_element_value(xml_search, PCMK__XA_GRANTED));
202 assert_non_null(crm_element_value(xml_search, PCMK_XA_LAST_GRANTED));
203
204 pcmk__xml_free(xml_search);
205 g_hash_table_destroy(attrs);
207}
208
209static void
210granted_to_not_granted_without_force(void **state)
211{
212 GHashTable *attrs = pcmk__strkey_table(free, free);
213 xmlNode *xml = NULL;
214 xmlNode *xml_search = NULL;
215 cib_t *cib;
216
217 pcmk__insert_dup(attrs, PCMK__XA_GRANTED, "false");
218
219 assert_int_equal(pcmk_ticket_set_attr(&xml, "ticketB", attrs, false), EACCES);
221 pcmk__xml_free(xml);
222
223 cib = cib_new();
225 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketB\"]",
226 &xml_search, cib_xpath);
227
228 assert_string_equal("true", crm_element_value(xml_search, PCMK__XA_GRANTED));
229 assert_null(crm_element_value(xml_search, PCMK_XA_LAST_GRANTED));
230
231 pcmk__xml_free(xml_search);
232 g_hash_table_destroy(attrs);
234}
235
236static void
237granted_to_not_granted_with_force(void **state)
238{
239 GHashTable *attrs = pcmk__strkey_table(free, free);
240 xmlNode *xml = NULL;
241 xmlNode *xml_search = NULL;
242 cib_t *cib;
243
244 pcmk__insert_dup(attrs, PCMK__XA_GRANTED, "false");
245
246 assert_int_equal(pcmk_ticket_set_attr(&xml, "ticketB", attrs, true), pcmk_rc_ok);
248 pcmk__xml_free(xml);
249
250 cib = cib_new();
252 cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketB\"]",
253 &xml_search, cib_xpath);
254
255 assert_string_equal("false", crm_element_value(xml_search, PCMK__XA_GRANTED));
256 assert_null(crm_element_value(xml_search, PCMK_XA_LAST_GRANTED));
257
258 pcmk__xml_free(xml_search);
259 g_hash_table_destroy(attrs);
261}
262
263/* There are two kinds of tests in this file:
264 *
265 * (1) Those that test what happens if the CIB is not set up correctly, and
266 * (2) Those that test what happens when run against a CIB.
267 *
268 * Therefore, we need two kinds of setup/teardown functions. We only do
269 * minimal overall setup for the entire group, and then setup the CIB for
270 * those tests that need it.
271 */
273 cmocka_unit_test(cib_not_connected),
274 cmocka_unit_test_setup_teardown(bad_arguments, setup_test, teardown_test),
275 cmocka_unit_test_setup_teardown(unknown_ticket_no_attrs, setup_test, teardown_test),
276 cmocka_unit_test_setup_teardown(unknown_ticket_with_attrs, setup_test, teardown_test),
277 cmocka_unit_test_setup_teardown(overwrite_existing_attr, setup_test, teardown_test),
278 cmocka_unit_test_setup_teardown(not_granted_to_granted_without_force, setup_test, teardown_test),
279 cmocka_unit_test_setup_teardown(not_granted_to_granted_with_force, setup_test, teardown_test),
280 cmocka_unit_test_setup_teardown(granted_to_not_granted_without_force, setup_test, teardown_test),
281 cmocka_unit_test_setup_teardown(granted_to_not_granted_with_force, setup_test, teardown_test))
int cib__clean_up_connection(cib_t **cib)
Definition cib_utils.c:942
cib_t * cib_new(void)
Create a new CIB connection object.
Definition cib_client.c:562
@ cib_command
Definition cib_types.h:46
@ cib_xpath
Definition cib_types.h:58
char * crm_system_name
Definition utils.c:45
High Level API.
int pcmk_ticket_set_attr(xmlNodePtr *xml, const char *ticket_id, GHashTable *attr_set, bool force)
Set the given attribute(s) on a ticket.
@ pcmk_rc_ok
Definition results.h:159
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
int(* signon)(cib_t *cib, const char *name, enum cib_conn_type type)
Definition cib_types.h:124
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition cib_types.h:151
cib_api_operations_t * cmds
Definition cib_types.h:325
void pcmk__cib_test_cleanup(char *out_path)
Definition unittest.c:148
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
void pcmk__assert_validates(xmlNode *xml)
Definition unittest.c:22
char * pcmk__cib_test_copy_cib(const char *in_file)
Definition unittest.c:113
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
void pcmk__xml_free(xmlNode *xml)
Definition xml.c:816
#define PCMK_XA_ID
Definition xml_names.h:301
#define PCMK_XA_LAST_GRANTED
Definition xml_names.h:315
#define PCMK__XA_GRANTED
#define PCMK__XE_TICKET_STATE