blob: 7c157739ef08f686a153cc9b4ffc2b0f02d6e879 [file] [log] [blame]
Radek Krejci85ac8312021-03-03 20:21:33 +01001/*
2 * @file test_schema_extensions.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for YANG (YIN) extension statements and their instances in schemas
5 *
6 * Copyright (c) 2018-2021 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#include "test_schema.h"
15
16#include <string.h>
17
18#include "context.h"
19#include "log.h"
20#include "tree_schema.h"
21
22void
23test_extension_argument(void **state)
24{
25 const struct lys_module *mod;
26 const char *mod_def_yang = "module a {\n"
27 " namespace \"urn:a\";\n"
28 " prefix a;\n\n"
29 " extension e {\n"
30 " argument name;\n"
31 " }\n\n"
32 " a:e \"aaa\";\n"
33 "}\n";
34 const char *mod_def_yin =
35 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
36 "<module name=\"a\"\n"
37 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
38 " xmlns:a=\"urn:a\">\n"
39 " <namespace uri=\"urn:a\"/>\n"
40 " <prefix value=\"a\"/>\n\n"
41 " <extension name=\"e\">\n"
42 " <argument name=\"name\"/>\n"
43 " </extension>\n\n"
44 " <a:e name=\"aaa\"/>\n"
45 "</module>\n";
46 const char *mod_test_yin, *mod_test_yang;
47 char *printed;
48
49 mod_test_yang = "module b {\n"
50 " namespace \"urn:b\";\n"
51 " prefix b;\n\n"
52 " import a {\n"
53 " prefix a;\n"
54 " }\n\n"
55 " a:e \"xxx\";\n"
56 "}\n";
57 mod_test_yin =
58 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
59 "<module name=\"b\"\n"
60 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
61 " xmlns:b=\"urn:b\"\n"
62 " xmlns:a=\"urn:a\">\n"
63 " <namespace uri=\"urn:b\"/>\n"
64 " <prefix value=\"b\"/>\n"
65 " <import module=\"a\">\n"
66 " <prefix value=\"a\"/>\n"
67 " </import>\n\n"
68 " <a:e name=\"xxx\"/>\n"
69 "</module>\n";
70
71 /* from YANG */
72 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)mod_def_yang);
73 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, mod_test_yang, LYS_IN_YANG, &mod));
74 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
75 assert_string_equal(printed, mod_test_yang);
76 free(printed);
77
78 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
79 assert_string_equal(printed, mod_test_yin);
80 free(printed);
81
82 assert_non_null(mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
83 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
84 assert_string_equal(printed, mod_def_yang);
85 free(printed);
86
87 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
88 assert_string_equal(printed, mod_def_yin);
89 free(printed);
90
91 /* context reset */
92 ly_ctx_destroy(UTEST_LYCTX, NULL);
93 ly_ctx_new(NULL, 0, &UTEST_LYCTX);
94
95 /* from YIN */
96 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)mod_def_yin);
97 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, &mod));
98 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
99 assert_string_equal(printed, mod_test_yang);
100 free(printed);
101
102 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
103 assert_string_equal(printed, mod_test_yin);
104 free(printed);
105
106 assert_non_null(mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
107 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
108 assert_string_equal(printed, mod_def_yang);
109 free(printed);
110
111 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
112 assert_string_equal(printed, mod_def_yin);
113 free(printed);
114}
115
116void
117test_extension_argument_element(void **state)
118{
119 const struct lys_module *mod;
120 const char *mod_def_yang = "module a {\n"
121 " namespace \"urn:a\";\n"
122 " prefix a;\n\n"
123 " extension e {\n"
124 " argument name {\n"
125 " yin-element true;\n"
126 " }\n"
127 " }\n\n"
128 " a:e \"aaa\";\n"
129 "}\n";
130 const char *mod_def_yin =
131 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
132 "<module name=\"a\"\n"
133 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
134 " xmlns:a=\"urn:a\">\n"
135 " <namespace uri=\"urn:a\"/>\n"
136 " <prefix value=\"a\"/>\n\n"
137 " <extension name=\"e\">\n"
138 " <argument name=\"name\">\n"
139 " <yin-element value=\"true\"/>\n"
140 " </argument>\n"
141 " </extension>\n\n"
142 " <a:e>\n"
143 " <a:name>aaa</a:name>\n"
144 " </a:e>\n"
145 "</module>\n";
146 const char *mod_test_yin, *mod_test_yang;
147 char *printed;
148
149 mod_test_yang = "module b {\n"
150 " namespace \"urn:b\";\n"
151 " prefix b;\n\n"
152 " import a {\n"
153 " prefix a;\n"
154 " }\n\n"
155 " a:e \"xxx\";\n"
156 "}\n";
157 mod_test_yin =
158 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
159 "<module name=\"b\"\n"
160 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
161 " xmlns:b=\"urn:b\"\n"
162 " xmlns:a=\"urn:a\">\n"
163 " <namespace uri=\"urn:b\"/>\n"
164 " <prefix value=\"b\"/>\n"
165 " <import module=\"a\">\n"
166 " <prefix value=\"a\"/>\n"
167 " </import>\n\n"
168 " <a:e>\n"
169 " <a:name>xxx</a:name>\n"
170 " </a:e>\n"
171 "</module>\n";
172
173 /* from YANG */
174 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)mod_def_yang);
175 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, mod_test_yang, LYS_IN_YANG, &mod));
176 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
177 assert_string_equal(printed, mod_test_yang);
178 free(printed);
179
180 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
181 assert_string_equal(printed, mod_test_yin);
182 free(printed);
183
184 assert_non_null(mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
185 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
186 assert_string_equal(printed, mod_def_yang);
187 free(printed);
188
189 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
190 assert_string_equal(printed, mod_def_yin);
191 free(printed);
192
193 /* context reset */
194 ly_ctx_destroy(UTEST_LYCTX, NULL);
195 ly_ctx_new(NULL, 0, &UTEST_LYCTX);
196
197 /* from YIN */
198 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, (void *)mod_def_yin);
199 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, &mod));
200 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
201 assert_string_equal(printed, mod_test_yang);
202 free(printed);
203
204 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
205 assert_string_equal(printed, mod_test_yin);
206 free(printed);
207
208 assert_non_null(mod = ly_ctx_get_module(UTEST_LYCTX, "a", NULL));
209 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YANG, 0));
210 assert_string_equal(printed, mod_def_yang);
211 free(printed);
212
213 assert_int_equal(LY_SUCCESS, lys_print_mem(&printed, mod, LYS_OUT_YIN, 0));
214 assert_string_equal(printed, mod_def_yin);
215 free(printed);
216
217 /* invalid */
218 mod_test_yang = "module x { namespace \"urn:x\"; prefix x; import a { prefix a; } a:e; }";
219 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yang, LYS_IN_YANG, NULL));
220 CHECK_LOG_CTX("Extension instance \"a:e\" misses argument element \"name\".", "/x:{extension='a:e'}");
221
222 mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
223 "<module name=\"x\"\n"
224 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
225 " xmlns:x=\"urn:x\"\n"
226 " xmlns:a=\"urn:a\">\n"
227 " <namespace uri=\"urn:x\"/>\n"
228 " <prefix value=\"x\"/>\n"
229 " <import module=\"a\">\n"
230 " <prefix value=\"a\"/>\n"
231 " </import>\n\n"
232 " <a:e/>\n"
233 "</module>\n";
234 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL));
235 CHECK_LOG_CTX("Extension instance \"a:e\" misses argument element \"name\".", "/x:{extension='a:e'}");
236
237 mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
238 "<module name=\"x\"\n"
239 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
240 " xmlns:x=\"urn:x\"\n"
241 " xmlns:a=\"urn:a\">\n"
242 " <namespace uri=\"urn:x\"/>\n"
243 " <prefix value=\"x\"/>\n"
244 " <import module=\"a\">\n"
245 " <prefix value=\"a\"/>\n"
246 " </import>\n\n"
247 " <a:e name=\"xxx\"/>\n"
248 "</module>\n";
249 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL));
250 CHECK_LOG_CTX("Extension instance \"a:e\" misses argument element \"name\".", "/x:{extension='a:e'}");
251
252 mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
253 "<module name=\"x\"\n"
254 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
255 " xmlns:x=\"urn:x\"\n"
256 " xmlns:a=\"urn:a\">\n"
257 " <namespace uri=\"urn:x\"/>\n"
258 " <prefix value=\"x\"/>\n"
259 " <import module=\"a\">\n"
260 " <prefix value=\"a\"/>\n"
261 " </import>\n\n"
262 " <a:e>\n"
263 " <x:name>xxx</x:name>\n"
264 " </a:e>\n"
265 "</module>\n";
266 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL));
267 CHECK_LOG_CTX("Extension instance \"a:e\" element and its argument element \"name\" are expected in the same namespace, but they differ.",
268 "/x:{extension='a:e'}");
269
270 mod_test_yin = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
271 "<module name=\"x\"\n"
272 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
273 " xmlns:x=\"urn:x\"\n"
274 " xmlns:a=\"urn:a\">\n"
275 " <namespace uri=\"urn:x\"/>\n"
276 " <prefix value=\"x\"/>\n"
277 " <import module=\"a\">\n"
278 " <prefix value=\"a\"/>\n"
279 " </import>\n\n"
280 " <a:e>\n"
281 " <a:value>xxx</a:value>\n"
282 " </a:e>\n"
283 "</module>\n";
284 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, mod_test_yin, LYS_IN_YIN, NULL));
285 CHECK_LOG_CTX("Extension instance \"a:e\" expects argument element \"name\" as its first XML child, but \"value\" element found.",
286 "/x:{extension='a:e'}");
287
288}