pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
pcmk_resource_delete_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_resource_delete 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_resource_delete(&xml, "rsc", "primitive"), ENOTCONN);
30  free_xml(xml);
31 }
32 
33 static int
34 setup_test(void **state)
35 {
36  cib_path = pcmk__cib_test_copy_cib("crm_mon.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_input(void **state)
55 {
56  xmlNode *xml = NULL;
57 
58  /* There is a primitive resource named "Fencing", so we're just checking
59  * that it returns EINVAL if both parameters aren't given.
60  */
61  assert_int_equal(pcmk_resource_delete(&xml, "Fencing", NULL), EINVAL);
63  free_xml(xml);
64  xml = NULL;
65 
66  assert_int_equal(pcmk_resource_delete(&xml, NULL, "primitive"), EINVAL);
68  free_xml(xml);
69 }
70 
71 static xmlNode *
72 find_rsc(const char *rsc)
73 {
74  GString *xpath = g_string_sized_new(1024);
75  xmlNode *xml_search = NULL;
76  cib_t *cib = NULL;
77 
78  cib = cib_new();
80 
81  pcmk__g_strcat(xpath,
83  "//*[@" PCMK_XA_ID "=\"", rsc, "\"]", NULL);
84 
85  cib->cmds->query(cib, (const char *) xpath->str, &xml_search,
87 
88  g_string_free(xpath, TRUE);
90  return xml_search;
91 }
92 
93 static void
94 incorrect_type(void **state)
95 {
96  xmlNode *xml = NULL;
97  xmlNode *result = NULL;
98 
99  /* cib_process_delete returns pcmk_ok even if given the wrong type so
100  * we have to do an xpath query of the CIB to make sure it's still
101  * there.
102  */
103  assert_int_equal(pcmk_resource_delete(&xml, "Fencing", "clone"), pcmk_rc_ok);
105  free_xml(xml);
106 
107  result = find_rsc("Fencing");
108  assert_non_null(result);
109 
110  free_xml(result);
111 }
112 
113 static void
114 correct_type(void **state)
115 {
116  xmlNode *xml = NULL;
117  xmlNode *result = NULL;
118 
119  assert_int_equal(pcmk_resource_delete(&xml, "Fencing", "primitive"), pcmk_rc_ok);
121  free_xml(xml);
122 
123  result = find_rsc("Fencing");
124  assert_null(result);
125 
126  free_xml(result);
127 }
128 
129 static void
130 unknown_resource(void **state)
131 {
132  xmlNode *xml = NULL;
133 
134  /* cib_process_delete returns pcmk_ok even if asked to delete something
135  * that doesn't exist.
136  */
137  assert_int_equal(pcmk_resource_delete(&xml, "no_such_resource", "primitive"), pcmk_rc_ok);
139  free_xml(xml);
140 }
141 
142 /* There are two kinds of tests in this file:
143  *
144  * (1) Those that test what happens if the CIB is not set up correctly, and
145  * (2) Those that test what happens when run against a CIB.
146  *
147  * Therefore, we need two kinds of setup/teardown functions. We only do
148  * minimal overall setup for the entire group, and then setup the CIB for
149  * those tests that need it.
150  */
152  cmocka_unit_test(cib_not_connected),
153  cmocka_unit_test_setup_teardown(bad_input, setup_test, teardown_test),
154  cmocka_unit_test_setup_teardown(incorrect_type, setup_test, teardown_test),
155  cmocka_unit_test_setup_teardown(correct_type, setup_test, teardown_test),
156  cmocka_unit_test_setup_teardown(unknown_resource, setup_test, teardown_test))
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
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1296
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
const char * pcmk_cib_xpath_for(const char *element_name)
Get the relative XPath needed to find a specified CIB element name.
Definition: cib.c:112
pcmk__action_result_t result
Definition: pcmk_fence.c:35
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_XE_RESOURCES
Definition: xml_names.h:175
int pcmk_resource_delete(xmlNodePtr *xml, const char *rsc_id, const char *rsc_type)
Remove a resource.