pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
crm_xml_init_test.c
Go to the documentation of this file.
1 /*
2  * Copyright 2023-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/common/xml.h>
15 
16 #include "crmcommon_private.h"
17 
18 /* Copied from lib/common/xml.c */
19 #define XML_DOC_PRIVATE_MAGIC 0x81726354UL
20 #define XML_NODE_PRIVATE_MAGIC 0x54637281UL
21 
22 static int
23 setup(void **state) {
24  crm_xml_init();
25  return 0;
26 }
27 
28 static int
29 teardown(void **state) {
31  return 0;
32 }
33 
34 static void
35 buffer_scheme_test(void **state) {
36  assert_int_equal(XML_BUFFER_ALLOC_DOUBLEIT, xmlGetBufferAllocationScheme());
37 }
38 
39 /* These functions also serve as unit tests of the static new_private_data
40  * function. We can't test free_private_data because libxml will call that as
41  * part of freeing everything else. By the time we'd get back into a unit test
42  * where we could check that private members are NULL, the structure containing
43  * the private data would have been freed.
44  *
45  * This could probably be tested with a lot of function mocking, but that
46  * doesn't seem worth it.
47  */
48 
49 static void
50 create_document_node(void **state) {
51  xml_doc_private_t *docpriv = NULL;
52  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
53 
54  /* Double check things */
55  assert_non_null(doc);
56  assert_int_equal(doc->type, XML_DOCUMENT_NODE);
57 
58  /* Check that the private data is initialized correctly */
59  docpriv = doc->_private;
60  assert_non_null(docpriv);
61  assert_int_equal(docpriv->check, XML_DOC_PRIVATE_MAGIC);
62  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty|pcmk__xf_created));
63 
64  /* Clean up */
65  xmlFreeDoc(doc);
66 }
67 
68 static void
69 create_element_node(void **state) {
70  xml_doc_private_t *docpriv = NULL;
71  xml_node_private_t *priv = NULL;
72  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
73  xmlNodePtr node = xmlNewDocNode(doc, NULL, (pcmkXmlStr) "test", NULL);
74 
75  /* Adding a node to the document marks it as dirty */
76  docpriv = doc->_private;
77  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
78 
79  /* Double check things */
80  assert_non_null(node);
81  assert_int_equal(node->type, XML_ELEMENT_NODE);
82 
83  /* Check that the private data is initialized correctly */
84  priv = node->_private;
85  assert_non_null(priv);
86  assert_int_equal(priv->check, XML_NODE_PRIVATE_MAGIC);
87  assert_true(pcmk_all_flags_set(priv->flags, pcmk__xf_dirty|pcmk__xf_created));
88 
89  /* Clean up */
90  xmlFreeNode(node);
91  xmlFreeDoc(doc);
92 }
93 
94 static void
95 create_attr_node(void **state) {
96  xml_doc_private_t *docpriv = NULL;
97  xml_node_private_t *priv = NULL;
98  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
99  xmlNodePtr node = xmlNewDocNode(doc, NULL, (pcmkXmlStr) "test", NULL);
100  xmlAttrPtr attr = xmlNewProp(node, (pcmkXmlStr) PCMK_XA_NAME,
101  (pcmkXmlStr) "dummy-value");
102 
103  /* Adding a node to the document marks it as dirty */
104  docpriv = doc->_private;
105  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
106 
107  /* Double check things */
108  assert_non_null(attr);
109  assert_int_equal(attr->type, XML_ATTRIBUTE_NODE);
110 
111  /* Check that the private data is initialized correctly */
112  priv = attr->_private;
113  assert_non_null(priv);
114  assert_int_equal(priv->check, XML_NODE_PRIVATE_MAGIC);
115  assert_true(pcmk_all_flags_set(priv->flags, pcmk__xf_dirty|pcmk__xf_created));
116 
117  /* Clean up */
118  xmlFreeNode(node);
119  xmlFreeDoc(doc);
120 }
121 
122 static void
123 create_comment_node(void **state) {
124  xml_doc_private_t *docpriv = NULL;
125  xml_node_private_t *priv = NULL;
126  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
127  xmlNodePtr node = xmlNewDocComment(doc, (pcmkXmlStr) "blahblah");
128 
129  /* Adding a node to the document marks it as dirty */
130  docpriv = doc->_private;
131  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
132 
133  /* Double check things */
134  assert_non_null(node);
135  assert_int_equal(node->type, XML_COMMENT_NODE);
136 
137  /* Check that the private data is initialized correctly */
138  priv = node->_private;
139  assert_non_null(priv);
140  assert_int_equal(priv->check, XML_NODE_PRIVATE_MAGIC);
141  assert_true(pcmk_all_flags_set(priv->flags, pcmk__xf_dirty|pcmk__xf_created));
142 
143  /* Clean up */
144  xmlFreeNode(node);
145  xmlFreeDoc(doc);
146 }
147 
148 static void
149 create_text_node(void **state) {
150  xml_doc_private_t *docpriv = NULL;
151  xml_node_private_t *priv = NULL;
152  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
153  xmlNodePtr node = xmlNewDocText(doc, (pcmkXmlStr) "blahblah");
154 
155  /* Adding a node to the document marks it as dirty */
156  docpriv = doc->_private;
157  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
158 
159  /* Double check things */
160  assert_non_null(node);
161  assert_int_equal(node->type, XML_TEXT_NODE);
162 
163  /* Check that no private data was created */
164  priv = node->_private;
165  assert_null(priv);
166 
167  /* Clean up */
168  xmlFreeNode(node);
169  xmlFreeDoc(doc);
170 }
171 
172 static void
173 create_dtd_node(void **state) {
174  xml_doc_private_t *docpriv = NULL;
175  xml_node_private_t *priv = NULL;
176  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
177  xmlDtdPtr dtd = xmlNewDtd(doc, (pcmkXmlStr) PCMK_XA_NAME,
178  (pcmkXmlStr) "externalId",
179  (pcmkXmlStr) "systemId");
180 
181  /* Adding a node to the document marks it as dirty */
182  docpriv = doc->_private;
183  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
184 
185  /* Double check things */
186  assert_non_null(dtd);
187  assert_int_equal(dtd->type, XML_DTD_NODE);
188 
189  /* Check that no private data was created */
190  priv = dtd->_private;
191  assert_null(priv);
192 
193  /* Clean up */
194  /* If you call xmlFreeDtd before xmlFreeDoc, you get a segfault */
195  xmlFreeDoc(doc);
196 }
197 
198 static void
199 create_cdata_node(void **state) {
200  xml_doc_private_t *docpriv = NULL;
201  xml_node_private_t *priv = NULL;
202  xmlDocPtr doc = xmlNewDoc(PCMK__XML_VERSION);
203  xmlNodePtr node = xmlNewCDataBlock(doc, (pcmkXmlStr) "blahblah", 8);
204 
205  /* Adding a node to the document marks it as dirty */
206  docpriv = doc->_private;
207  assert_true(pcmk_all_flags_set(docpriv->flags, pcmk__xf_dirty));
208 
209  /* Double check things */
210  assert_non_null(node);
211  assert_int_equal(node->type, XML_CDATA_SECTION_NODE);
212 
213  /* Check that no private data was created */
214  priv = node->_private;
215  assert_null(priv);
216 
217  /* Clean up */
218  xmlFreeNode(node);
219  xmlFreeDoc(doc);
220 }
221 
222 PCMK__UNIT_TEST(setup, teardown,
223  cmocka_unit_test(buffer_scheme_test),
224  cmocka_unit_test(create_document_node),
225  cmocka_unit_test(create_element_node),
226  cmocka_unit_test(create_attr_node),
227  cmocka_unit_test(create_comment_node),
228  cmocka_unit_test(create_text_node),
229  cmocka_unit_test(create_dtd_node),
230  cmocka_unit_test(create_cdata_node));
#define XML_NODE_PRIVATE_MAGIC
#define PCMK_XA_NAME
Definition: xml_names.h:325
void crm_xml_cleanup(void)
Definition: xml.c:2143
#define XML_DOC_PRIVATE_MAGIC
void crm_xml_init(void)
Initialize the CRM XML subsystem.
Definition: xml.c:2121
Wrappers for and extensions to libxml2.
const xmlChar * pcmkXmlStr
Definition: xml.h:41
#define PCMK__XML_VERSION
libxml2 supports only XML version 1.0, at least as of libxml2-2.12.5
PCMK__UNIT_TEST(setup, teardown, cmocka_unit_test(buffer_scheme_test), cmocka_unit_test(create_document_node), cmocka_unit_test(create_element_node), cmocka_unit_test(create_attr_node), cmocka_unit_test(create_comment_node), cmocka_unit_test(create_text_node), cmocka_unit_test(create_dtd_node), cmocka_unit_test(create_cdata_node))