pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
pcmk__build_schema_xml_node_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 <glib.h>
17 
18 const char *rngs1[] = { "pacemaker-3.0.rng", "status-1.0.rng", "alerts-2.10.rng",
19  "nvset-2.9.rng", "score.rng", "rule-2.9.rng",
20  "tags-1.3.rng", "acls-2.0.rng", "fencing-2.4.rng",
21  "constraints-3.0.rng", "resources-3.0.rng", "nvset-3.0.rng",
22  "nodes-3.0.rng", "options-3.0.rng", NULL };
23 
24 const char *rngs2[] = { "pacemaker-2.0.rng", "status-1.0.rng", "tags-1.3.rng",
25  "acls-2.0.rng", "fencing-1.2.rng", "constraints-1.2.rng",
26  "rule.rng", "score.rng", "resources-1.3.rng",
27  "nvset-1.3.rng", "nodes-1.3.rng", "options-1.0.rng",
28  "nvset.rng", "cib-1.2.rng", NULL };
29 
30 const char *rngs3[] = { "pacemaker-2.1.rng", "constraints-2.1.rng", NULL };
31 
32 static int
33 setup(void **state)
34 {
35  setenv("PCMK_schema_directory", PCMK__TEST_SCHEMA_DIR, 1);
38  return 0;
39 }
40 
41 static int
42 teardown(void **state)
43 {
45  unsetenv("PCMK_schema_directory");
46  return 0;
47 }
48 
49 static void
50 invalid_name(void **state)
51 {
52  GList *already_included = NULL;
53  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
54 
55  pcmk__build_schema_xml_node(parent, "pacemaker-9.0", &already_included);
56  assert_null(parent->children);
57  assert_null(already_included);
59 }
60 
61 static void
62 single_schema(void **state)
63 {
64  GList *already_included = NULL;
65  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
66  xmlNode *schema_node = NULL;
67  xmlNode *file_node = NULL;
68  int i = 0;
69 
70  pcmk__build_schema_xml_node(parent, "pacemaker-3.0", &already_included);
71 
72  assert_non_null(already_included);
73  assert_non_null(parent->children);
74 
75  /* Test that the result looks like this:
76  *
77  * <schemas>
78  * <schema version="pacemaker-3.0">
79  * <file path="pacemaker-3.0.rng">CDATA</file>
80  * <file path="status-1.0.rng">CDATA</file>
81  * ...
82  * </schema>
83  * </schemas>
84  */
85  schema_node = pcmk__xe_first_child(parent, NULL, NULL, NULL);
86  assert_string_equal("pacemaker-3.0",
87  crm_element_value(schema_node, PCMK_XA_VERSION));
88 
89  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
90  while (file_node != NULL && rngs1[i] != NULL) {
91  assert_string_equal(rngs1[i],
92  crm_element_value(file_node, PCMK_XA_PATH));
93  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
94 
95  file_node = pcmk__xe_next(file_node);
96  i++;
97  }
98 
99  g_list_free_full(already_included, free);
100  free_xml(parent);
101 }
102 
103 static void
104 multiple_schemas(void **state)
105 {
106  GList *already_included = NULL;
107  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
108  xmlNode *schema_node = NULL;
109  xmlNode *file_node = NULL;
110  int i = 0;
111 
112  pcmk__build_schema_xml_node(parent, "pacemaker-2.0", &already_included);
113  pcmk__build_schema_xml_node(parent, "pacemaker-2.1", &already_included);
114 
115  assert_non_null(already_included);
116  assert_non_null(parent->children);
117 
118  /* Like single_schema, but make sure files aren't included multiple times
119  * when the function is called repeatedly.
120  */
121  schema_node = pcmk__xe_first_child(parent, NULL, NULL, NULL);
122  assert_string_equal("pacemaker-2.0",
123  crm_element_value(schema_node, PCMK_XA_VERSION));
124 
125  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
126  while (file_node != NULL && rngs2[i] != NULL) {
127  assert_string_equal(rngs2[i],
128  crm_element_value(file_node, PCMK_XA_PATH));
129  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
130 
131  file_node = pcmk__xe_next(file_node);
132  i++;
133  }
134 
135  schema_node = pcmk__xe_next(schema_node);
136  assert_string_equal("pacemaker-2.1",
137  crm_element_value(schema_node, PCMK_XA_VERSION));
138 
139  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
140  i = 0;
141 
142  while (file_node != NULL && rngs3[i] != NULL) {
143  assert_string_equal(rngs3[i],
144  crm_element_value(file_node, PCMK_XA_PATH));
145  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
146 
147  file_node = pcmk__xe_next(file_node);
148  i++;
149  }
150 
151  g_list_free_full(already_included, free);
152  free_xml(parent);
153 }
154 
155 PCMK__UNIT_TEST(setup, teardown,
156  cmocka_unit_test(invalid_name),
157  cmocka_unit_test(single_schema),
158  cmocka_unit_test(multiple_schemas))
#define PCMK_XA_PATH
Definition: xml_names.h:350
#define PCMK__UNIT_TEST(group_setup, group_teardown,...)
void crm_schema_init(void)
Definition: schemas.c:470
enum crm_ais_msg_types type
Definition: cpg.c:51
void crm_schema_cleanup(void)
Definition: schemas.c:643
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:446
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition: xml.c:440
#define PCMK__XA_SCHEMAS
const char * rngs1[]
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:74
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
Definition: xml.c:867
const char * rngs2[]
void pcmk__build_schema_xml_node(xmlNode *parent, const char *name, GList **already_included)
Definition: schemas.c:1552
const char * rngs3[]
const char * parent
Definition: cib.c:27
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition: xml.c:720
#define PCMK_XA_VERSION
Definition: xml_names.h:439