blob: 8fa8506fa3268325b274ad7665ee7270c78aace4 [file] [log] [blame]
Radek Iša56ca9e42020-09-08 18:42:00 +02001/*
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"
23#include "utests.h"
24
25static void
26test_searchdirs(void **state)
27{
28 const char * const *list;
29
30 /* invalid arguments */
31 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(NULL, NULL));
32 CHECK_LOG("Invalid argument ctx (ly_ctx_set_searchdir()).", NULL);
33 assert_null(ly_ctx_get_searchdirs(NULL));
34 CHECK_LOG("Invalid argument ctx (ly_ctx_get_searchdirs()).", NULL);
35 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(NULL, NULL));
36 CHECK_LOG("Invalid argument ctx (ly_ctx_unset_searchdir()).", NULL);
37
38 /* readable and executable, but not a directory */
39 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utest_context"));
40 CHECK_LOG_CTX("Given search directory \""TESTS_BIN "/utest_context\" is not a directory.", NULL);
41 /* not executable */
42 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(UTEST_LYCTX, __FILE__));
43 CHECK_LOG_CTX("Unable to fully access search directory \""__FILE__ "\" (Permission denied).", NULL);
44 /* not existing */
45 assert_int_equal(LY_EINVAL, ly_ctx_set_searchdir(UTEST_LYCTX, "/nonexistingfile"));
46 CHECK_LOG_CTX("Unable to use search directory \"/nonexistingfile\" (No such file or directory).", NULL);
47
48 /* ly_set_add() fails */
49 /* no change */
50 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, NULL));
51
52 /* correct path */
53 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
54 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
55 assert_string_equal(TESTS_BIN "/utests", UTEST_LYCTX->search_paths.objs[0]);
56
57 /* duplicated paths */
58 assert_int_equal(LY_EEXIST, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
59 assert_int_equal(1, UTEST_LYCTX->search_paths.count);
60 assert_string_equal(TESTS_BIN "/utests", UTEST_LYCTX->search_paths.objs[0]);
61
62 /* another paths - add 8 to fill the initial buffer of the searchpaths list */
63 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN "/CMakeFiles"));
64 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../src"));
65 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../CMakeModules"));
66 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC "/../doc"));
67 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_SRC));
68 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_BIN));
69 assert_int_equal(7, UTEST_LYCTX->search_paths.count);
70
71 /* get searchpaths */
72 list = ly_ctx_get_searchdirs(UTEST_LYCTX);
73 assert_non_null(list);
74 assert_string_equal(TESTS_BIN "/utests", list[0]);
75 assert_string_equal(TESTS_BIN "/CMakeFiles", list[1]);
76 assert_string_equal(TESTS_SRC, list[5]);
77 assert_string_equal(TESTS_BIN, list[6]);
78 assert_null(list[7]);
79
80 /* removing searchpaths */
81 /* nonexisting */
82 assert_int_equal(LY_EINVAL, ly_ctx_unset_searchdir(UTEST_LYCTX, "/nonexistingfile"));
83 CHECK_LOG_CTX("Invalid argument value (ly_ctx_unset_searchdir()).", NULL);
84 /* first */
85 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_BIN "/utests"));
86 assert_string_not_equal(TESTS_BIN "/utests", list[0]);
87 assert_int_equal(6, UTEST_LYCTX->search_paths.count);
88 /* middle */
89 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_SRC));
90 assert_int_equal(5, UTEST_LYCTX->search_paths.count);
91 /* last */
92 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, TESTS_BIN));
93 assert_int_equal(4, UTEST_LYCTX->search_paths.count);
94 /* all */
95 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, NULL));
96 assert_int_equal(0, UTEST_LYCTX->search_paths.count);
97
98 /* again - no change */
99 assert_int_equal(LY_SUCCESS, ly_ctx_unset_searchdir(UTEST_LYCTX, NULL));
100
101 /* cleanup */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200102 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200103
104 /* test searchdir list in ly_ctx_new() */
105 assert_int_equal(LY_EINVAL, ly_ctx_new("/nonexistingfile", 0, &UTEST_LYCTX));
106 CHECK_LOG("Unable to use search directory \"/nonexistingfile\" (No such file or directory).", NULL);
107 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_SRC ":"TESTS_BIN ":"TESTS_BIN ":"TESTS_SRC, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
108 assert_int_equal(2, UTEST_LYCTX->search_paths.count);
109 assert_string_equal(TESTS_SRC, UTEST_LYCTX->search_paths.objs[0]);
110 assert_string_equal(TESTS_BIN, UTEST_LYCTX->search_paths.objs[1]);
111}
112
113static void
114test_options(void **state)
115{
116 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200117 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200118
119 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0xffff, &UTEST_LYCTX));
120
121 /* invalid arguments */
122 assert_int_equal(0, ly_ctx_get_options(NULL));
123 CHECK_LOG("Invalid argument ctx (ly_ctx_get_options()).", NULL);
124
125 assert_int_equal(LY_EINVAL, ly_ctx_set_options(NULL, 0));
126 CHECK_LOG("Invalid argument ctx (ly_ctx_set_options()).", NULL);
127 assert_int_equal(LY_EINVAL, ly_ctx_unset_options(NULL, 0));
128 CHECK_LOG("Invalid argument ctx (ly_ctx_unset_options()).", NULL);
129
130 /* option not allowed to be changed */
131 assert_int_equal(LY_EINVAL, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_NO_YANGLIBRARY));
132 CHECK_LOG_CTX("Invalid argument option (ly_ctx_set_options()).", NULL);
133 assert_int_equal(LY_EINVAL, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_NO_YANGLIBRARY));
134 CHECK_LOG_CTX("Invalid argument option (ly_ctx_set_options()).", NULL);
135
136 /* unset */
137 /* LY_CTX_ALL_IMPLEMENTED */
138 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
139 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_ALL_IMPLEMENTED));
140 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
141
142 /* LY_CTX_REF_IMPLEMENTED */
143 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
144 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED));
145 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
146
147 /* LY_CTX_DISABLE_SEARCHDIRS */
148 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
149 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIRS));
150 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
151
152 /* LY_CTX_DISABLE_SEARCHDIR_CWD */
153 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
154 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIR_CWD));
155 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
156
157 /* LY_CTX_PREFER_SEARCHDIRS */
158 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
159 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_PREFER_SEARCHDIRS));
160 assert_int_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
161
162 assert_int_equal(UTEST_LYCTX->flags, ly_ctx_get_options(UTEST_LYCTX));
163
164 /* set back */
165 /* LY_CTX_ALL_IMPLEMENTED */
166 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_ALL_IMPLEMENTED));
167 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_ALL_IMPLEMENTED);
168
169 /* LY_CTX_REF_IMPLEMENTED */
170 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_REF_IMPLEMENTED));
171 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_REF_IMPLEMENTED);
172
173 /* LY_CTX_DISABLE_SEARCHDIRS */
174 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIRS));
175 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIRS);
176
177 /* LY_CTX_DISABLE_SEARCHDIR_CWD */
178 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_DISABLE_SEARCHDIR_CWD));
179 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_DISABLE_SEARCHDIR_CWD);
180
181 /* LY_CTX_PREFER_SEARCHDIRS */
182 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_PREFER_SEARCHDIRS));
183 assert_int_not_equal(0, UTEST_LYCTX->flags & LY_CTX_PREFER_SEARCHDIRS);
184
185 assert_int_equal(UTEST_LYCTX->flags, ly_ctx_get_options(UTEST_LYCTX));
186}
187
188static LY_ERR
189test_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const char *UNUSED(submod_name),
190 const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format,
191 const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
192{
193 *module_data = user_data;
194 *format = LYS_IN_YANG;
195 *free_module_data = NULL;
196 return LY_SUCCESS;
197}
198
199static void
200test_models(void **state)
201{
202 struct ly_in *in;
203 const char *str;
204 struct lys_module *mod1, *mod2;
205 struct lys_glob_unres unres = {0};
206
207 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200208 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200209
210 /* invalid arguments */
Michal Vasko794ab4b2021-03-31 09:42:19 +0200211 assert_int_equal(0, ly_ctx_get_change_count(NULL));
212 CHECK_LOG("Invalid argument ctx (ly_ctx_get_change_count()).", NULL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200213
214 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &UTEST_LYCTX));
Michal Vasko794ab4b2021-03-31 09:42:19 +0200215 assert_int_equal(UTEST_LYCTX->change_count, ly_ctx_get_change_count(UTEST_LYCTX));
Radek Iša56ca9e42020-09-08 18:42:00 +0200216
217 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module x {namespace urn:x;prefix x;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200218 assert_int_equal(LY_EINVAL, lys_parse_in(UTEST_LYCTX, in, 4, NULL, NULL, &unres.creating, &mod1));
Michal Vaskof4258e12021-06-15 12:11:42 +0200219 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200220 ly_in_free(in, 0);
221 CHECK_LOG_CTX("Invalid schema input format.", NULL);
222
223 /* import callback */
224 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)(str = "test"));
225 assert_ptr_equal(test_imp_clb, UTEST_LYCTX->imp_clb);
226 assert_ptr_equal(str, UTEST_LYCTX->imp_clb_data);
227 assert_ptr_equal(test_imp_clb, ly_ctx_get_module_imp_clb(UTEST_LYCTX, (void **)&str));
228 assert_string_equal("test", str);
229
230 ly_ctx_set_module_imp_clb(UTEST_LYCTX, NULL, NULL);
231 assert_null(UTEST_LYCTX->imp_clb);
232 assert_null(UTEST_LYCTX->imp_clb_data);
233
234 /* name collision of module and submodule */
235 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-30;}");
236 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 +0200237 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 +0200238 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200239 ly_in_free(in, 0);
Radek Krejci8297b792020-08-16 14:49:05 +0200240 CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL,
241 "Name collision between module and submodule of name \"y\".", "Line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200242
243 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 +0200244 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 +0200245 ly_in_free(in, 0);
246 assert_int_equal(LY_SUCCESS, ly_in_new_memory("module y {namespace urn:y;prefix y;}", &in));
Michal Vaskodd992582021-06-10 14:34:57 +0200247 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 +0200248 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200249 ly_in_free(in, 0);
Radek Krejci8297b792020-08-16 14:49:05 +0200250 CHECK_LOG_CTX("Parsing module \"y\" failed.", NULL,
251 "Name collision between module and submodule of name \"y\".", "Line number 1.");
Radek Iša56ca9e42020-09-08 18:42:00 +0200252
253 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to b {prefix b;}}");
254 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 +0200255 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 +0200256 lys_unres_glob_revert(UTEST_LYCTX, &unres);
257 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200258 ly_in_free(in, 0);
Radek Krejci8297b792020-08-16 14:49:05 +0200259 CHECK_LOG_CTX("Parsing module \"b\" failed.", NULL,
260 "Including \"y\" submodule into \"b\" failed.", NULL,
261 "Parsing submodule failed.", NULL,
Radek Iša56ca9e42020-09-08 18:42:00 +0200262 "Name collision between submodules of name \"y\".", "Line number 1.");
263
264 /* selecting correct revision of the submodules */
265 ly_ctx_reset_latests(UTEST_LYCTX);
266 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule y {belongs-to a {prefix a;} revision 2018-10-31;}");
267 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 +0200268 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 +0200269 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 ly_in_free(in, 0);
271 assert_string_equal("2018-10-31", mod2->parsed->includes[0].submodule->revs[0].date);
272
273 /* reloading module in case only the compiled module resists in the context */
274 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 +0200275 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod1));
Radek Iša56ca9e42020-09-08 18:42:00 +0200276 ly_in_free(in, 0);
Radek Iša56ca9e42020-09-08 18:42:00 +0200277 assert_non_null(mod1->compiled);
278 assert_non_null(mod1->parsed);
279
280#if 0
281 /* TODO in case we are able to remove the parsed schema, here we will test how it will handle missing import parsed schema */
282
283 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));
284 /* mod1->parsed is necessary to compile mod2 because of possible groupings, typedefs, ... */
285 ly_ctx_set_module_imp_clb(UTEST_LYCTX, NULL, NULL);
286 assert_int_equal(LY_ENOTFOUND, lys_create_module(UTEST_LYCTX, in, LYS_IN_YANG, 1, NULL, NULL, &mod2));
287 /*logbuf_assert("Unable to reload \"w\" module to import it into \"z\", source data not found.");*/
288 CHECK_LOG_CTX("Recompilation of module \"w\" failed.", NULL);
289 assert_null(mod2);
290 ly_in_free(in, 0);
291#endif
292
293 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));
294 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 +0200295 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in, LYS_IN_YANG, NULL, &mod2));
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 ly_in_free(in, 0);
297 assert_non_null(mod2);
298 assert_non_null(mod1->parsed);
299 assert_string_equal("w", mod1->name);
300}
301
302static void
303test_imports(void **state)
304{
aPiecekd4911ee2021-07-30 07:40:24 +0200305 struct lys_module *mod1, *mod2, *mod3, *import;
aPiecek9f8c7e72021-07-28 12:01:56 +0200306 char *str;
aPiecekd4911ee2021-07-30 07:40:24 +0200307 uint16_t ctx_options;
Radek Iša56ca9e42020-09-08 18:42:00 +0200308
309 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200310 ly_ctx_destroy(UTEST_LYCTX);
aPiecekd4911ee2021-07-30 07:40:24 +0200311 ctx_options = LY_CTX_DISABLE_SEARCHDIRS | LY_CTX_NO_YANGLIBRARY;
Radek Iša56ca9e42020-09-08 18:42:00 +0200312
aPiecekd4911ee2021-07-30 07:40:24 +0200313 /* Import callback provides newer revision of module 'a',
314 * however the older revision is implemented soon and therefore it is preferred. */
315 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
Radek Iša56ca9e42020-09-08 18:42:00 +0200316 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "module a {namespace urn:a; prefix a; revision 2019-09-17;}");
317 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-16;}",
318 LYS_IN_YANG, &mod1));
aPiecek8ca21bd2021-07-26 14:31:01 +0200319 assert_true(LYS_MOD_LATEST_REV & mod1->latest_revision);
Radek Iša56ca9e42020-09-08 18:42:00 +0200320 assert_int_equal(1, mod1->implemented);
321 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
322 LYS_IN_YANG, &mod2));
aPiecekd4911ee2021-07-30 07:40:24 +0200323 assert_ptr_equal(mod1, mod2->parsed->imports[0].module);
324 assert_true((LYS_MOD_LATEST_REV | LYS_MOD_IMPORTED_REV) & mod1->latest_revision);
325 assert_string_equal("2019-09-16", mod1->revision);
326 assert_int_equal(1, mod1->implemented);
Radek Iša56ca9e42020-09-08 18:42:00 +0200327 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200328 ly_ctx_destroy(UTEST_LYCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200329
aPiecekd4911ee2021-07-30 07:40:24 +0200330 /* Import callback provides older revision of module 'a' and it is
331 * imported by another module, so it is preferred even if newer
332 * revision is implemented later. */
333 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
334 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 +0200335 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module b {namespace urn:b;prefix b;import a {prefix a;}}",
336 LYS_IN_YANG, &mod2));
aPiecekd4911ee2021-07-30 07:40:24 +0200337 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {namespace urn:a;prefix a;revision 2019-09-17;}",
338 LYS_IN_YANG, &mod1));
339 ly_log_level(LY_LLVRB);
340 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module c {namespace urn:c;prefix c;import a {prefix a;}}",
341 LYS_IN_YANG, &mod3));
342 CHECK_LOG("Implemented module \"a@2019-09-17\" is not used for import, revision \"2019-09-16\" is imported instead.", NULL);
343 ly_log_level(LY_LLWRN);
344 assert_true(LYS_MOD_LATEST_SEARCHDIRS & mod1->latest_revision);
345 assert_int_equal(1, mod1->implemented);
Radek Iša56ca9e42020-09-08 18:42:00 +0200346 import = mod2->parsed->imports[0].module;
aPiecekd4911ee2021-07-30 07:40:24 +0200347 assert_true(LYS_MOD_IMPORTED_REV & import->latest_revision);
348 assert_string_equal("2019-09-16", import->revision);
349 assert_int_equal(0, import->implemented);
350 import = mod3->parsed->imports[0].module;
351 assert_string_equal("2019-09-16", import->revision);
352 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-16"));
353 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "a", "2019-09-17"));
354 assert_string_equal("2019-09-17", ly_ctx_get_module_implemented(UTEST_LYCTX, "a")->revision);
aPiecek9f8c7e72021-07-28 12:01:56 +0200355 ly_ctx_destroy(UTEST_LYCTX);
356
357 /* check of circular dependency */
aPiecekd4911ee2021-07-30 07:40:24 +0200358 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, ctx_options, &UTEST_LYCTX));
aPiecek9f8c7e72021-07-28 12:01:56 +0200359 str = "module a {namespace urn:a; prefix a;"
360 "import b {prefix b;}"
361 "}";
362 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, str);
363 str = "module b { yang-version 1.1; namespace urn:b; prefix b;"
364 "import a {prefix a;}"
365 "}";
366 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Iša56ca9e42020-09-08 18:42:00 +0200367}
368
369static void
370test_get_models(void **state)
371{
372 struct lys_module *mod, *mod2;
373 const char *str0 = "module a {namespace urn:a;prefix a;}";
374 const char *str1 = "module a {namespace urn:a;prefix a;revision 2018-10-23;}";
375 const char *str2 = "module a {namespace urn:a;prefix a;revision 2018-10-23;revision 2018-10-24;}";
376 struct ly_in *in0, *in1, *in2;
377 struct lys_glob_unres unres = {0};
378
379 unsigned int index = 0;
380 const char *names[] = {"ietf-yang-metadata", "yang", "ietf-inet-types", "ietf-yang-types", "ietf-datastores", "ietf-yang-library", "a", "a", "a"};
381
382 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str0, &in0));
383 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
384 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str2, &in2));
385
386 /* invalid arguments */
387 assert_ptr_equal(NULL, ly_ctx_get_module(NULL, NULL, NULL));
388 CHECK_LOG("Invalid argument ctx (ly_ctx_get_module()).", NULL);
389 assert_ptr_equal(NULL, ly_ctx_get_module(UTEST_LYCTX, NULL, NULL));
390 CHECK_LOG_CTX("Invalid argument name (ly_ctx_get_module()).", NULL);
391 assert_ptr_equal(NULL, ly_ctx_get_module_ns(NULL, NULL, NULL));
392 CHECK_LOG("Invalid argument ctx (ly_ctx_get_module_ns()).", NULL);
393 assert_ptr_equal(NULL, ly_ctx_get_module_ns(UTEST_LYCTX, NULL, NULL));
394 CHECK_LOG_CTX("Invalid argument ns (ly_ctx_get_module_ns()).", NULL);
395 assert_null(ly_ctx_get_module(UTEST_LYCTX, "nonsence", NULL));
396
397 /* internal modules */
398 assert_null(ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-yang-types"));
399 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "yang");
400 assert_non_null(mod);
401 assert_non_null(mod->parsed);
402 assert_string_equal("yang", mod->name);
403 mod2 = ly_ctx_get_module_implemented_ns(UTEST_LYCTX, mod->ns);
404 assert_ptr_equal(mod, mod2);
405 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-yang-metadata", "2016-08-05"));
406 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-yang-types", "2013-07-15"));
407 assert_non_null(ly_ctx_get_module(UTEST_LYCTX, "ietf-inet-types", "2013-07-15"));
408 assert_non_null(ly_ctx_get_module_ns(UTEST_LYCTX, "urn:ietf:params:xml:ns:yang:ietf-datastores", "2018-02-14"));
409
410 /* select module by revision */
Michal Vasko4de7d072021-07-09 09:13:18 +0200411 assert_int_equal(LY_SUCCESS, lys_parse(UTEST_LYCTX, in1, LYS_IN_YANG, NULL, &mod));
Radek Iša56ca9e42020-09-08 18:42:00 +0200412 /* invalid attempts - implementing module of the same name and inserting the same module */
Michal Vaskodd992582021-06-10 14:34:57 +0200413 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 +0200414 assert_int_equal(LY_EDENIED, lys_implement(mod2, NULL, &unres));
415 CHECK_LOG_CTX("Module \"a@2018-10-24\" is present in the context in other implemented revision (2018-10-23).", NULL);
Michal Vaskof4258e12021-06-15 12:11:42 +0200416 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200417 ly_in_reset(in1);
418 /* it is already there, fine */
Michal Vaskodd992582021-06-10 14:34:57 +0200419 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 +0200420 /* insert the second module only as imported, not implemented */
Michal Vaskof4258e12021-06-15 12:11:42 +0200421 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200422 ly_in_reset(in2);
Michal Vaskodd992582021-06-10 14:34:57 +0200423 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 +0200424 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200425 assert_non_null(mod2);
426 assert_ptr_not_equal(mod, mod2);
427 mod = ly_ctx_get_module_latest(UTEST_LYCTX, "a");
428 assert_ptr_equal(mod, mod2);
429 mod2 = ly_ctx_get_module_latest_ns(UTEST_LYCTX, mod->ns);
430 assert_ptr_equal(mod, mod2);
431 /* work with module with no revision */
Michal Vaskodd992582021-06-10 14:34:57 +0200432 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 +0200433 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200434 assert_ptr_equal(mod, ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
435 assert_ptr_not_equal(mod, ly_ctx_get_module_latest(UTEST_LYCTX, "a"));
436
437 str1 = "submodule b {belongs-to a {prefix a;}}";
438 ly_in_free(in1, 0);
439 assert_int_equal(LY_SUCCESS, ly_in_new_memory(str1, &in1));
Michal Vaskodd992582021-06-10 14:34:57 +0200440 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 +0200441 CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL);
Michal Vaskof4258e12021-06-15 12:11:42 +0200442 lys_unres_glob_erase(&unres);
Radek Iša56ca9e42020-09-08 18:42:00 +0200443
444 while ((mod = (struct lys_module *)ly_ctx_get_module_iter(UTEST_LYCTX, &index))) {
445 assert_string_equal(names[index - 1], mod->name);
446 }
447 assert_int_equal(9, index);
448
449 /* cleanup */
450 ly_in_free(in0, 0);
451 ly_in_free(in1, 0);
452 ly_in_free(in2, 0);
453}
454
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200455static void
456test_ylmem(void **state)
457{
458#define DATA_YANG_LIBRARY_START "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"\
459 " <module-set>\n"\
460 " <name>complete</name>\n"\
461 " <module>\n"\
462 " <name>yang</name>\n"\
463 " <revision>2021-04-07</revision>\n"\
464 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"\
465 " </module>\n"\
466 " <module>\n"\
467 " <name>ietf-yang-library</name>\n"\
468 " <revision>2019-01-04</revision>\n"\
469 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"\
470 " </module>\n"
471
472#define DATA_YANG_BASE_IMPORTS " <import-only-module>\n"\
473 " <name>ietf-yang-metadata</name>\n"\
474 " <revision>2016-08-05</revision>\n"\
475 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"\
476 " </import-only-module>\n"\
477 " <import-only-module>\n"\
478 " <name>ietf-inet-types</name>\n"\
479 " <revision>2013-07-15</revision>\n"\
480 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"\
481 " </import-only-module>\n"\
482 " <import-only-module>\n"\
483 " <name>ietf-yang-types</name>\n"\
484 " <revision>2013-07-15</revision>\n"\
485 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"\
486 " </import-only-module>\n"\
487 " <import-only-module>\n"\
488 " <name>ietf-datastores</name>\n"\
489 " <revision>2018-02-14</revision>\n"\
490 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"\
491 " </import-only-module>\n"
492
493#define DATA_YANG_SCHEMA_MODULE_STATE " </module-set>\n"\
494 " <schema>\n"\
495 " <name>complete</name>\n"\
496 " <module-set>complete</module-set>\n"\
497 " </schema>\n"\
498 " <content-id>9</content-id>\n"\
499 "</yang-library>\n"\
500 "<modules-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"\
501 " <module-set-id>12</module-set-id>\n"\
502 " <module>\n"\
503 " <name>ietf-yang-metadata</name>\n"\
504 " <revision>2016-08-05</revision>\n"\
505 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"\
506 " <conformance-type>import</conformance-type>\n"\
507 " </module>\n"\
508 " <module>\n"\
509 " <name>yang</name>\n"\
510 " <revision>2020-06-17</revision>\n"\
511 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"\
512 " <conformance-type>implement</conformance-type>\n"\
513 " </module>\n"\
514 " <module>\n"\
515 " <name>ietf-inet-types</name>\n"\
516 " <revision>2013-07-15</revision>\n"\
517 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"\
518 " <conformance-type>import</conformance-type>\n"\
519 " </module>\n"\
520 " <module>\n"\
521 " <name>ietf-yang-types</name>\n"\
522 " <revision>2013-07-15</revision>\n"\
523 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"\
524 " <conformance-type>import</conformance-type>\n"\
525 " </module>\n"\
526 " <module>\n"\
527 " <name>ietf-yang-library</name>\n"\
528 " <revision>2019-01-04</revision>\n"\
529 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"\
530 " <conformance-type>implement</conformance-type>\n"\
531 " </module>\n"\
532 " <module>\n"\
533 " <name>ietf-datastores</name>\n"\
534 " <revision>2018-02-14</revision>\n"\
535 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"\
536 " <conformance-type>import</conformance-type>\n"\
537 " </module>\n"
538
539 const char *yanglibrary_only =
540 DATA_YANG_LIBRARY_START
541 DATA_YANG_BASE_IMPORTS
542 DATA_YANG_SCHEMA_MODULE_STATE
543 "</modules-state>\n";
544
545 const char *with_netconf =
546 DATA_YANG_LIBRARY_START
547 " <module>\n"
548 " <name>ietf-netconf</name>\n"
549 " <revision>2011-06-01</revision>\n"
550 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
551 " </module>\n"
552 DATA_YANG_BASE_IMPORTS
553 " <import-only-module>\n"
554 " <name>ietf-netconf-acm</name>\n"
555 " <revision>2018-02-14</revision>\n"
556 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
557 " </import-only-module>\n"
558 DATA_YANG_SCHEMA_MODULE_STATE
559 " <module>\n"
560 " <name>ietf-netconf</name>\n"
561 " <revision>2011-06-01</revision>\n"
562 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
563 " <conformance-type>implement</conformance-type>\n"
564 " </module>\n"
565 " <module>\n"
566 " <name>ietf-netconf-acm</name>\n"
567 " <revision>2018-02-14</revision>\n"
568 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
569 " <conformance-type>import</conformance-type>\n"
570 " </module>\n"
571 "</modules-state>";
572
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200573 char *with_netconf_features = malloc(8096);
574 strcpy(with_netconf_features,
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200575 DATA_YANG_LIBRARY_START
576 " <module>\n"
577 " <name>ietf-netconf</name>\n"
578 " <revision>2011-06-01</revision>\n"
579 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
580 " <feature>writable-running</feature>\n"
581 " <feature>candidate</feature>\n"
582 " <feature>confirmed-commit</feature>\n"
583 " <feature>rollback-on-error</feature>\n"
584 " <feature>validate</feature>\n"
585 " <feature>startup</feature>\n"
586 " <feature>url</feature>\n"
587 " <feature>xpath</feature>\n"
588 " </module>\n"
589 " <import-only-module>\n"
590 " <name>ietf-yang-metadata</name>\n"
591 " <revision>2016-08-05</revision>\n"
592 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-metadata</namespace>\n"
593 " </import-only-module>\n"
594 " <import-only-module>\n"
595 " <name>ietf-inet-types</name>\n"
596 " <revision>2013-07-15</revision>\n"
597 " <namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</namespace>\n"
598 " </import-only-module>\n"
599 " <import-only-module>\n"
600 " <name>ietf-yang-types</name>\n"
601 " <revision>2013-07-15</revision>\n"
602 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</namespace>\n"
603 " </import-only-module>\n"
604 " <import-only-module>\n"
605 " <name>ietf-datastores</name>\n"
606 " <revision>2018-02-14</revision>\n"
607 " <namespace>urn:ietf:params:xml:ns:yang:ietf-datastores</namespace>\n"
608 " </import-only-module>\n"
609 " <import-only-module>\n"
610 " <name>ietf-netconf-acm</name>\n"
611 " <revision>2018-02-14</revision>\n"
612 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200613 " </import-only-module>\n");
614 strcpy(with_netconf_features + strlen(with_netconf_features),
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200615 DATA_YANG_SCHEMA_MODULE_STATE
616 " <module>\n"
617 " <name>ietf-netconf</name>\n"
618 " <revision>2011-06-01</revision>\n"
619 " <namespace>urn:ietf:params:xml:ns:netconf:base:1.0</namespace>\n"
620 " <feature>writable-running</feature>\n"
621 " <feature>candidate</feature>\n"
622 " <feature>confirmed-commit</feature>\n"
623 " <feature>rollback-on-error</feature>\n"
624 " <feature>validate</feature>\n"
625 " <feature>startup</feature>\n"
626 " <feature>url</feature>\n"
627 " <feature>xpath</feature>\n"
628 " <conformance-type>implement</conformance-type>\n"
629 " </module>\n"
630 " <module>\n"
631 " <name>ietf-netconf-acm</name>\n"
632 " <revision>2018-02-14</revision>\n"
633 " <namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-acm</namespace>\n"
634 " <conformance-type>import</conformance-type>\n"
635 " </module>\n"
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200636 "</modules-state>");
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200637
638 const char *garbage_revision =
639 "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
640 " <module-set>\n"
641 " <name>complete</name>\n"
642 " <module>\n"
643 " <name>yang</name>\n"
644 " <revision>2020-06-17</revision>\n"
645 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
646 " </module>\n"
647 " <module>\n"
648 " <name>ietf-yang-library</name>\n"
649 " <revision>2019-01-01</revision>\n"
650 " <namespace>urn:ietf:params:xml:ns:yang:ietf-yang-library</namespace>\n"
651 " </module>\n"
652 DATA_YANG_BASE_IMPORTS
653 DATA_YANG_SCHEMA_MODULE_STATE
654 "</modules-state>\n";
655
656 const char *no_yanglibrary =
657 "<yang-library xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-library\">\n"
658 " <module-set>\n"
659 " <name>complete</name>\n"
660 " <module>\n"
661 " <name>yang</name>\n"
662 " <revision>2021-04-07</revision>\n"
663 " <namespace>urn:ietf:params:xml:ns:yang:1</namespace>\n"
664 " </module>\n"
665 DATA_YANG_BASE_IMPORTS
666 DATA_YANG_SCHEMA_MODULE_STATE
667 "</modules-state>\n";
668
669 (void) state;
670 /* seperate context to avoid double free during teadown */
671 struct ly_ctx *ctx_test = NULL;
672
673 /* test invalid parameters */
674 assert_int_equal(LY_EINVAL, ly_ctx_new_ylpath(NULL, NULL, LYD_XML, 0, &ctx_test));
675 assert_int_equal(LY_EINVAL, ly_ctx_new_ylpath(NULL, TESTS_SRC, LYD_XML, 0, NULL));
676 assert_int_equal(LY_ESYS, ly_ctx_new_ylpath(NULL, TESTS_SRC "garbage", LYD_XML, 0, &ctx_test));
677
678 /* basic test with ietf-yang-library-only */
679 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 +0200680 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-yang-library", "2019-01-04"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200681 assert_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200682 ly_ctx_destroy(ctx_test);
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200683
684 /* test loading module, should also import other module */
685 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 +0200686 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200687 assert_int_equal(1, ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01")->implemented);
Michal Vaskoad8d0f52021-04-26 13:21:24 +0200688 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200689 assert_int_equal(0, ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14")->implemented);
690 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 +0200691 ly_ctx_destroy(ctx_test);
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200692
693 /* test loading module with feature if they are present */
694 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 +0200695 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf", "2011-06-01"));
696 assert_non_null(ly_ctx_get_module(ctx_test, "ietf-netconf-acm", "2018-02-14"));
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200697 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 +0200698 ly_ctx_destroy(ctx_test);
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200699
700 /* test with not matching revision */
701 assert_int_equal(LY_EINVAL, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", garbage_revision, LYD_XML, 0, &ctx_test));
702
703 /* test data containing ietf-yang-library which conflicts with the option */
704 assert_int_equal(LY_EINVAL, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", with_netconf_features, LYD_XML, LY_CTX_NO_YANGLIBRARY, &ctx_test));
705
706 /* test creating without ietf-yang-library */
707 assert_int_equal(LY_SUCCESS, ly_ctx_new_ylmem(TESTS_SRC "/modules/yang/", no_yanglibrary, LYD_XML, LY_CTX_NO_YANGLIBRARY, &ctx_test));
708 assert_int_equal(NULL, ly_ctx_get_module(ctx_test, "ietf-yang-library", "2019-01-04"));
Radek Krejci90ed21e2021-04-12 14:47:46 +0200709 ly_ctx_destroy(ctx_test);
Michal Vasko22e0f3a2021-09-22 12:19:23 +0200710 free(with_netconf_features);
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +0200711}
712
aPiecekbb96b802021-04-12 08:12:52 +0200713static LY_ERR
714check_node_priv_parsed_is_set(struct lysc_node *node, void *data, ly_bool *UNUSED(dfs_continue))
715{
716 const struct lysp_node *pnode;
717 const char ***iter;
718
719 pnode = (const struct lysp_node *)node->priv;
720 CHECK_POINTER(pnode, 1);
721 iter = (const char ***)data;
722 CHECK_POINTER(**iter, 1);
723 CHECK_STRING(pnode->name, **iter);
724 (*iter)++;
725
726 return LY_SUCCESS;
727}
728
729static LY_ERR
730check_node_priv_parsed_not_set(struct lysc_node *node, void *UNUSED(data), ly_bool *UNUSED(dfs_continue))
731{
732 CHECK_POINTER(node->priv, 0);
733 return LY_SUCCESS;
734}
735
aPiecekfcfec0f2021-04-23 12:47:30 +0200736static void
737check_ext_instance_priv_parsed_is_set(struct lysc_ext_instance *ext)
738{
739 LY_ARRAY_COUNT_TYPE u, v;
740 struct lysc_ext_substmt *substmts;
741 struct lysc_node *cnode;
742 const char **iter;
743 const char *check[] = {
744 "tmp_cont", "lf", NULL
745 };
746
747 LY_ARRAY_FOR(ext, u) {
748 substmts = ext[u].substmts;
749 LY_ARRAY_FOR(substmts, v) {
750 if (substmts && substmts[v].storage && LY_STMT_IS_NODE(substmts[v].stmt)) {
751 cnode = *(struct lysc_node **)substmts[v].storage;
752 iter = check;
753 assert_int_equal(LY_SUCCESS, lysc_tree_dfs_full(cnode, check_node_priv_parsed_is_set, &iter));
754 }
755 }
756 }
757}
758
759static void
760check_ext_instance_priv_parsed_not_set(struct lysc_ext_instance *ext)
761{
762 LY_ARRAY_COUNT_TYPE u, v;
763 struct lysc_ext_substmt *substmts;
764 struct lysc_node *cnode;
765
766 LY_ARRAY_FOR(ext, u) {
767 substmts = ext[u].substmts;
768 LY_ARRAY_FOR(substmts, v) {
769 if (substmts && substmts[v].storage && LY_STMT_IS_NODE(substmts[v].stmt)) {
770 cnode = *(struct lysc_node **)substmts[v].storage;
771 if (cnode) {
772 CHECK_POINTER((struct lysp_node *)cnode->priv, 0);
773 }
774 }
775 }
776 }
777}
778
aPiecekbb96b802021-04-12 08:12:52 +0200779/**
780 * @brief Testing of LY_CTX_SET_PRIV_PARSED.
781 */
782static void
783test_set_priv_parsed(void **state)
784{
Michal Vasko4de7d072021-07-09 09:13:18 +0200785 struct lys_module *mod;
aPiecekbb96b802021-04-12 08:12:52 +0200786 const char *schema_a;
787 const char **iter;
788 const char *check[] = {
789 "cont", "contnotif", "augleaf", "contx", "grpleaf", "l1",
790 "l1a", "l1b", "l1c", "foo1", "ll", "any", "l2",
791 "l2c", "l2cx", "ch", "cas", "casx", "oper",
792 "input", "inparam", "output", "outparam", "n1", NULL
793 };
794
795 /* each node must have a unique name. */
796 schema_a = "module a {\n"
797 " namespace urn:tests:a;\n"
798 " prefix a;yang-version 1.1;\n"
aPiecekfcfec0f2021-04-23 12:47:30 +0200799 "\n"
800 " import ietf-restconf {\n"
801 " prefix rc;\n"
802 " revision-date 2017-01-26;\n"
803 " }\n"
804 "\n"
805 " rc:yang-data \"tmp\" {\n"
806 " container tmp_cont {\n"
807 " leaf lf {\n"
808 " type string;\n"
809 " }\n"
810 " }\n"
811 " }\n"
aPiecekbb96b802021-04-12 08:12:52 +0200812 " container cont {\n"
813 " notification contnotif;\n"
814 " leaf-list contx {\n"
815 " type string;\n"
816 " }\n"
817 " uses grp;\n"
818 " }\n"
819 " list l1 {\n"
820 " key \"l1a l1b\";\n"
821 " leaf l1a {\n"
822 " type string;\n"
823 " }\n"
824 " leaf l1b {\n"
825 " type string;\n"
826 " }\n"
827 " leaf l1c {\n"
828 " type string;\n"
829 " }\n"
830 " }\n"
831 " feature f1;\n"
832 " feature f2;\n"
833 " leaf foo1 {\n"
834 " type uint16;\n"
835 " if-feature f1;\n"
836 " }\n"
837 " leaf foo2 {\n"
838 " type uint16;\n"
839 " }\n"
840 " leaf foo3 {\n"
841 " type uint16;\n"
842 " if-feature f2;\n"
843 " }\n"
844 " leaf-list ll {\n"
845 " type string;\n"
846 " }\n"
847 " anydata any {\n"
848 " config false;\n"
849 " }\n"
850 " list l2 {\n"
851 " config false;\n"
852 " container l2c {\n"
853 " leaf l2cx {\n"
854 " type string;\n"
855 " }\n"
856 " }\n"
857 " }\n"
858 " choice ch {\n"
859 " case cas {\n"
860 " leaf casx {\n"
861 " type string;\n"
862 " }\n"
863 " }\n"
864 " }\n"
865 " rpc oper {\n"
866 " input {\n"
867 " leaf inparam {\n"
868 " type string;\n"
869 " }\n"
870 " }\n"
871 " output {\n"
872 " leaf outparam {\n"
873 " type int8;\n"
874 " }\n"
875 " }\n"
876 " }\n"
877 " notification n1;\n"
878 " grouping grp {\n"
879 " leaf grpleaf {\n"
880 " type uint16;\n"
881 " }\n"
882 " }\n"
883 " augment /cont {\n"
884 " leaf augleaf {\n"
885 " type uint16;\n"
886 " }\n"
887 " }\n"
888 " deviation /a:foo2 {\n"
889 " deviate not-supported;\n"
890 " }\n"
891 "}\n";
892
893 /* use own context with extra flags */
Radek Krejci90ed21e2021-04-12 14:47:46 +0200894 ly_ctx_destroy(UTEST_LYCTX);
aPiecekbb96b802021-04-12 08:12:52 +0200895 const char *feats[] = {"f1", NULL};
Radek Krejciddbc4812021-04-13 21:18:02 +0200896
aPiecekbb96b802021-04-12 08:12:52 +0200897 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_SET_PRIV_PARSED, &UTEST_LYCTX));
aPiecekfcfec0f2021-04-23 12:47:30 +0200898 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
899 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-restconf", "2017-01-26", NULL));
aPiecekbb96b802021-04-12 08:12:52 +0200900 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, feats, NULL);
901
902 print_message("[ ] create context\n");
903 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
904 iter = check;
905 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_is_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200906 check_ext_instance_priv_parsed_is_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200907
908 print_message("[ ] unset option\n");
909 assert_int_equal(LY_SUCCESS, ly_ctx_unset_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED));
910 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
911 iter = check;
912 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_not_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200913 check_ext_instance_priv_parsed_not_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200914
915 print_message("[ ] set option\n");
916 assert_int_equal(LY_SUCCESS, ly_ctx_set_options(UTEST_LYCTX, LY_CTX_SET_PRIV_PARSED));
917 mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL);
918 iter = check;
919 assert_int_equal(LY_SUCCESS, lysc_module_dfs_full(mod, check_node_priv_parsed_is_set, &iter));
aPiecekfcfec0f2021-04-23 12:47:30 +0200920 check_ext_instance_priv_parsed_is_set(mod->compiled->exts);
aPiecekbb96b802021-04-12 08:12:52 +0200921}
922
Michal Vasko01db7de2021-04-16 12:23:30 +0200923static void
924test_explicit_compile(void **state)
925{
926 uint32_t i;
Michal Vasko4de7d072021-07-09 09:13:18 +0200927 struct lys_module *mod;
Michal Vasko01db7de2021-04-16 12:23:30 +0200928 const char *schema_a = "module a {\n"
929 " namespace urn:tests:a;\n"
930 " prefix a;yang-version 1.1;\n"
931 " feature f1;\n"
932 " feature f2;\n"
933 " leaf foo1 {\n"
934 " type uint16;\n"
935 " if-feature f1;\n"
936 " }\n"
937 " leaf foo2 {\n"
938 " type uint16;\n"
939 " }\n"
940 " container cont {\n"
941 " leaf foo3 {\n"
942 " type string;\n"
943 " }\n"
944 " }\n"
945 "}\n";
946 const char *schema_b = "module b {\n"
947 " namespace urn:tests:b;\n"
948 " prefix b;yang-version 1.1;\n"
949 " import a {\n"
950 " prefix a;\n"
951 " }\n"
952 " augment /a:cont {\n"
953 " leaf augleaf {\n"
954 " type uint16;\n"
955 " }\n"
956 " }\n"
957 "}\n";
958 const char *schema_c = "module c {\n"
959 " namespace urn:tests:c;\n"
960 " prefix c;yang-version 1.1;\n"
961 " import a {\n"
962 " prefix a;\n"
963 " }\n"
964 " deviation /a:foo2 {\n"
965 " deviate not-supported;\n"
966 " }\n"
967 "}\n";
968
969 /* use own context with extra flags */
970 ly_ctx_destroy(UTEST_LYCTX);
971 const char *feats[] = {"f1", NULL};
972
973 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_EXPLICIT_COMPILE, &UTEST_LYCTX));
974 UTEST_ADD_MODULE(schema_a, LYS_IN_YANG, NULL, &mod);
975 UTEST_ADD_MODULE(schema_b, LYS_IN_YANG, NULL, NULL);
976 UTEST_ADD_MODULE(schema_c, LYS_IN_YANG, NULL, NULL);
977 assert_int_equal(LY_SUCCESS, lys_set_implemented((struct lys_module *)mod, feats));
978
Michal Vaskodd992582021-06-10 14:34:57 +0200979 /* none of the modules should be compiled */
Michal Vasko01db7de2021-04-16 12:23:30 +0200980 i = 0;
981 while ((mod = ly_ctx_get_module_iter(UTEST_LYCTX, &i))) {
Michal Vaskodd992582021-06-10 14:34:57 +0200982 assert_null(mod->compiled);
Michal Vasko01db7de2021-04-16 12:23:30 +0200983 }
984
985 assert_int_equal(LY_SUCCESS, ly_ctx_compile(UTEST_LYCTX));
986
987 /* check internal modules */
988 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "yang");
989 assert_non_null(mod);
990 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-datastores");
991 assert_non_null(mod);
992 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "ietf-yang-library");
993 assert_non_null(mod);
994
995 /* check test modules */
996 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "a");
997 assert_non_null(mod);
998 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "b");
999 assert_non_null(mod);
1000 mod = ly_ctx_get_module_implemented(UTEST_LYCTX, "c");
1001 assert_non_null(mod);
1002}
1003
Radek Iša56ca9e42020-09-08 18:42:00 +02001004int
1005main(void)
1006{
1007 const struct CMUnitTest tests[] = {
1008 UTEST(test_searchdirs),
1009 UTEST(test_options),
1010 UTEST(test_models),
1011 UTEST(test_imports),
1012 UTEST(test_get_models),
Tadeáš Vintrlíkea268182021-04-07 13:53:32 +02001013 UTEST(test_ylmem),
aPiecekbb96b802021-04-12 08:12:52 +02001014 UTEST(test_set_priv_parsed),
Michal Vasko01db7de2021-04-16 12:23:30 +02001015 UTEST(test_explicit_compile),
Radek Iša56ca9e42020-09-08 18:42:00 +02001016 };
1017
1018 return cmocka_run_group_tests(tests, NULL, NULL);
1019}