pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
pcmk_ticket_remove_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 
17 static char *cib_path = NULL;
18 
19 static void
20 cib_not_connected(void **state)
21 {
22  xmlNode *xml = NULL;
23 
24  /* Without any special setup, cib_new() in pcmk_ticket_remove_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_remove_attr(&xml, NULL, NULL, false), ENOTCONN);
30  free_xml(xml);
31 }
32 
33 static int
34 setup_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 
45 static int
46 teardown_test(void **state)
47 {
48  pcmk__cib_test_cleanup(cib_path);
49  cib_path = NULL;
50  return 0;
51 }
52 
53 static void
54 bad_arguments(void **state)
55 {
56  xmlNode *xml = NULL;
57 
58  assert_int_equal(pcmk_ticket_remove_attr(NULL, "ticketA", NULL, false), EINVAL);
59 
60  assert_int_equal(pcmk_ticket_remove_attr(&xml, NULL, NULL, false), EINVAL);
62  free_xml(xml);
63 }
64 
65 static void
66 no_attrs(void **state)
67 {
68  GList *attrs = NULL;
69  xmlNode *xml = NULL;
70  xmlNode *xml_search = NULL;
71  cib_t *cib = cib_new();
72 
74 
75  /* Deleting no attributes on a ticket that doesn't exist is a no-op */
76  assert_int_equal(pcmk_ticket_remove_attr(&xml, "XYZ", NULL, false), pcmk_rc_ok);
78  free_xml(xml);
79  xml = NULL;
80 
81  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"XYZ\"]",
82  &xml_search, cib_xpath | cib_scope_local);
83  assert_null(xml_search);
84 
85  /* Deleting no attributes on a ticket that exists is also a no-op */
86  assert_int_equal(pcmk_ticket_remove_attr(&xml, "ticketA", NULL, false), pcmk_rc_ok);
88  free_xml(xml);
89  xml = NULL;
90 
91  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
92  &xml_search, cib_xpath | cib_scope_local);
93  assert_string_equal("1", crm_element_value(xml_search, "owner"));
94  free_xml(xml_search);
95 
96  /* Another way of specifying no attributes */
97  assert_int_equal(pcmk_ticket_remove_attr(&xml, "XYZ", attrs, false), pcmk_rc_ok);
99  free_xml(xml);
100 
101  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"XYZ\"]",
102  &xml_search, cib_xpath | cib_scope_local);
103  assert_null(xml_search);
104 
105  g_list_free(attrs);
107 }
108 
109 static void
110 remove_missing_attrs(void **state)
111 {
112  GList *attrs = NULL;
113  xmlNode *xml = NULL;
114  xmlNode *xml_search = NULL;
115  cib_t *cib;
116 
117  attrs = g_list_append(attrs, strdup("XYZ"));
118 
119  /* Deleting an attribute that doesn't exist is a no-op */
120  assert_int_equal(pcmk_ticket_remove_attr(&xml, "ticketA", attrs, false), pcmk_rc_ok);
122  free_xml(xml);
123 
124  cib = cib_new();
125  cib->cmds->signon(cib, crm_system_name, cib_command);
126  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
127  &xml_search, cib_xpath | cib_scope_local);
128 
129  assert_string_equal("1", crm_element_value(xml_search, "owner"));
130  assert_null(crm_element_value(xml_search, "XYZ"));
131 
132  free_xml(xml_search);
133  g_list_free_full(attrs, free);
135 }
136 
137 static void
138 remove_existing_attr(void **state)
139 {
140  GList *attrs = NULL;
141  xmlNode *xml = NULL;
142  xmlNode *xml_search = NULL;
143  cib_t *cib;
144 
145  attrs = g_list_append(attrs, strdup("owner"));
146 
147  assert_int_equal(pcmk_ticket_remove_attr(&xml, "ticketA", attrs, false), pcmk_rc_ok);
149  free_xml(xml);
150 
151  cib = cib_new();
152  cib->cmds->signon(cib, crm_system_name, cib_command);
153  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketA\"]",
154  &xml_search, cib_xpath | cib_scope_local);
155 
156  assert_null(crm_element_value(xml_search, "owner"));
157 
158  free_xml(xml_search);
159  g_list_free_full(attrs, free);
161 }
162 
163 static void
164 remove_granted_without_force(void **state)
165 {
166  GList *attrs = NULL;
167  xmlNode *xml = NULL;
168  xmlNode *xml_search = NULL;
169  cib_t *cib;
170 
171  attrs = g_list_append(attrs, strdup(PCMK__XA_GRANTED));
172 
173  assert_int_equal(pcmk_ticket_remove_attr(&xml, "ticketB", attrs, false), EACCES);
175  free_xml(xml);
176 
177  cib = cib_new();
178  cib->cmds->signon(cib, crm_system_name, cib_command);
179  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketB\"]",
180  &xml_search, cib_xpath | cib_scope_local);
181 
182  assert_string_equal("true", crm_element_value(xml_search, PCMK__XA_GRANTED));
183 
184  free_xml(xml_search);
185  g_list_free_full(attrs, free);
187 }
188 
189 static void
190 remove_granted_with_force(void **state)
191 {
192  GList *attrs = NULL;
193  xmlNode *xml = NULL;
194  xmlNode *xml_search = NULL;
195  cib_t *cib;
196 
197  attrs = g_list_append(attrs, strdup(PCMK__XA_GRANTED));
198 
199  assert_int_equal(pcmk_ticket_remove_attr(&xml, "ticketB", attrs, true), pcmk_rc_ok);
201  free_xml(xml);
202 
203  cib = cib_new();
204  cib->cmds->signon(cib, crm_system_name, cib_command);
205  cib->cmds->query(cib, "//" PCMK__XE_TICKET_STATE "[@" PCMK_XA_ID "=\"ticketB\"]",
206  &xml_search, cib_xpath | cib_scope_local);
207 
208  assert_null(crm_element_value(xml_search, PCMK__XA_GRANTED));
209 
210  free_xml(xml_search);
211  g_list_free_full(attrs, free);
213 }
214 
215 /* There are two kinds of tests in this file:
216  *
217  * (1) Those that test what happens if the CIB is not set up correctly, and
218  * (2) Those that test what happens when run against a CIB.
219  *
220  * Therefore, we need two kinds of setup/teardown functions. We only do
221  * minimal overall setup for the entire group, and then setup the CIB for
222  * those tests that need it.
223  */
225  cmocka_unit_test(cib_not_connected),
226  cmocka_unit_test_setup_teardown(bad_arguments, setup_test, teardown_test),
227  cmocka_unit_test_setup_teardown(no_attrs, setup_test, teardown_test),
228  cmocka_unit_test_setup_teardown(remove_missing_attrs, setup_test, teardown_test),
229  cmocka_unit_test_setup_teardown(remove_existing_attr, setup_test, teardown_test),
230  cmocka_unit_test_setup_teardown(remove_granted_without_force, setup_test, teardown_test),
231  cmocka_unit_test_setup_teardown(remove_granted_with_force, setup_test, teardown_test))
#define PCMK__XE_TICKET_STATE
cib_t * cib_new(void)
Create a new CIB connection object.
Definition: cib_client.c:616
High Level API.
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
char * crm_system_name
Definition: utils.c:50
cib_api_operations_t * cmds
Definition: cib_types.h:399
int(* signon)(cib_t *cib, const char *name, enum cib_conn_type type)
Definition: cib_types.h:159
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:446
int pcmk_ticket_remove_attr(xmlNodePtr *xml, const char *ticket_id, GList *attr_delete, bool force)
Remove the given attribute(s) from a ticket.
Definition: pcmk_ticket.c:416
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:74
Wrappers for and extensions to libxml2.
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:198
#define PCMK_XA_ID
Definition: xml_names.h:296
void free_xml(xmlNode *child)
Definition: xml.c:867
int cib__clean_up_connection(cib_t **cib)
Definition: cib_utils.c:1046
void pcmk__cib_test_cleanup(char *out_path)
Definition: unittest.c:121
void pcmk__assert_validates(xmlNode *xml)
Definition: unittest.c:20
char * pcmk__cib_test_copy_cib(const char *in_file)
Definition: unittest.c:86
#define PCMK__XA_GRANTED