pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
crm_schema_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 <ftw.h>
13 #include <unistd.h>
14 
15 #include <crm/common/xml.h>
18 #include "crmcommon_private.h"
19 
20 static char *remote_schema_dir = NULL;
21 
22 static int
23 symlink_schema(const char *tmpdir, const char *target_file, const char *link_file)
24 {
25  int rc = 0;
26  char *oldpath = NULL;
27  char *newpath = NULL;
28 
29  oldpath = crm_strdup_printf("%s/%s", PCMK__TEST_SCHEMA_DIR, target_file);
30  newpath = crm_strdup_printf("%s/%s", tmpdir, link_file);
31 
32  rc = symlink(oldpath, newpath);
33 
34  free(oldpath);
35  free(newpath);
36  return rc;
37 }
38 
39 static int
40 rm_files(const char *pathname, const struct stat *sbuf, int type, struct FTW *ftwb)
41 {
42  return remove(pathname);
43 }
44 
45 static int
46 rmtree(const char *dir)
47 {
48  return nftw(dir, rm_files, 10, FTW_DEPTH|FTW_MOUNT|FTW_PHYS);
49 }
50 
51 static int
52 setup(void **state)
53 {
54  char *dir = NULL;
55 
56  /* Create a directory to hold additional schema files. These don't need
57  * to be anything special - we can just copy existing schemas but give
58  * them new names.
59  */
60  dir = crm_strdup_printf("%s/test-schemas.XXXXXX", pcmk__get_tmpdir());
61  remote_schema_dir = mkdtemp(dir);
62 
63  if (remote_schema_dir == NULL) {
64  free(dir);
65  return -1;
66  }
67 
68  /* Add new files to simulate a remote node not being up-to-date. We can't
69  * add a new major version here without also creating an XSL transform, and
70  * we can't add an older version (like 1.1 or 2.11 or something) because
71  * remotes will only ever ask for stuff newer than their newest.
72  */
73  if (symlink_schema(dir, "pacemaker-3.0.rng", "pacemaker-3.1.rng") != 0) {
74  rmdir(dir);
75  free(dir);
76  return -1;
77  }
78 
79  if (symlink_schema(dir, "pacemaker-3.0.rng", "pacemaker-3.2.rng") != 0) {
80  rmdir(dir);
81  free(dir);
82  return -1;
83  }
84 
85  setenv("PCMK_remote_schema_directory", remote_schema_dir, 1);
86  setenv("PCMK_schema_directory", PCMK__TEST_SCHEMA_DIR, 1);
87 
88  /* Do not call crm_schema_init here because that is the function we're
89  * testing. It needs to be called in each unit test. However, we can
90  * call crm_schema_cleanup in teardown().
91  */
92 
93  return 0;
94 }
95 
96 static int
97 teardown(void **state)
98 {
99  int rc = 0;
100  char *f = NULL;
101 
103  unsetenv("PCMK_remote_schema_directory");
104  unsetenv("PCMK_schema_directory");
105 
106  rc = rmtree(remote_schema_dir);
107 
108  free(remote_schema_dir);
109  free(f);
110  return rc;
111 }
112 
113 static void
114 assert_schema(const char *schema_name, int schema_index)
115 {
116  GList *entry = NULL;
117  pcmk__schema_t *schema = NULL;
118 
119  entry = pcmk__get_schema(schema_name);
120  assert_non_null(entry);
121 
122  schema = entry->data;
123  assert_non_null(schema);
124 
125  assert_int_equal(schema_index, schema->schema_index);
126 }
127 
128 static void
129 extra_schema_files(void **state)
130 {
131  crm_schema_init();
132 
133  /* Just iterate through the list of schemas and make sure everything
134  * (including the new schemas we loaded from a second directory) is in
135  * the right order.
136  */
137  assert_schema("pacemaker-1.0", 0);
138  assert_schema("pacemaker-1.2", 1);
139  assert_schema("pacemaker-2.0", 3);
140  assert_schema("pacemaker-3.0", 14);
141  assert_schema("pacemaker-3.1", 15);
142  assert_schema("pacemaker-3.2", 16);
143 
144  // @COMPAT pacemaker-next is deprecated since 2.1.5
145  assert_schema("pacemaker-next", 17);
146 
147  // @COMPAT none is deprecated since 2.1.8
148  assert_schema(PCMK_VALUE_NONE, 18);
149 }
150 
151 PCMK__UNIT_TEST(setup, teardown,
152  cmocka_unit_test(extra_schema_files));
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
PCMK__UNIT_TEST(setup, teardown, cmocka_unit_test(extra_schema_files))
#define PCMK_VALUE_NONE
Definition: options.h:178
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
GList * pcmk__get_schema(const char *name)
Definition: schemas.c:663
Wrappers for and extensions to libxml2.
const char * pcmk__get_tmpdir(void)
Definition: io.c:547