pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_ticket_state_test.c
Go to the documentation of this file.
1/*
2 * Copyright 2024-2025 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#include <libxml/xpath.h> // xmlXPathObject, etc.
18
19static char *cib_path = NULL;
20
21static void
22cib_not_connected(void **state)
23{
24 xmlNode *xml = NULL;
25
26 /* Without any special setup, cib_new() in pcmk_ticket_state will use the
27 * native CIB which means IPC calls. But there's nothing listening for those
28 * calls, so signon() will return ENOTCONN. Check that we handle that.
29 */
30 assert_int_equal(pcmk_ticket_state(&xml, "ticketA"), ENOTCONN);
32 pcmk__xml_free(xml);
33}
34
35static int
36setup_test(void **state)
37{
38 cib_path = pcmk__cib_test_copy_cib("tickets.xml");
39
40 if (cib_path == NULL) {
41 return -1;
42 }
43
44 return 0;
45}
46
47static int
48teardown_test(void **state)
49{
50 pcmk__cib_test_cleanup(cib_path);
51 cib_path = NULL;
52 return 0;
53}
54
55static void
56bad_arguments(void **state)
57{
58 assert_int_equal(pcmk_ticket_state(NULL, "ticketA"), EINVAL);
59}
60
61static void
62unknown_ticket(void **state)
63{
64 xmlNode *xml = NULL;
65
66 assert_int_equal(pcmk_ticket_state(&xml, "XYZ"), ENXIO);
68 pcmk__xml_free(xml);
69}
70
71static void
72ticket_exists(void **state)
73{
74 xmlNode *xml = NULL;
75 xmlXPathObject *xpath_obj = NULL;
76
77 assert_int_equal(pcmk_ticket_state(&xml, "ticketA"), pcmk_rc_ok);
79
80 /* Verify that the XML result has only one <ticket>, and that its ID is
81 * what we asked for.
82 */
83 xpath_obj = pcmk__xpath_search(xml->doc,
86 "[@" PCMK_XA_ID "=\"ticketA\"]");
87
88 assert_int_equal(pcmk__xpath_num_results(xpath_obj), 1);
89 xmlXPathFreeObject(xpath_obj);
90 pcmk__xml_free(xml);
91}
92
93static void
94multiple_tickets(void **state)
95{
96 xmlNode *xml = NULL;
97 xmlNode *ticket_node = NULL;
98 xmlXPathObject *xpath_obj = NULL;
99
100 assert_int_equal(pcmk_ticket_state(&xml, NULL), pcmk_rc_ok);
102
103 /* Verify that the XML result has four <ticket> elements, and that their
104 * IDs are as expected.
105 */
106 xpath_obj = pcmk__xpath_search(xml->doc,
109
110 assert_int_equal(pcmk__xpath_num_results(xpath_obj), 4);
111
112 ticket_node = pcmk__xpath_result(xpath_obj, 0);
113 assert_non_null(ticket_node);
114 assert_string_equal(crm_element_value(ticket_node, PCMK_XA_ID), "ticketA");
115
116 ticket_node = pcmk__xpath_result(xpath_obj, 1);
117 assert_non_null(ticket_node);
118 assert_string_equal(crm_element_value(ticket_node, PCMK_XA_ID), "ticketB");
119
120 ticket_node = pcmk__xpath_result(xpath_obj, 2);
121 assert_non_null(ticket_node);
122 assert_string_equal(crm_element_value(ticket_node, PCMK_XA_ID), "ticketC");
123
124 ticket_node = pcmk__xpath_result(xpath_obj, 3);
125 assert_non_null(ticket_node);
126 assert_string_equal(crm_element_value(ticket_node, PCMK_XA_ID), "ticketC");
127
128 xmlXPathFreeObject(xpath_obj);
129 pcmk__xml_free(xml);
130}
131
132static void
133duplicate_tickets(void **state)
134{
135 xmlNode *xml = NULL;
136 xmlXPathObject *xpath_obj = NULL;
137
138 assert_int_equal(pcmk_ticket_state(&xml, "ticketC"), pcmk_rc_duplicate_id);
139
140 /* Verify that the XML result has two <ticket> elements, and that their
141 * IDs are as expected.
142 */
143 xpath_obj = pcmk__xpath_search(xml->doc,
146 "[@" PCMK_XA_ID "=\"ticketC\"]");
147
148 assert_int_equal(pcmk__xpath_num_results(xpath_obj), 2);
149 xmlXPathFreeObject(xpath_obj);
150 pcmk__xml_free(xml);
151}
152
153/* There are two kinds of tests in this file:
154 *
155 * (1) Those that test what happens if the CIB is not set up correctly, and
156 * (2) Those that test what happens when run against a CIB.
157 *
158 * Therefore, we need two kinds of setup/teardown functions. We only do
159 * minimal overall setup for the entire group, and then setup the CIB for
160 * those tests that need it.
161 */
163 cmocka_unit_test(cib_not_connected),
164 cmocka_unit_test_setup_teardown(bad_arguments, setup_test, teardown_test),
165 cmocka_unit_test_setup_teardown(unknown_ticket, setup_test, teardown_test),
166 cmocka_unit_test_setup_teardown(ticket_exists, setup_test, teardown_test),
167 cmocka_unit_test_setup_teardown(multiple_tickets, setup_test, teardown_test),
168 cmocka_unit_test_setup_teardown(duplicate_tickets, setup_test, teardown_test))
High Level API.
int pcmk_ticket_state(xmlNodePtr *xml, const char *ticket_id)
Return a ticket's state XML.
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_rc_duplicate_id
Definition results.h:121
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_XE_TICKET
Definition xml_names.h:212
#define PCMK_XA_ID
Definition xml_names.h:301
#define PCMK_XE_TICKETS
Definition xml_names.h:213
#define PCMK_XE_PACEMAKER_RESULT
Definition xml_names.h:156
xmlXPathObject * pcmk__xpath_search(xmlDoc *doc, const char *path)
Definition xpath.c:137
xmlNode * pcmk__xpath_result(xmlXPathObject *xpath_obj, int index)
Definition xpath.c:65