blob: cfba1d30f3d6db4036b586ed2ea772965a9f300e [file] [log] [blame]
Michal Vaskof20ad112023-02-10 15:12:12 +01001/**
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_context.c
Radek Iša56ca9e42020-09-08 18:42:00 +02003 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from context.c
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14#define _UTEST_MAIN_
15#include "utests.h"
16
17#include "common.h"
18#include "context.h"
19#include "in.h"
20#include "schema_compile.h"
Radek Krejcief5f7672021-04-01 17:04:12 +020021#include "tests_config.h"
Radek Iša56ca9e42020-09-08 18:42:00 +020022#include "tree_schema_internal.h"
Jan Kundráte2789d32021-12-13 18:28:45 +010023#ifdef _WIN32
24static void
25slashes_to_backslashes(char *path)
26{
27 while ((path = strchr(path, '/'))) {
28 *path++ = '\\';
29 }
30}
31
32static void
33test_searchdirs(void **state)
34{
35 const char * const *list;
36 char *path1 = strdup(TESTS_BIN "/utests");
37 char *path2 = strdup(TESTS_SRC);
38
39 slashes_to_backslashes(path1);
40 slashes_to_backslashes(path2);
41
42 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(NULL, NULL));
43 CHECK_LOG("Invalid argument ctx (ly_ctx_set_searchdir()).", NULL);
44 assert_null(ly_ctx_get_searchdirs(NULL));
45 CHECK_LOG("Invalid argument ctx (ly_ctx_get_searchdirs()).", NULL);
46 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(NULL, NULL));
47 CHECK_LOG("Invalid argument ctx (ly_ctx_unset_searchdir()).", NULL);
48
49 /* correct path */
50 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, path1));
51 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
52 assert_string_equal(path1, UTEST_LYCTX->search_paths.objs[0]);
53
54 /* duplicated paths */
55 assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(UTEST_LYCTX, path1));
56 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
57 assert_string_equal(path1, UTEST_LYCTX->search_paths.objs[0]);
58
59 /* another path */
60 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, path2));
61 assert_int_equal(2, UTEST_LYCTX->search_paths.count);
62 assert_string_equal(path2, UTEST_LYCTX->search_paths.objs[1]);
63
64 /* get searchpaths */
65 list = ly_ctx_get_searchdirs(UTEST_LYCTX);
66 assert_non_null(list);
67 assert_string_equal(path1, list[0]);
68 assert_string_equal(path2, list[1]);
69 assert_null(list[2]);
70
71 /* removing searchpaths */
72 /* nonexisting */
73 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(UTEST_LYCTX, "/nonexistingfile"));
74 CHECK_LOG_CTX("Invalid argument value (ly_ctx_unset_searchdir()).", NULL);
75
76 /* first */
77 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, path1));
78 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
79 assert_string_not_equal(path1, list[0]);
80
81 /* second */
82 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, path2));
83 assert_int_equal(0, UTEST_LYCTX->search_paths.count);
84
85 free(path1);
86 free(path2);
87}
88
89#else
90
Radek Iša56ca9e42020-09-08 18:42:00 +020091static void
92test_searchdirs(void **state)
93{
94 const char * const *list;
95
96 /* invalid arguments */
97 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(NULL, NULL));
98 CHECK_LOG("Invalid argument ctx (ly_ctx_set_searchdir()).", NULL);
99 assert_null(ly_ctx_get_searchdirs(NULL));
100 CHECK_LOG("Invalid argument ctx (ly_ctx_get_searchdirs()).", NULL);
101 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(NULL, NULL));
102 CHECK_LOG("Invalid argument ctx (ly_ctx_unset_searchdir()).", NULL);
103
104 /* readable and executable, but not a directory */
105 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utest_context"));
106 CHECK_LOG_CTX("Given search directory \""TESTS_BIN "/utest_context\" is not a directory.", NULL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200107 /* not existing */
108 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(UTEST_LYCTX, "/nonexistingfile"));
109 CHECK_LOG_CTX("Unable to use search directory \"/nonexistingfile\" (No such file or directory).", NULL);
110
111 /* ly_set_add() fails */
112 /* no change */
113 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, NULL));
114
115 /* correct path */
116 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
117 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
118 assert_string_equal(TESTS_BIN "/utests", UTEST_LYCTX->search_paths.objs[0]);
119
120 /* duplicated paths */
121 assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
122 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
123 assert_string_equal(TESTS_BIN "/utests", UTEST_LYCTX->search_paths.objs[0]);
124
125 /* another paths - add 8 to fill the initial buffer of the searchpaths list */
126 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/CMakeFiles"));
127 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../src"));
128 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../CMakeModules"));
129 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../doc"));
130 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC));
131 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN));
132 assert_int_equal(7, UTEST_LYCTX->search_paths.count);
133
134 /* get searchpaths */
135 list = ly_ctx_get_searchdirs(UTEST_LYCTX);
136 assert_non_null(list);
137 assert_string_equal(TESTS_BIN "/utests", list[0]);
138 assert_string_equal(TESTS_BIN "/CMakeFiles", list[1]);
139 assert_string_equal(TESTS_SRC, list[5]);
140 assert_string_equal(TESTS_BIN, list[6]);
141 assert_null(list[7]);
142
143 /* removing searchpaths */
144 /* nonexisting */
145 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(UTEST_LYCTX, "/nonexistingfile"));
146 CHECK_LOG_CTX("Invalid argument value (ly_ctx_unset_searchdir()).", NULL);
147 /* first */
148 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
149 assert_string_not_equal(TESTS_BIN "/utests", list[0]);
150 assert_int_equal(6, UTEST_LYCTX->search_paths.count);
151 /* middle */
152 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_SRC));
153 assert_int_equal(5, UTEST_LYCTX->search_paths.count);
154 /* last */
155 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_BIN));
156 assert_int_equal(4, UTEST_LYCTX->search_paths.count);
157 /* all */
158 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, NULL));
159 assert_int_equal(0, UTEST_LYCTX->search_paths.count);
160
161 /* again - no change */
162 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, NULL));
163
164 /* cleanup */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200165 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200166
167 /* test searchdir list in ly_ctx_new() */
168 assert_int_equal(LY_EINVAL, ly_ctx_new("/nonexistingfile", 0, &UTEST_LYCTX));
169 CHECK_LOG("Unable to use search directory \"/nonexistingfile\" (No such file or directory).", NULL);
Jan Kundrát34bb9282021-12-13 18:45:50 +0100170 assert_int_equal(LY_SUCCESS,
171 ly_ctx_new(TESTS_SRC PATH_SEPARATOR TESTS_BIN PATH_SEPARATOR TESTS_BIN PATH_SEPARATOR TESTS_SRC,
172 LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
Radek Iša56ca9e42020-09-08 18:42:00 +0200173 assert_int_equal(2, UTEST_LYCTX->search_paths.count);
174 assert_string_equal(TESTS_SRC, UTEST_LYCTX->search_paths.objs[0]);
175 assert_string_equal(TESTS_BIN, UTEST_LYCTX->search_paths.objs[1]);
176}
177
Jan Kundráte2789d32021-12-13 18:28:45 +0100178#endif
179
Radek Iša56ca9e42020-09-08 18:42:00 +0200180static void
181test_options(void **state)
182{
183 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200184 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200185
186 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0xffff, &UTEST_LYCTX));
187
188 /* invalid arguments */
189 assert_int_equal(0, ly_ctx_get_options(NULL));
190 CHECK_LOG("Invalid argument ctx (ly_ctx_get_options()).", NULL);
191
192 assert_int_equal(LY_EINVAL, ly_ctx_set_options(NULL, 0));
193 CHECK_LOG("Invalid argument ctx (ly_ctx_set_options()).", NULL);
194 assert_int_equal(LY_EINVAL, ly_ctx_unset_options(NULL, 0));
195 CHECK_LOG("Invalid argument ctx (ly_ctx_unset_options()).", NULL);
196
Radek Iša56ca9e42020-09-08 18:42:00 +0200197 /* unset */
198 /* LY_CTX_ALL_IMPLEMENTED */
199 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
200 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_ALL_IMPLEMENTED));
201 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
202
203 /* LY_CTX_REF_IMPLEMENTED */
204 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
205 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED));
206 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
207
208 /* LY_CTX_DISABLE_SEARCHDIRS */
209 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
210 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIRS));
211 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
212
213 /* LY_CTX_DISABLE_SEARCHDIR_CWD */
214 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
215 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIR_CWD));
216 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
217
218 /* LY_CTX_PREFER_SEARCHDIRS */
219 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
220 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_PREFER_SEARCHDIRS));
221 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
222
223 assert_int_equal(UTEST_LYCTX->flags, ly_ctx_get_options(UTEST_LYCTX));
224
225 /* set back */
226 /* LY_CTX_ALL_IMPLEMENTED */
227 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_ALL_IMPLEMENTED));
228 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
229
230 /* LY_CTX_REF_IMPLEMENTED */
231 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED));
232 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
233
234 /* LY_CTX_DISABLE_SEARCHDIRS */
235 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIRS));
236 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
237
238 /* LY_CTX_DISABLE_SEARCHDIR_CWD */
239 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIR_CWD));
240 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
241
242 /* LY_CTX_PREFER_SEARCHDIRS */
243 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_PREFER_SEARCHDIRS));
244 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
245
246 assert_int_equal(UTEST_LYCTX->flags, ly_ctx_get_options(UTEST_LYCTX));
247}
248
249static LY_ERR
250test_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const char *UNUSED(submod_name),
251 const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format,
252 const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
253{
254 *module_data = user_data;
255 *format = LYS_IN_YANG;
256 *free_module_data = NULL;
257 return LY_SUCCESS;
258}
259
260static void
261test_models(void **state)
262{
263 struct ly_in *in;
264 const char *str;
265 struct lys_module *mod1, *mod2;
266 struct lys_glob_unres unres = {0};
267
268 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200269 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200270
271 /* invalid arguments */
Michal Vasko794ab4b2021-03-31 09:42:19 +0200272 assert_int_equal(0, ly_ctx_get_change_count(NULL));
273 CHECK_LOG("Invalid argument ctx (ly_ctx_get_change_count()).", NULL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200274
275 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
Michal Vasko794ab4b2021-03-31 09:42:19 +0200276 assert_int_equal(UTEST_LYCTX->change_count, ly_ctx_get_change_count(UTEST_LYCTX));
Radek Iša56ca9e42020-09-08 18:42:00 +0200277
278 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200279 assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, 4, NULL, NULL, &unres.creating, &mod1));
Michal Vaskof4258e12021-06-15 12:11:42 +0200280 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200281 ly_in_free(in, 0);
282 CHECK_LOG_CTX("Invalid schema input format.", NULL);
283
284 /* import callback */
285 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)(str = "test"));
286 assert_ptr_equal(test_imp_clb, UTEST_LYCTX->imp_clb);
287 assert_ptr_equal(str, UTEST_LYCTX->imp_clb_data);
288 assert_ptr_equal(test_imp_clb, ly_ctx_get_module_imp_clb(UTEST_LYCTX, (void **)&str));
289 assert_string_equal("test", str);
290
291 ly_ctx_set_module_imp_clb(UTEST_LYCTX, NULL, NULL);
292 assert_null(UTEST_LYCTX->imp_clb);
293 assert_null(UTEST_LYCTX->imp_clb_data);
294
295 /* name collision of module and submodule */
296 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-30;}");
297 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;include y;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200298 assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
Michal Vaskof4258e12021-06-15 12:11:42 +0200299 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200300 ly_in_free(in, 0);
Michal Vasko62af3692023-02-09 14:00:09 +0100301 CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL);
302 CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200303
304 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y;revision 2018-10-30; }", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200305 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 ly_in_free(in, 0);
307 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200308 assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
Michal Vaskof4258e12021-06-15 12:11:42 +0200309 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200310 ly_in_free(in, 0);
Michal Vasko62af3692023-02-09 14:00:09 +0100311 CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL);
312 CHECK_LOG_CTX("Name collision between module and submodule of name \"y\".", "Line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200313
314 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to b {prefix b;}}");
315 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module b {namespace urn:b;prefix b;include y;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200316 assert_int_equal(LY_EVALID, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod1));
Michal Vaskof4258e12021-06-15 12:11:42 +0200317 lys_unres_glob_revert(UTEST_LYCTX, &unres);
318 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200319 ly_in_free(in, 0);
Michal Vasko62af3692023-02-09 14:00:09 +0100320 CHECK_LOG_CTX("Parsing module \"b\" failed.", NULL);
321 CHECK_LOG_CTX("Including \"y\" submodule into \"b\" failed.", NULL);
322 CHECK_LOG_CTX("Parsing submodule failed.", NULL);
323 CHECK_LOG_CTX("Name collision between submodules of name \"y\".", "Line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200324
325 /* selecting correct revision of the submodules */
326 ly_ctx_reset_latests(UTEST_LYCTX);
327 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-31;}");
328 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module a {namespace urn:a;prefix a;include y; revision 2018-10-31;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200329 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
Michal Vaskof4258e12021-06-15 12:11:42 +0200330 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200331 ly_in_free(in, 0);
332 assert_string_equal("2018-10-31", mod2->parsed->includes[0].submodule->revs[0].date);
333
334 /* reloading module in case only the compiled module resists in the context */
335 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module w {namespace urn:w;prefix w;revision 2018-10-24;}", &in));
Michal Vasko4de7d072021-07-09 09:13:18 +0200336 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod1));
Radek Iša56ca9e42020-09-08 18:42:00 +0200337 ly_in_free(in, 0);
Radek Iša56ca9e42020-09-08 18:42:00 +0200338 assert_non_null(mod1->compiled);
339 assert_non_null(mod1->parsed);
340
Radek Iša56ca9e42020-09-08 18:42:00 +0200341 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module z {namespace urn:z;prefix z;import w {prefix w;revision-date 2018-10-24;}}", &in));
342 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module w {namespace urn:w;prefix w;revision 2018-10-24;}");
Michal Vasko4de7d072021-07-09 09:13:18 +0200343 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod2));
Radek Iša56ca9e42020-09-08 18:42:00 +0200344 ly_in_free(in, 0);
345 assert_non_null(mod2);
346 assert_non_null(mod1->parsed);
347 assert_string_equal("w", mod1->name);
348}
349
350static void
351test_imports(void **state)
352{
aPiecekd4911ee2021-07-30 07:40:24 +0200353 struct lys_module *mod1, *mod2, *mod3, *import;
aPiecek9f8c7e72021-07-28 12:01:56 +0200354 char *str;
aPiecekd4911ee2021-07-30 07:40:24 +0200355 uint16_t ctx_options;
Radek Iša56ca9e42020-09-08 18:42:00 +0200356
357 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200358 ly_ctx_destroy(UTEST_LYCTX);
aPiecekd4911ee2021-07-30 07:40:24 +0200359 ctx_options = LY_CTX_DISABLE_SEARCHDIRS | LY_CTX_NO_YANGLIBRARY;
Radek Iša56ca9e42020-09-08 18:42:00 +0200360
aPiecekd4911ee2021-07-30 07:40:24 +0200361 /* Import callback provides newer revision of module 'a',
362 * however the older revision is implemented soon and therefore it is preferred. */
363 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
Radek Iša56ca9e42020-09-08 18:42:00 +0200364 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-17;}");
365 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-16;}",
366 LYS_IN_YANG, &mod1));
aPiecek8ca21bd2021-07-26 14:31:01 +0200367 assert_true(LYS_MOD_LATEST_REV & mod1->latest_revision);
Radek Iša56ca9e42020-09-08 18:42:00 +0200368 assert_int_equal(1, mod1->implemented);
369 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
370 LYS_IN_YANG, &mod2));
aPiecekd4911ee2021-07-30 07:40:24 +0200371 assert_ptr_equal(mod1, mod2->parsed->imports[0].module);
372 assert_true((LYS_MOD_LATEST_REV | LYS_MOD_IMPORTED_REV) & mod1->latest_revision);
373 assert_string_equal("2019-09-16", mod1->revision);
374 assert_int_equal(1, mod1->implemented);
Radek Iša56ca9e42020-09-08 18:42:00 +0200375 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200376 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200377
aPiecekd4911ee2021-07-30 07:40:24 +0200378 /* Import callback provides older revision of module 'a' and it is
379 * imported by another module, so it is preferred even if newer
380 * revision is implemented later. */
381 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
382 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-16;}");
Radek Iša56ca9e42020-09-08 18:42:00 +0200383 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
384 LYS_IN_YANG, &mod2));
aPiecekd4911ee2021-07-30 07:40:24 +0200385 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-17;}",
386 LYS_IN_YANG, &mod1));
387 ly_log_level(LY_LLVRB);
388 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module c {namespace urn:c;prefix c;import a {prefix a;}}",
389 LYS_IN_YANG, &mod3));
390 CHECK_LOG("Implemented module \"a@2019-09-17\" is not used for import, revision \"2019-09-16\" is imported instead.", NULL);
391 ly_log_level(LY_LLWRN);
392 assert_true(LYS_MOD_LATEST_SEARCHDIRS & mod1->latest_revision);
393 assert_int_equal(1, mod1->implemented);
Radek Iša56ca9e42020-09-08 18:42:00 +0200394 import = mod2->parsed->imports[0].module;
aPiecekd4911ee2021-07-30 07:40:24 +0200395 assert_true(LYS_MOD_IMPORTED_REV & import->latest_revision);
396 assert_string_equal("2019-09-16", import->revision);
397 assert_int_equal(0, import->implemented);
398 import = mod3->parsed->imports[0].module;
399 assert_string_equal("2019-09-16", import->revision);
400 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
401 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-17"));
402 assert_string_equal("2019-09-17", ly_ctx_get_module_implemented(UTEST_LYCTX, "a")->revision);
aPiecek9f8c7e72021-07-28 12:01:56 +0200403 ly_ctx_destroy(UTEST_LYCTX);
404
405 /* check of circular dependency */
aPiecekd4911ee2021-07-30 07:40:24 +0200406 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
aPiecek9f8c7e72021-07-28 12:01:56 +0200407 str = "module a {namespace urn:a; prefix a;"
408 "import b {prefix b;}"
409 "}";
410 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, str);
411 str = "module b { yang-version 1.1; namespace urn:b; prefix b;"
412 "import a {prefix a;}"
413 "}";
414 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Michal Vasko62af3692023-02-09 14:00:09 +0100415 ly_err_clean(UTEST_LYCTX, NULL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200416}
417
418static void
419test_get_models(void **state)
420{
421 struct lys_module *mod, *mod2;
422 const char *str0 = "module a {namespace urn:a;prefix a;}";
423 const char *str1 = "module a {namespace urn:a;prefix a;revision 2018-10-23;}";
424 const char *str2 = "module a {namespace urn:a;prefix a;revision 2018-10-23;revision 2018-10-24;}";
425 struct ly_in *in0, *in1, *in2;
426 struct lys_glob_unres unres = {0};
427
428 unsigned int index = 0;
Michal Vaskoddd76592022-01-17 13:34:48 +0100429 const char *names[] = {
430 "ietf-yang-metadata", "yang", "ietf-inet-types", "ietf-yang-types", "ietf-yang-schema-mount",
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200431 "ietf-yang-structure-ext", "ietf-datastores", "ietf-yang-library", "a", "a", "a"
Michal Vaskoddd76592022-01-17 13:34:48 +0100432 };
Radek Iša56ca9e42020-09-08 18:42:00 +0200433
434 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str0, &in0));
435 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
436 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str2, &in2));
437
438 /* invalid arguments */
439 assert_ptr_equal(NULL, ly_ctx_get_module(NULL, NULL, NULL));
440 CHECK_LOG("Invalid argument ctx (ly_ctx_get_module()).", NULL);
441 assert_ptr_equal(NULL, ly_ctx_get_module(UTEST_LYCTX, NULL, NULL));
442 CHECK_LOG_CTX("Invalid argument name (ly_ctx_get_module()).", NULL);
443 assert_ptr_equal(NULL, ly_ctx_get_module_ns(NULL, NULL, NULL));
444 CHECK_LOG("Invalid argument ctx (ly_ctx_get_module_ns()).", NULL);
445 assert_ptr_equal(NULL, ly_ctx_get_module_ns(UTEST_LYCTX, NULL, NULL));
446 CHECK_LOG_CTX("Invalid argument ns (ly_ctx_get_module_ns()).", NULL);
447 assert_null(ly_ctx_get_module(UTEST_LYCTX, "nonsence", NULL));
448
449 /* internal modules */
450 assert_null(ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-yang-types"));
451 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "yang");
452 assert_non_null(mod);
453 assert_non_null(mod->parsed);
454 assert_string_equal("yang", mod->name);
455 mod2 = ly_ctx_get_module_implemented_ns(UTEST_LYCTX, mod->ns);
456 assert_ptr_equal(mod, mod2);
457 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-yang-metadata", "2016-08-05"));
458 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-yang-types", "2013-07-15"));
459 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-inet-types", "2013-07-15"));
460 assert_non_null(ly_ctx_get_module_ns(UTEST_LYCTX, "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
461
462 /* select module by revision */
Michal Vasko4de7d072021-07-09 09:13:18 +0200463 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, &mod));
Radek Iša56ca9e42020-09-08 18:42:00 +0200464 /* invalid attempts - implementing module of the same name and inserting the same module */
Michal Vaskodd992582021-06-10 14:34:57 +0200465 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
Michal Vasko4e205e82021-06-08 14:01:47 +0200466 assert_int_equal(LY_EDENIED, lys_implement(mod2, NULL, &unres));
Michal Vasko978532b2022-01-21 14:13:40 +0100467 CHECK_LOG_CTX("Module \"a@2018-10-24\" is already implemented in revision \"2018-10-23\".", NULL);
Michal Vaskof4258e12021-06-15 12:11:42 +0200468 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200469 ly_in_reset(in1);
470 /* it is already there, fine */
Michal Vaskodd992582021-06-10 14:34:57 +0200471 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres.creating, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200472 /* insert the second module only as imported, not implemented */
Michal Vaskof4258e12021-06-15 12:11:42 +0200473 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200474 ly_in_reset(in2);
Michal Vaskodd992582021-06-10 14:34:57 +0200475 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in2, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod2));
Michal Vaskof4258e12021-06-15 12:11:42 +0200476 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200477 assert_non_null(mod2);
478 assert_ptr_not_equal(mod, mod2);
479 mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
480 assert_ptr_equal(mod, mod2);
481 mod2 = ly_ctx_get_module_latest_ns(UTEST_LYCTX, mod->ns);
482 assert_ptr_equal(mod, mod2);
483 /* work with module with no revision */
Michal Vaskodd992582021-06-10 14:34:57 +0200484 assert_int_equal(LY_SUCCESS, lys_parse_in(UTEST_LYCTX, in0, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
Michal Vaskof4258e12021-06-15 12:11:42 +0200485 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200486 assert_ptr_equal(mod, ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
487 assert_ptr_not_equal(mod, ly_ctx_get_module_latest(UTEST_LYCTX, "a"));
488
489 str1 = "submodule b {belongs-to a {prefix a;}}";
490 ly_in_free(in1, 0);
491 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
Michal Vaskodd992582021-06-10 14:34:57 +0200492 assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, NULL, &unres.creating, &mod));
Radek Iša56ca9e42020-09-08 18:42:00 +0200493 CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
Michal Vaskof4258e12021-06-15 12:11:42 +0200494 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200495
496 while ((mod = (struct lys_module *)ly_ctx_get_module_iter(UTEST_LYCTX, &index))) {
497 assert_string_equal(names[index - 1], mod->name);
498 }
Michal Vaskoedb0fa52022-10-04 10:36:00 +0200499 assert_int_equal(11, index);
Radek Iša56ca9e42020-09-08 18:42:00 +0200500
501 /* cleanup */
502 ly_in_free(in0, 0);
503 ly_in_free(in1, 0);
504 ly_in_free(in2, 0);
505}
506
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200507static void
508test_ylmem(void **state)
509{
510#define DATA_YANG_LIBRARY_START "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"\
511 " <module-set>\n"\
512 " <name>complete</name>\n"\
513 " <module>\n"\
514 " <name>yang</name>\n"\
Michal Vasko79a7a872022-06-17 09:00:48 +0200515 " <revision>2022-06-16</revision>\n"\
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200516 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"\
517 " </module>\n"\
518 " <module>\n"\
519 " <name>ietf-yang-library</name>\n"\
520 " <revision>2019-01-04</revision>\n"\
521 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"\
522 " </module>\n"
523
524#define DATA_YANG_BASE_IMPORTS " <import-only-module>\n"\
525 " <name>ietf-yang-metadata</name>\n"\
526 " <revision>2016-08-05</revision>\n"\
527 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"\
528 " </import-only-module>\n"\
529 " <import-only-module>\n"\
530 " <name>ietf-inet-types</name>\n"\
531 " <revision>2013-07-15</revision>\n"\
532 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"\
533 " </import-only-module>\n"\
534 " <import-only-module>\n"\
535 " <name>ietf-yang-types</name>\n"\
536 " <revision>2013-07-15</revision>\n"\
537 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"\
538 " </import-only-module>\n"\
539 " <import-only-module>\n"\
540 " <name>ietf-datastores</name>\n"\
541 " <revision>2018-02-14</revision>\n"\
542 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"\
543 " </import-only-module>\n"
544
545#define DATA_YANG_SCHEMA_MODULE_STATE " </module-set>\n"\
546 " <schema>\n"\
547 " <name>complete</name>\n"\
548 " <module-set>complete</module-set>\n"\
549 " </schema>\n"\
550 " <content-id>9</content-id>\n"\
551 "</yang-library>\n"\
552 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"\
553 " <module-set-id>12</module-set-id>\n"\
554 " <module>\n"\
555 " <name>ietf-yang-metadata</name>\n"\
556 " <revision>2016-08-05</revision>\n"\
557 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"\
558 " <conformance-type>import</conformance-type>\n"\
559 " </module>\n"\
560 " <module>\n"\
561 " <name>yang</name>\n"\
Michal Vasko79a7a872022-06-17 09:00:48 +0200562 " <revision>2022-06-16</revision>\n"\
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200563 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"\
564 " <conformance-type>implement</conformance-type>\n"\
565 " </module>\n"\
566 " <module>\n"\
567 " <name>ietf-inet-types</name>\n"\
568 " <revision>2013-07-15</revision>\n"\
569 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"\
570 " <conformance-type>import</conformance-type>\n"\
571 " </module>\n"\
572 " <module>\n"\
573 " <name>ietf-yang-types</name>\n"\
574 " <revision>2013-07-15</revision>\n"\
575 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"\
576 " <conformance-type>import</conformance-type>\n"\
577 " </module>\n"\
578 " <module>\n"\
579 " <name>ietf-yang-library</name>\n"\
580 " <revision>2019-01-04</revision>\n"\
581 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"\
582 " <conformance-type>implement</conformance-type>\n"\
583 " </module>\n"\
584 " <module>\n"\
585 " <name>ietf-datastores</name>\n"\
586 " <revision>2018-02-14</revision>\n"\
587 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"\
588 " <conformance-type>import</conformance-type>\n"\
589 " </module>\n"
590
591 const char *yanglibrary_only =
592 DATA_YANG_LIBRARY_START
593 DATA_YANG_BASE_IMPORTS
594 DATA_YANG_SCHEMA_MODULE_STATE
595 "</modules-state>\n";
596
597 const char *with_netconf =
598 DATA_YANG_LIBRARY_START
599 " <module>\n"
600 " <name>ietf-netconf</name>\n"
601 " <revision>2011-06-01</revision>\n"
602 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
603 " </module>\n"
604 DATA_YANG_BASE_IMPORTS
605 " <import-only-module>\n"
606 " <name>ietf-netconf-acm</name>\n"
607 " <revision>2018-02-14</revision>\n"
608 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
609 " </import-only-module>\n"
610 DATA_YANG_SCHEMA_MODULE_STATE
611 " <module>\n"
612 " <name>ietf-netconf</name>\n"
613 " <revision>2011-06-01</revision>\n"
614 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
615 " <conformance-type>implement</conformance-type>\n"
616 " </module>\n"
617 " <module>\n"
618 " <name>ietf-netconf-acm</name>\n"
619 " <revision>2018-02-14</revision>\n"
620 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
621 " <conformance-type>import</conformance-type>\n"
622 " </module>\n"
623 "</modules-state>";
624
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200625 char *with_netconf_features = malloc(8096);
Michal Vasko2bf4af42023-01-04 12:08:38 +0100626
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200627 strcpy(with_netconf_features,
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200628 DATA_YANG_LIBRARY_START
629 " <module>\n"
630 " <name>ietf-netconf</name>\n"
631 " <revision>2011-06-01</revision>\n"
632 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
633 " <feature>writable-running</feature>\n"
634 " <feature>candidate</feature>\n"
635 " <feature>confirmed-commit</feature>\n"
636 " <feature>rollback-on-error</feature>\n"
637 " <feature>validate</feature>\n"
638 " <feature>startup</feature>\n"
639 " <feature>url</feature>\n"
640 " <feature>xpath</feature>\n"
641 " </module>\n"
642 " <import-only-module>\n"
643 " <name>ietf-yang-metadata</name>\n"
644 " <revision>2016-08-05</revision>\n"
645 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"
646 " </import-only-module>\n"
647 " <import-only-module>\n"
648 " <name>ietf-inet-types</name>\n"
649 " <revision>2013-07-15</revision>\n"
650 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"
651 " </import-only-module>\n"
652 " <import-only-module>\n"
653 " <name>ietf-yang-types</name>\n"
654 " <revision>2013-07-15</revision>\n"
655 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"
656 " </import-only-module>\n"
657 " <import-only-module>\n"
658 " <name>ietf-datastores</name>\n"
659 " <revision>2018-02-14</revision>\n"
660 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"
661 " </import-only-module>\n"
662 " <import-only-module>\n"
663 " <name>ietf-netconf-acm</name>\n"
664 " <revision>2018-02-14</revision>\n"
665 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200666 " </import-only-module>\n");
667 strcpy(with_netconf_features + strlen(with_netconf_features),
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200668 DATA_YANG_SCHEMA_MODULE_STATE
669 " <module>\n"
670 " <name>ietf-netconf</name>\n"
671 " <revision>2011-06-01</revision>\n"
672 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
673 " <feature>writable-running</feature>\n"
674 " <feature>candidate</feature>\n"
675 " <feature>confirmed-commit</feature>\n"
676 " <feature>rollback-on-error</feature>\n"
677 " <feature>validate</feature>\n"
678 " <feature>startup</feature>\n"
679 " <feature>url</feature>\n"
680 " <feature>xpath</feature>\n"
681 " <conformance-type>implement</conformance-type>\n"
682 " </module>\n"
683 " <module>\n"
684 " <name>ietf-netconf-acm</name>\n"
685 " <revision>2018-02-14</revision>\n"
686 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
687 " <conformance-type>import</conformance-type>\n"
688 " </module>\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200689 "</modules-state>");
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200690
691 const char *garbage_revision =
692 "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
693 " <module-set>\n"
694 " <name>complete</name>\n"
695 " <module>\n"
696 " <name>yang</name>\n"
Michal Vasko79a7a872022-06-17 09:00:48 +0200697 " <revision>2022-06-16</revision>\n"
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200698 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
699 " </module>\n"
700 " <module>\n"
701 " <name>ietf-yang-library</name>\n"
702 " <revision>2019-01-01</revision>\n"
703 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
704 " </module>\n"
705 DATA_YANG_BASE_IMPORTS
706 DATA_YANG_SCHEMA_MODULE_STATE
707 "</modules-state>\n";
708
709 const char *no_yanglibrary =
710 "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
711 " <module-set>\n"
712 " <name>complete</name>\n"
713 " <module>\n"
714 " <name>yang</name>\n"
Michal Vasko79a7a872022-06-17 09:00:48 +0200715 " <revision>2022-06-16</revision>\n"
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200716 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
717 " </module>\n"
718 DATA_YANG_BASE_IMPORTS
719 DATA_YANG_SCHEMA_MODULE_STATE
720 "</modules-state>\n";
721
722 (void) state;
723 /* seperate context to avoid double free during teadown */
724 struct ly_ctx *ctx_test = NULL;
725
726 /* test invalid parameters */
727 assert_int_equal(LY_EINVAL, ly_ctx_new_ylpath(NULL, NULL, LYD_XML, 0, &ctx_test));
728 assert_int_equal(LY_EINVAL, ly_ctx_new_ylpath(NULL, TESTS_SRC, LYD_XML, 0, NULL));
729 assert_int_equal(LY_ESYS, ly_ctx_new_ylpath(NULL, TESTS_SRC "garbage", LYD_XML, 0, &ctx_test));
730
731 /* basic test with ietf-yang-library-only */
732 assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", yanglibrary_only, LYD_XML, 0, &ctx_test));
Michal Vaskoad8d0f52021-04-26 13:21:24 +0200733 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-yang-library", "2019-01-04"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200734 assert_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200735 ly_ctx_destroy(ctx_test);
ekinzie0ab8b302022-10-10 03:03:57 -0400736 ctx_test = NULL;
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200737
738 /* test loading module, should also import other module */
739 assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf, LYD_XML, 0, &ctx_test));
Michal Vaskoad8d0f52021-04-26 13:21:24 +0200740 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200741 assert_int_equal(1, ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01")->implemented);
Michal Vaskoad8d0f52021-04-26 13:21:24 +0200742 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200743 assert_int_equal(0, ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14")->implemented);
744 assert_int_equal(LY_ENOT, lys_feature_value(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"), "url"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200745 ly_ctx_destroy(ctx_test);
ekinzie0ab8b302022-10-10 03:03:57 -0400746 ctx_test = NULL;
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200747
748 /* test loading module with feature if they are present */
749 assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf_features, LYD_XML, 0, &ctx_test));
Michal Vaskoad8d0f52021-04-26 13:21:24 +0200750 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
751 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200752 assert_int_equal(LY_SUCCESS, lys_feature_value(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"), "url"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200753 ly_ctx_destroy(ctx_test);
ekinzie0ab8b302022-10-10 03:03:57 -0400754 ctx_test = NULL;
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200755
756 /* test with not matching revision */
757 assert_int_equal(LY_EINVAL, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", garbage_revision, LYD_XML, 0, &ctx_test));
758
759 /* test data containing ietf-yang-library which conflicts with the option */
760 assert_int_equal(LY_EINVAL, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf_features, LYD_XML, LY_CTX_NO_YANGLIBRARY, &ctx_test));
761
762 /* test creating without ietf-yang-library */
763 assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", no_yanglibrary, LYD_XML, LY_CTX_NO_YANGLIBRARY, &ctx_test));
764 assert_int_equal(NULL, ly_ctx_get_module(ctx_test, "ietf-yang-library", "2019-01-04"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200765 ly_ctx_destroy(ctx_test);
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200766 free(with_netconf_features);
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200767}
768
aPiecekbb96b802021-04-12 08:12:52 +0200769static LY_ERR
770check_node_priv_parsed_is_set(struct lysc_node *node, void *data, ly_bool *UNUSED(dfs_continue))
771{
772 const struct lysp_node *pnode;
773 const char ***iter;
774
775 pnode = (const struct lysp_node *)node->priv;
776 CHECK_POINTER(pnode, 1);
777 iter = (const char ***)data;
778 CHECK_POINTER(**iter, 1);
779 CHECK_STRING(pnode->name, **iter);
780 (*iter)++;
781
782 return LY_SUCCESS;
783}
784
785static LY_ERR
786check_node_priv_parsed_not_set(struct lysc_node *node, void *UNUSED(data), ly_bool *UNUSED(dfs_continue))
787{
788 CHECK_POINTER(node->priv, 0);
789 return LY_SUCCESS;
790}
791
aPiecekfcfec0f2021-04-23 12:47:30 +0200792static void
793check_ext_instance_priv_parsed_is_set(struct lysc_ext_instance *ext)
794{
795 LY_ARRAY_COUNT_TYPE u, v;
796 struct lysc_ext_substmt *substmts;
797 struct lysc_node *cnode;
798 const char **iter;
799 const char *check[] = {
800 "tmp_cont", "lf", NULL
801 };
802
803 LY_ARRAY_FOR(ext, u) {
804 substmts = ext[u].substmts;
805 LY_ARRAY_FOR(substmts, v) {
Michal Vasko193dacd2022-10-13 08:43:05 +0200806 if (substmts && substmts[v].storage && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
aPiecekfcfec0f2021-04-23 12:47:30 +0200807 cnode = *(struct lysc_node **)substmts[v].storage;
808 iter = check;
809 assert_int_equal(LY_SUCCESS, lysc_tree_dfs_full(cnode, check_node_priv_parsed_is_set, &iter));
810 }
811 }
812 }
813}
814
815static void
816check_ext_instance_priv_parsed_not_set(struct lysc_ext_instance *ext)
817{
818 LY_ARRAY_COUNT_TYPE u, v;
819 struct lysc_ext_substmt *substmts;
820 struct lysc_node *cnode;
821
822 LY_ARRAY_FOR(ext, u) {
823 substmts = ext[u].substmts;
824 LY_ARRAY_FOR(substmts, v) {
Michal Vasko193dacd2022-10-13 08:43:05 +0200825 if (substmts && substmts[v].storage && (substmts[v].stmt & LY_STMT_DATA_NODE_MASK)) {
aPiecekfcfec0f2021-04-23 12:47:30 +0200826 cnode = *(struct lysc_node **)substmts[v].storage;
827 if (cnode) {
828 CHECK_POINTER((struct lysp_node *)cnode->priv, 0);
829 }
830 }
831 }
832 }
833}
834
aPiecekbb96b802021-04-12 08:12:52 +0200835/**
836 * @brief Testing of LY_CTX_SET_PRIV_PARSED.
837 */
838static void
839test_set_priv_parsed(void **state)
840{
Michal Vasko4de7d072021-07-09 09:13:18 +0200841 struct lys_module *mod;
aPiecekbb96b802021-04-12 08:12:52 +0200842 const char *schema_a;
843 const char **iter;
844 const char *check[] = {
Michal Vasko95f736c2022-06-08 12:03:31 +0200845 "cont", "contnotif", "contx", "grpleaf", "augleaf", "l1",
aPiecekbb96b802021-04-12 08:12:52 +0200846 "l1a", "l1b", "l1c", "foo1", "ll", "any", "l2",
847 "l2c", "l2cx", "ch", "cas", "casx", "oper",
848 "input", "inparam", "output", "outparam", "n1", NULL
849 };
850
851 /* each node must have a unique name. */
852 schema_a = "module a {\n"
853 " namespace urn:tests:a;\n"
854 " prefix a;yang-version 1.1;\n"
aPiecekfcfec0f2021-04-23 12:47:30 +0200855 "\n"
856 " import ietf-restconf {\n"
857 " prefix rc;\n"
858 " revision-date 2017-01-26;\n"
859 " }\n"
860 "\n"
861 " rc:yang-data \"tmp\" {\n"
862 " container tmp_cont {\n"
863 " leaf lf {\n"
864 " type string;\n"
865 " }\n"
866 " }\n"
867 " }\n"
aPiecekbb96b802021-04-12 08:12:52 +0200868 " container cont {\n"
869 " notification contnotif;\n"
870 " leaf-list contx {\n"
871 " type string;\n"
872 " }\n"
873 " uses grp;\n"
874 " }\n"
875 " list l1 {\n"
876 " key \"l1a l1b\";\n"
877 " leaf l1a {\n"
878 " type string;\n"
879 " }\n"
880 " leaf l1b {\n"
881 " type string;\n"
882 " }\n"
883 " leaf l1c {\n"
884 " type string;\n"
885 " }\n"
886 " }\n"
887 " feature f1;\n"
888 " feature f2;\n"
889 " leaf foo1 {\n"
890 " type uint16;\n"
891 " if-feature f1;\n"
892 " }\n"
893 " leaf foo2 {\n"
894 " type uint16;\n"
895 " }\n"
896 " leaf foo3 {\n"
897 " type uint16;\n"
898 " if-feature f2;\n"
899 " }\n"
900 " leaf-list ll {\n"
901 " type string;\n"
902 " }\n"
903 " anydata any {\n"
904 " config false;\n"
905 " }\n"
906 " list l2 {\n"
907 " config false;\n"
908 " container l2c {\n"
909 " leaf l2cx {\n"
910 " type string;\n"
911 " }\n"
912 " }\n"
913 " }\n"
914 " choice ch {\n"
915 " case cas {\n"
916 " leaf casx {\n"
917 " type string;\n"
918 " }\n"
919 " }\n"
920 " }\n"
921 " rpc oper {\n"
922 " input {\n"
923 " leaf inparam {\n"
924 " type string;\n"
925 " }\n"
926 " }\n"
927 " output {\n"
928 " leaf outparam {\n"
929 " type int8;\n"
930 " }\n"
931 " }\n"
932 " }\n"
933 " notification n1;\n"
934 " grouping grp {\n"
935 " leaf grpleaf {\n"
936 " type uint16;\n"
937 " }\n"
938 " }\n"
939 " augment /cont {\n"
940 " leaf augleaf {\n"
941 " type uint16;\n"
942 " }\n"
943 " }\n"
944 " deviation /a:foo2 {\n"
945 " deviate not-supported;\n"
946 " }\n"
947 "}\n";
948
949 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200950 ly_ctx_destroy(UTEST_LYCTX);
aPiecekbb96b802021-04-12 08:12:52 +0200951 const char *feats[] = {"f1", NULL};
Radek Krejciddbc4812021-04-13 21:18:02 +0200952
aPiecekbb96b802021-04-12 08:12:52 +0200953 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_SET_PRIV_PARSED, &UTEST_LYCTX));
aPiecekfcfec0f2021-04-23 12:47:30 +0200954 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
955 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-restconf", "2017-01-26", NULL));
aPiecekbb96b802021-04-12 08:12:52 +0200956 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, feats, NULL);
957
958 print_message("[ ] create context\n");
959 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
960 iter = check;
961 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_is_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200962 check_ext_instance_priv_parsed_is_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200963
964 print_message("[ ] unset option\n");
965 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED));
966 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
967 iter = check;
968 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_not_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200969 check_ext_instance_priv_parsed_not_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200970
971 print_message("[ ] set option\n");
972 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED));
973 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
974 iter = check;
975 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_is_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200976 check_ext_instance_priv_parsed_is_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200977}
978
Michal Vasko01db7de2021-04-16 12:23:30 +0200979static void
980test_explicit_compile(void **state)
981{
982 uint32_t i;
Michal Vasko4de7d072021-07-09 09:13:18 +0200983 struct lys_module *mod;
Michal Vasko01db7de2021-04-16 12:23:30 +0200984 const char *schema_a = "module a {\n"
985 " namespace urn:tests:a;\n"
986 " prefix a;yang-version 1.1;\n"
987 " feature f1;\n"
988 " feature f2;\n"
989 " leaf foo1 {\n"
990 " type uint16;\n"
991 " if-feature f1;\n"
992 " }\n"
993 " leaf foo2 {\n"
994 " type uint16;\n"
995 " }\n"
996 " container cont {\n"
997 " leaf foo3 {\n"
998 " type string;\n"
999 " }\n"
1000 " }\n"
1001 "}\n";
1002 const char *schema_b = "module b {\n"
1003 " namespace urn:tests:b;\n"
1004 " prefix b;yang-version 1.1;\n"
1005 " import a {\n"
1006 " prefix a;\n"
1007 " }\n"
1008 " augment /a:cont {\n"
1009 " leaf augleaf {\n"
1010 " type uint16;\n"
1011 " }\n"
1012 " }\n"
1013 "}\n";
1014 const char *schema_c = "module c {\n"
1015 " namespace urn:tests:c;\n"
1016 " prefix c;yang-version 1.1;\n"
1017 " import a {\n"
1018 " prefix a;\n"
1019 " }\n"
1020 " deviation /a:foo2 {\n"
1021 " deviate not-supported;\n"
1022 " }\n"
1023 "}\n";
1024
1025 /* use own context with extra flags */
1026 ly_ctx_destroy(UTEST_LYCTX);
1027 const char *feats[] = {"f1", NULL};
1028
1029 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_EXPLICIT_COMPILE, &UTEST_LYCTX));
1030 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, &mod);
1031 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
1032 UTEST_ADD_MODULE(schema_c, LYS_IN_YANG, NULL, NULL);
1033 assert_int_equal(LY_SUCCESS, lys_set_implemented((struct lys_module *)mod, feats));
1034
Michal Vaskodd992582021-06-10 14:34:57 +02001035 /* none of the modules should be compiled */
Michal Vasko01db7de2021-04-16 12:23:30 +02001036 i = 0;
1037 while ((mod = ly_ctx_get_module_iter(UTEST_LYCTX, &i))) {
Michal Vaskodd992582021-06-10 14:34:57 +02001038 assert_null(mod->compiled);
Michal Vasko01db7de2021-04-16 12:23:30 +02001039 }
1040
1041 assert_int_equal(LY_SUCCESS, ly_ctx_compile(UTEST_LYCTX));
1042
1043 /* check internal modules */
1044 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "yang");
1045 assert_non_null(mod);
1046 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-datastores");
1047 assert_non_null(mod);
1048 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-yang-library");
1049 assert_non_null(mod);
1050
1051 /* check test modules */
1052 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "a");
1053 assert_non_null(mod);
1054 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "b");
1055 assert_non_null(mod);
1056 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "c");
1057 assert_non_null(mod);
1058}
1059
Radek Iša56ca9e42020-09-08 18:42:00 +02001060int
1061main(void)
1062{
1063 const struct CMUnitTest tests[] = {
1064 UTEST(test_searchdirs),
1065 UTEST(test_options),
1066 UTEST(test_models),
1067 UTEST(test_imports),
1068 UTEST(test_get_models),
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +02001069 UTEST(test_ylmem),
aPiecekbb96b802021-04-12 08:12:52 +02001070 UTEST(test_set_priv_parsed),
Michal Vasko01db7de2021-04-16 12:23:30 +02001071 UTEST(test_explicit_compile),
Radek Iša56ca9e42020-09-08 18:42:00 +02001072 };
1073
1074 return cmocka_run_group_tests(tests, NULL, NULL);
1075}