pacemaker  2.1.9-49aab99839
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 {
46  unsetenv("PCMK_schema_directory");
47  return 0;
48 }
49 
50 static void
51 invalid_name(void **state)
52 {
53  GList *already_included = NULL;
54  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
55 
56  pcmk__build_schema_xml_node(parent, "pacemaker-9.0", &already_included);
57  assert_null(parent->children);
58  assert_null(already_included);
60 }
61 
62 static void
63 single_schema(void **state)
64 {
65  GList *already_included = NULL;
66  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
67  xmlNode *schema_node = NULL;
68  xmlNode *file_node = NULL;
69  int i = 0;
70 
71  pcmk__build_schema_xml_node(parent, "pacemaker-3.0", &already_included);
72 
73  assert_non_null(already_included);
74  assert_non_null(parent->children);
75 
76  /* Test that the result looks like this:
77  *
78  * <schemas>
79  * <schema version="pacemaker-3.0">
80  * <file path="pacemaker-3.0.rng">CDATA</file>
81  * <file path="status-1.0.rng">CDATA</file>
82  * ...
83  * </schema>
84  * </schemas>
85  */
86  schema_node = pcmk__xe_first_child(parent, NULL, NULL, NULL);
87  assert_string_equal("pacemaker-3.0",
88  crm_element_value(schema_node, PCMK_XA_VERSION));
89 
90  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
91  while (file_node != NULL && rngs1[i] != NULL) {
92  assert_string_equal(rngs1[i],
93  crm_element_value(file_node, PCMK_XA_PATH));
94  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
95 
96  file_node = pcmk__xe_next(file_node);
97  i++;
98  }
99 
100  g_list_free_full(already_included, free);
101  free_xml(parent);
102 }
103 
104 static void
105 multiple_schemas(void **state)
106 {
107  GList *already_included = NULL;
108  xmlNode *parent = pcmk__xe_create(NULL, PCMK__XA_SCHEMAS);
109  xmlNode *schema_node = NULL;
110  xmlNode *file_node = NULL;
111  int i = 0;
112 
113  pcmk__build_schema_xml_node(parent, "pacemaker-2.0", &already_included);
114  pcmk__build_schema_xml_node(parent, "pacemaker-2.1", &already_included);
115 
116  assert_non_null(already_included);
117  assert_non_null(parent->children);
118 
119  /* Like single_schema, but make sure files aren't included multiple times
120  * when the function is called repeatedly.
121  */
122  schema_node = pcmk__xe_first_child(parent, NULL, NULL, NULL);
123  assert_string_equal("pacemaker-2.0",
124  crm_element_value(schema_node, PCMK_XA_VERSION));
125 
126  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
127  while (file_node != NULL && rngs2[i] != NULL) {
128  assert_string_equal(rngs2[i],
129  crm_element_value(file_node, PCMK_XA_PATH));
130  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
131 
132  file_node = pcmk__xe_next(file_node);
133  i++;
134  }
135 
136  schema_node = pcmk__xe_next(schema_node);
137  assert_string_equal("pacemaker-2.1",
138  crm_element_value(schema_node, PCMK_XA_VERSION));
139 
140  file_node = pcmk__xe_first_child(schema_node, NULL, NULL, NULL);
141  i = 0;
142 
143  while (file_node != NULL && rngs3[i] != NULL) {
144  assert_string_equal(rngs3[i],
145  crm_element_value(file_node, PCMK_XA_PATH));
146  assert_int_equal(pcmk__xml_first_child(file_node)->type, XML_CDATA_SECTION_NODE);
147 
148  file_node = pcmk__xe_next(file_node);
149  i++;
150  }
151 
152  g_list_free_full(already_included, free);
153  free_xml(parent);
154 }
155 
156 PCMK__UNIT_TEST(setup, teardown,
157  cmocka_unit_test(invalid_name),
158  cmocka_unit_test(single_schema),
159  cmocka_unit_test(multiple_schemas))
#define PCMK_XA_PATH
Definition: xml_names.h:355
#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:458
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition: xml.c:481
#define PCMK__XA_SCHEMAS
const char * rngs1[]
int pcmk__xml_test_setup_group(void **state)
Definition: unittest.c:85
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
Definition: xml.c:958
int pcmk__xml_test_teardown_group(void **state)
Definition: unittest.c:104
const char * rngs2[]
void pcmk__build_schema_xml_node(xmlNode *parent, const char *name, GList **already_included)
Definition: schemas.c:1558
const char * rngs3[]
const char * parent
Definition: cib.c:27
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition: xml.c:770
#define PCMK_XA_VERSION
Definition: xml_names.h:444