blob: 7a8bfcc5806ca38433c9c5aeaa63cd9f4a0b3a26 [file] [log] [blame]
David Sedlákb1ce3f82019-06-05 14:37:26 +02001/**
2 * @file test_parser_yin.c
3 * @author David Sedlák <xsedla1d@stud.fit.vutbr.cz>
4 * @brief unit tests for functions from parser_yin.c
5 *
6 * Copyright (c) 2015 - 2019 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
David Sedlák3b4db242018-10-19 16:11:01 +020015#include <stdarg.h>
16#include <stddef.h>
17#include <setjmp.h>
18#include <cmocka.h>
19
20#include <stdio.h>
21#include <string.h>
David Sedlák79e50cb2019-06-05 16:33:09 +020022#include <stdbool.h>
David Sedlák3b4db242018-10-19 16:11:01 +020023
David Sedlákecf5eb82019-06-03 14:12:44 +020024#include "../../src/common.h"
25#include "../../src/tree_schema.h"
26#include "../../src/tree_schema_internal.h"
27#include "../../src/parser_yin.h"
David Sedlák8f5bce02019-06-03 16:41:08 +020028#include "../../src/xml.h"
David Sedlák3b4db242018-10-19 16:11:01 +020029
David Sedlák555c7202019-07-04 12:14:12 +020030/* prototypes of static functions */
31void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
David Sedlák986cb412019-07-04 13:10:11 +020032void lysp_ext_free(struct ly_ctx *ctx, struct lysp_ext *ext);
David Sedlák555c7202019-07-04 12:14:12 +020033
David Sedlák68a1af12019-03-08 13:46:54 +010034struct state {
David Sedlák3b4db242018-10-19 16:11:01 +020035 struct ly_ctx *ctx;
David Sedlák3017da42019-02-15 09:48:04 +010036 struct lys_module *mod;
David Sedlák619db942019-07-03 14:47:30 +020037 struct lysp_module *lysp_mod;
David Sedlákda8ffa32019-07-08 14:17:10 +020038 struct yin_parser_ctx *yin_ctx;
David Sedlák79e50cb2019-06-05 16:33:09 +020039 bool finished_correctly;
David Sedlák68a1af12019-03-08 13:46:54 +010040};
David Sedlák872c7b42018-10-26 13:15:20 +020041
David Sedlák79e50cb2019-06-05 16:33:09 +020042#define BUFSIZE 1024
43char logbuf[BUFSIZE] = {0};
44int store = -1; /* negative for infinite logging, positive for limited logging */
45
46/* set to 0 to printing error messages to stderr instead of checking them in code */
47#define ENABLE_LOGGER_CHECKING 1
48
49#if ENABLE_LOGGER_CHECKING
50static void
51logger(LY_LOG_LEVEL level, const char *msg, const char *path)
52{
53 (void) level; /* unused */
54 if (store) {
55 if (path && path[0]) {
56 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
57 } else {
58 strncpy(logbuf, msg, BUFSIZE - 1);
59 }
60 if (store > 0) {
61 --store;
62 }
63 }
64}
65#endif
66
67#if ENABLE_LOGGER_CHECKING
68# define logbuf_assert(str) assert_string_equal(logbuf, str)
69#else
70# define logbuf_assert(str)
71#endif
72
73#define TEST_DUP_GENERIC(PREFIX, MEMBER, VALUE1, VALUE2, FUNC, RESULT, LINE, CLEANUP) \
74 str = PREFIX MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
75 assert_int_equal(LY_EVALID, FUNC(&ctx, &str, RESULT)); \
76 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
77 CLEANUP
78
79
David Sedlák68a1af12019-03-08 13:46:54 +010080static int
81setup_f(void **state)
82{
83 struct state *st = NULL;
David Sedlák3b4db242018-10-19 16:11:01 +020084
David Sedlák79e50cb2019-06-05 16:33:09 +020085#if ENABLE_LOGGER_CHECKING
86 /* setup logger */
87 ly_set_log_clb(logger, 1);
88#endif
89
David Sedlák68a1af12019-03-08 13:46:54 +010090 /* allocate state variable */
91 (*state) = st = calloc(1, sizeof(*st));
92 if (!st) {
93 fprintf(stderr, "Memmory allocation failed");
94 return EXIT_FAILURE;
95 }
David Sedlák872c7b42018-10-26 13:15:20 +020096
David Sedlák68a1af12019-03-08 13:46:54 +010097 /* create new libyang context */
98 ly_ctx_new(NULL, 0, &st->ctx);
David Sedlák872c7b42018-10-26 13:15:20 +020099
David Sedlák68a1af12019-03-08 13:46:54 +0100100 /* allocate new module */
101 st->mod = calloc(1, sizeof(*st->mod));
102 st->mod->ctx = st->ctx;
103
David Sedlák619db942019-07-03 14:47:30 +0200104 /* allocate new parsed module */
105 st->lysp_mod = calloc(1, sizeof(*st->lysp_mod));
106 st->lysp_mod->mod = calloc(1, sizeof(*st->lysp_mod->mod));
107 st->lysp_mod->mod->ctx = st->ctx;
108
109 /* allocate parser context */
David Sedlákda8ffa32019-07-08 14:17:10 +0200110 st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
111 st->yin_ctx->xml_ctx.ctx = st->ctx;
112 st->yin_ctx->xml_ctx.line = 1;
David Sedlák8f5bce02019-06-03 16:41:08 +0200113
David Sedlák68a1af12019-03-08 13:46:54 +0100114 return EXIT_SUCCESS;
David Sedlák3b4db242018-10-19 16:11:01 +0200115}
116
117static int
David Sedlák68a1af12019-03-08 13:46:54 +0100118teardown_f(void **state)
119{
120 struct state *st = *(struct state **)state;
David Sedlák619db942019-07-03 14:47:30 +0200121 struct lys_module *temp;
David Sedlák68a1af12019-03-08 13:46:54 +0100122
David Sedlák79e50cb2019-06-05 16:33:09 +0200123#if ENABLE_LOGGER_CHECKING
124 /* teardown logger */
125 if (!st->finished_correctly && logbuf[0] != '\0') {
126 fprintf(stderr, "%s\n", logbuf);
127 }
128#endif
129
David Sedlák619db942019-07-03 14:47:30 +0200130 temp = st->lysp_mod->mod;
131
David Sedlákda8ffa32019-07-08 14:17:10 +0200132 lyxml_context_clear(&st->yin_ctx->xml_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100133 lys_module_free(st->mod, NULL);
David Sedlák619db942019-07-03 14:47:30 +0200134 lysp_module_free(st->lysp_mod);
135 lys_module_free(temp, NULL);
David Sedlák68a1af12019-03-08 13:46:54 +0100136 ly_ctx_destroy(st->ctx, NULL);
David Sedlákda8ffa32019-07-08 14:17:10 +0200137 free(st->yin_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100138 free(st);
139
140 return EXIT_SUCCESS;
141}
142
David Sedlák392af4f2019-06-04 16:02:42 +0200143static struct state*
144reset_state(void **state)
145{
David Sedlák79e50cb2019-06-05 16:33:09 +0200146 ((struct state *)*state)->finished_correctly = true;
David Sedlák555c7202019-07-04 12:14:12 +0200147 logbuf[0] = '\0';
David Sedlák392af4f2019-06-04 16:02:42 +0200148 teardown_f(state);
149 setup_f(state);
150
151 return *state;
152}
153
David Sedlák79e50cb2019-06-05 16:33:09 +0200154void
155logbuf_clean(void)
156{
157 logbuf[0] = '\0';
158}
159
David Sedlák68a1af12019-03-08 13:46:54 +0100160static void
David Sedlák392af4f2019-06-04 16:02:42 +0200161test_yin_parse_module(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +0100162{
163 LY_ERR ret = LY_SUCCESS;
164 struct state *st = *state;
165
166 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200167 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
168 name=\"example-foo\"\
David Sedlák18730132019-03-15 15:51:34 +0100169 xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
170 xmlns:foo=\"urn:example:foo\"\
171 xmlns:myext=\"urn:example:extensions\">\
David Sedlákcd0c9512019-03-29 13:23:06 +0100172 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedláka7406952019-04-05 10:33:07 +0200173 <prefix xmlns:myxt=\"urn:emple:extensions\" value=\"foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlákd9d3a312019-06-04 09:47:10 +0200174 </module>",
David Sedlák68a1af12019-03-08 13:46:54 +0100175 st->mod);
176
177 assert_int_equal(ret, LY_SUCCESS);
178 assert_string_equal(st->mod->parsed->mod->name, "example-foo");
179 assert_string_equal(st->mod->parsed->mod->prefix, "foo");
David Sedlákcd0c9512019-03-29 13:23:06 +0100180 assert_string_equal(st->mod->parsed->mod->ns, "urn:example:foo");
David Sedlák392af4f2019-06-04 16:02:42 +0200181
182 st = reset_state(state);
183 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200184 "<module name=\"example-foo\">\
185 <invalid-tag uri=\"urn:example:foo\"\"/>\
186 </module>",
187 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200188 assert_int_equal(ret, LY_EVALID);
189
190 st = reset_state(state);
191 ret = yin_parse_module(st->ctx,
David Sedlák8f7a1172019-06-20 14:42:18 +0200192 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák57715b12019-06-17 13:05:22 +0200193 </module>",
David Sedlák2b214ac2019-06-06 16:11:03 +0200194 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200195 assert_int_equal(ret, LY_EVALID);
David Sedlák21f87cd2019-07-03 16:53:23 +0200196 logbuf_assert("Missing mandatory attribute \"name\" of module element. Line number 1.");
David Sedlák392af4f2019-06-04 16:02:42 +0200197
198 st = reset_state(state);
199 ret = yin_parse_module(st->ctx,
200 "",
201 st->mod);
202 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200203 logbuf_assert("Invalid keyword \"(null)\", expected \"module\" or \"submodule\". Line number 1.");
204 st->finished_correctly = true;
David Sedlák3b4db242018-10-19 16:11:01 +0200205}
206
207static void
David Sedlák1bccdfa2019-06-17 15:55:27 +0200208test_yin_match_keyword(void **state)
David Sedlák3b4db242018-10-19 16:11:01 +0200209{
David Sedlák8f7a1172019-06-20 14:42:18 +0200210 struct state *st = *state;
David Sedlák3b4db242018-10-19 16:11:01 +0200211
David Sedlák8f7a1172019-06-20 14:42:18 +0200212 const char *prefix, *name;
213 struct yin_arg_record *args = NULL;
214 size_t prefix_len, name_len;
215 /* create mock yin namespace in xml context */
216 const char *data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200217 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
218 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200219 LY_ARRAY_FREE(args);
220
David Sedlákda8ffa32019-07-08 14:17:10 +0200221 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydatax", strlen("anydatax"), prefix, prefix_len), YANG_NONE);
222 assert_int_equal(yin_match_keyword(st->yin_ctx, "asdasd", strlen("asdasd"), prefix, prefix_len), YANG_NONE);
223 assert_int_equal(yin_match_keyword(st->yin_ctx, "", 0, prefix, prefix_len), YANG_NONE);
224 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydata", strlen("anydata"), prefix, prefix_len), YANG_ANYDATA);
225 assert_int_equal(yin_match_keyword(st->yin_ctx, "anyxml", strlen("anyxml"), prefix, prefix_len), YANG_ANYXML);
226 assert_int_equal(yin_match_keyword(st->yin_ctx, "argument", strlen("argument"), prefix, prefix_len), YANG_ARGUMENT);
227 assert_int_equal(yin_match_keyword(st->yin_ctx, "augment", strlen("augment"), prefix, prefix_len), YANG_AUGMENT);
228 assert_int_equal(yin_match_keyword(st->yin_ctx, "base", strlen("base"), prefix, prefix_len), YANG_BASE);
229 assert_int_equal(yin_match_keyword(st->yin_ctx, "belongs-to", strlen("belongs-to"), prefix, prefix_len), YANG_BELONGS_TO);
230 assert_int_equal(yin_match_keyword(st->yin_ctx, "bit", strlen("bit"), prefix, prefix_len), YANG_BIT);
231 assert_int_equal(yin_match_keyword(st->yin_ctx, "case", strlen("case"), prefix, prefix_len), YANG_CASE);
232 assert_int_equal(yin_match_keyword(st->yin_ctx, "choice", strlen("choice"), prefix, prefix_len), YANG_CHOICE);
233 assert_int_equal(yin_match_keyword(st->yin_ctx, "config", strlen("config"), prefix, prefix_len), YANG_CONFIG);
234 assert_int_equal(yin_match_keyword(st->yin_ctx, "contact", strlen("contact"), prefix, prefix_len), YANG_CONTACT);
235 assert_int_equal(yin_match_keyword(st->yin_ctx, "container", strlen("container"), prefix, prefix_len), YANG_CONTAINER);
236 assert_int_equal(yin_match_keyword(st->yin_ctx, "default", strlen("default"), prefix, prefix_len), YANG_DEFAULT);
237 assert_int_equal(yin_match_keyword(st->yin_ctx, "description", strlen("description"), prefix, prefix_len), YANG_DESCRIPTION);
238 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviate", strlen("deviate"), prefix, prefix_len), YANG_DEVIATE);
239 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviation", strlen("deviation"), prefix, prefix_len), YANG_DEVIATION);
240 assert_int_equal(yin_match_keyword(st->yin_ctx, "enum", strlen("enum"), prefix, prefix_len), YANG_ENUM);
241 assert_int_equal(yin_match_keyword(st->yin_ctx, "error-app-tag", strlen("error-app-tag"), prefix, prefix_len), YANG_ERROR_APP_TAG);
242 assert_int_equal(yin_match_keyword(st->yin_ctx, "error-message", strlen("error-message"), prefix, prefix_len), YANG_ERROR_MESSAGE);
243 assert_int_equal(yin_match_keyword(st->yin_ctx, "extension", strlen("extension"), prefix, prefix_len), YANG_EXTENSION);
244 assert_int_equal(yin_match_keyword(st->yin_ctx, "feature", strlen("feature"), prefix, prefix_len), YANG_FEATURE);
245 assert_int_equal(yin_match_keyword(st->yin_ctx, "fraction-digits", strlen("fraction-digits"), prefix, prefix_len), YANG_FRACTION_DIGITS);
246 assert_int_equal(yin_match_keyword(st->yin_ctx, "grouping", strlen("grouping"), prefix, prefix_len), YANG_GROUPING);
247 assert_int_equal(yin_match_keyword(st->yin_ctx, "identity", strlen("identity"), prefix, prefix_len), YANG_IDENTITY);
248 assert_int_equal(yin_match_keyword(st->yin_ctx, "if-feature", strlen("if-feature"), prefix, prefix_len), YANG_IF_FEATURE);
249 assert_int_equal(yin_match_keyword(st->yin_ctx, "import", strlen("import"), prefix, prefix_len), YANG_IMPORT);
250 assert_int_equal(yin_match_keyword(st->yin_ctx, "include", strlen("include"), prefix, prefix_len), YANG_INCLUDE);
251 assert_int_equal(yin_match_keyword(st->yin_ctx, "input", strlen("input"), prefix, prefix_len), YANG_INPUT);
252 assert_int_equal(yin_match_keyword(st->yin_ctx, "key", strlen("key"), prefix, prefix_len), YANG_KEY);
253 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf", strlen("leaf"), prefix, prefix_len), YANG_LEAF);
254 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf-list", strlen("leaf-list"), prefix, prefix_len), YANG_LEAF_LIST);
255 assert_int_equal(yin_match_keyword(st->yin_ctx, "length", strlen("length"), prefix, prefix_len), YANG_LENGTH);
256 assert_int_equal(yin_match_keyword(st->yin_ctx, "list", strlen("list"), prefix, prefix_len), YANG_LIST);
257 assert_int_equal(yin_match_keyword(st->yin_ctx, "mandatory", strlen("mandatory"), prefix, prefix_len), YANG_MANDATORY);
258 assert_int_equal(yin_match_keyword(st->yin_ctx, "max-elements", strlen("max-elements"), prefix, prefix_len), YANG_MAX_ELEMENTS);
259 assert_int_equal(yin_match_keyword(st->yin_ctx, "min-elements", strlen("min-elements"), prefix, prefix_len), YANG_MIN_ELEMENTS);
260 assert_int_equal(yin_match_keyword(st->yin_ctx, "modifier", strlen("modifier"), prefix, prefix_len), YANG_MODIFIER);
261 assert_int_equal(yin_match_keyword(st->yin_ctx, "module", strlen("module"), prefix, prefix_len), YANG_MODULE);
262 assert_int_equal(yin_match_keyword(st->yin_ctx, "must", strlen("must"), prefix, prefix_len), YANG_MUST);
263 assert_int_equal(yin_match_keyword(st->yin_ctx, "namespace", strlen("namespace"), prefix, prefix_len), YANG_NAMESPACE);
264 assert_int_equal(yin_match_keyword(st->yin_ctx, "notification", strlen("notification"), prefix, prefix_len), YANG_NOTIFICATION);
265 assert_int_equal(yin_match_keyword(st->yin_ctx, "ordered-by", strlen("ordered-by"), prefix, prefix_len), YANG_ORDERED_BY);
266 assert_int_equal(yin_match_keyword(st->yin_ctx, "organization", strlen("organization"), prefix, prefix_len), YANG_ORGANIZATION);
267 assert_int_equal(yin_match_keyword(st->yin_ctx, "output", strlen("output"), prefix, prefix_len), YANG_OUTPUT);
268 assert_int_equal(yin_match_keyword(st->yin_ctx, "path", strlen("path"), prefix, prefix_len), YANG_PATH);
269 assert_int_equal(yin_match_keyword(st->yin_ctx, "pattern", strlen("pattern"), prefix, prefix_len), YANG_PATTERN);
270 assert_int_equal(yin_match_keyword(st->yin_ctx, "position", strlen("position"), prefix, prefix_len), YANG_POSITION);
271 assert_int_equal(yin_match_keyword(st->yin_ctx, "prefix", strlen("prefix"), prefix, prefix_len), YANG_PREFIX);
272 assert_int_equal(yin_match_keyword(st->yin_ctx, "presence", strlen("presence"), prefix, prefix_len), YANG_PRESENCE);
273 assert_int_equal(yin_match_keyword(st->yin_ctx, "range", strlen("range"), prefix, prefix_len), YANG_RANGE);
274 assert_int_equal(yin_match_keyword(st->yin_ctx, "reference", strlen("reference"), prefix, prefix_len), YANG_REFERENCE);
275 assert_int_equal(yin_match_keyword(st->yin_ctx, "refine", strlen("refine"), prefix, prefix_len), YANG_REFINE);
276 assert_int_equal(yin_match_keyword(st->yin_ctx, "require-instance", strlen("require-instance"), prefix, prefix_len), YANG_REQUIRE_INSTANCE);
277 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision", strlen("revision"), prefix, prefix_len), YANG_REVISION);
278 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision-date", strlen("revision-date"), prefix, prefix_len), YANG_REVISION_DATE);
279 assert_int_equal(yin_match_keyword(st->yin_ctx, "rpc", strlen("rpc"), prefix, prefix_len), YANG_RPC);
280 assert_int_equal(yin_match_keyword(st->yin_ctx, "status", strlen("status"), prefix, prefix_len), YANG_STATUS);
281 assert_int_equal(yin_match_keyword(st->yin_ctx, "submodule", strlen("submodule"), prefix, prefix_len), YANG_SUBMODULE);
282 assert_int_equal(yin_match_keyword(st->yin_ctx, "type", strlen("type"), prefix, prefix_len), YANG_TYPE);
283 assert_int_equal(yin_match_keyword(st->yin_ctx, "typedef", strlen("typedef"), prefix, prefix_len), YANG_TYPEDEF);
284 assert_int_equal(yin_match_keyword(st->yin_ctx, "unique", strlen("unique"), prefix, prefix_len), YANG_UNIQUE);
285 assert_int_equal(yin_match_keyword(st->yin_ctx, "units", strlen("units"), prefix, prefix_len), YANG_UNITS);
286 assert_int_equal(yin_match_keyword(st->yin_ctx, "uses", strlen("uses"), prefix, prefix_len), YANG_USES);
287 assert_int_equal(yin_match_keyword(st->yin_ctx, "value", strlen("value"), prefix, prefix_len), YANG_VALUE);
288 assert_int_equal(yin_match_keyword(st->yin_ctx, "when", strlen("when"), prefix, prefix_len), YANG_WHEN);
289 assert_int_equal(yin_match_keyword(st->yin_ctx, "yang-version", strlen("yang-version"), prefix, prefix_len), YANG_YANG_VERSION);
290 assert_int_equal(yin_match_keyword(st->yin_ctx, "yin-element", strlen("yin-element"), prefix, prefix_len), YANG_YIN_ELEMENT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200291
292 st->finished_correctly = true;
David Sedlák872c7b42018-10-26 13:15:20 +0200293}
David Sedlák3b4db242018-10-19 16:11:01 +0200294
David Sedlák872c7b42018-10-26 13:15:20 +0200295static void
David Sedlák060b00e2019-06-19 11:12:06 +0200296test_yin_match_argument_name(void **state)
David Sedlák872c7b42018-10-26 13:15:20 +0200297{
David Sedlák68a1af12019-03-08 13:46:54 +0100298 (void)state; /* unused */
David Sedlák872c7b42018-10-26 13:15:20 +0200299
David Sedlák060b00e2019-06-19 11:12:06 +0200300 assert_int_equal(yin_match_argument_name("", 5), YIN_ARG_UNKNOWN);
301 assert_int_equal(yin_match_argument_name("qwertyasd", 5), YIN_ARG_UNKNOWN);
302 assert_int_equal(yin_match_argument_name("conditionasd", 8), YIN_ARG_UNKNOWN);
303 assert_int_equal(yin_match_argument_name("condition", 9), YIN_ARG_CONDITION);
304 assert_int_equal(yin_match_argument_name("date", 4), YIN_ARG_DATE);
305 assert_int_equal(yin_match_argument_name("module", 6), YIN_ARG_MODULE);
306 assert_int_equal(yin_match_argument_name("name", 4), YIN_ARG_NAME);
307 assert_int_equal(yin_match_argument_name("tag", 3), YIN_ARG_TAG);
308 assert_int_equal(yin_match_argument_name("target-node", 11), YIN_ARG_TARGET_NODE);
309 assert_int_equal(yin_match_argument_name("text", 4), YIN_ARG_TEXT);
310 assert_int_equal(yin_match_argument_name("uri", 3), YIN_ARG_URI);
311 assert_int_equal(yin_match_argument_name("value", 5), YIN_ARG_VALUE);
David Sedlák3b4db242018-10-19 16:11:01 +0200312}
313
David Sedlák68a1af12019-03-08 13:46:54 +0100314static void
315test_meta(void **state)
316{
317 LY_ERR ret = LY_SUCCESS;
318 struct state *st = *state;
319
David Sedlák2b214ac2019-06-06 16:11:03 +0200320 ret = yin_parse_module(st->ctx,"<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
321 name=\"example-foo\">\
David Sedlák21f87cd2019-07-03 16:53:23 +0200322 <prefix value=\"foo\">ignored</prefix>\
323 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlák15a92662019-06-18 11:55:15 +0200324 <organization xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"><text>organization...</text></organization>\
325 <contact><text>contact...</text></contact>\
326 <description><text>description...</text></description>\
327 <reference><text>reference...</text></reference>\
David Sedlák68a1af12019-03-08 13:46:54 +0100328 </module>", st->mod);
329
330 assert_int_equal(ret, LY_SUCCESS);
David Sedláka7406952019-04-05 10:33:07 +0200331 assert_string_equal(st->mod->parsed->mod->org, "organization...");
David Sedlák68a1af12019-03-08 13:46:54 +0100332 assert_string_equal(st->mod->parsed->mod->contact, "contact...");
333 assert_string_equal(st->mod->parsed->mod->dsc, "description...");
334 assert_string_equal(st->mod->parsed->mod->ref, "reference...");
David Sedlák68826732019-06-05 10:50:58 +0200335
336 st = reset_state(state);
337 ret = yin_parse_module(st->ctx,"<module name=\"example-foo\">\
338 <organization test=\"invalid-argument\">organization...</organization>\
339 </module>", st->mod);
340 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200341
342 st->finished_correctly = true;
David Sedlák68a1af12019-03-08 13:46:54 +0100343}
344
David Sedlák8f5bce02019-06-03 16:41:08 +0200345static void
David Sedlákda63c082019-06-04 13:52:23 +0200346test_yin_parse_import(void **state)
347{
348 struct state *st = *state;
349 const char *prefix = NULL, *name = NULL;
350 size_t prefix_len = 0, name_len = 0;
351 LY_ERR ret = LY_SUCCESS;
David Sedlák8f7a1172019-06-20 14:42:18 +0200352 struct yin_arg_record *args = NULL;
David Sedlákda63c082019-06-04 13:52:23 +0200353
David Sedlák2b214ac2019-06-06 16:11:03 +0200354 const char *data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákda63c082019-06-04 13:52:23 +0200355 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200356 <revision-date date=\"2015-01-01\"></revision-date>\
David Sedlákb6e65972019-06-19 10:44:13 +0200357 <description><text>import description</text></description>\
358 <reference><text>import reference</text></reference>\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200359 </import>\
360 \
David Sedlák2b214ac2019-06-06 16:11:03 +0200361 <import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200362 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200363 <revision-date date=\"2015-01-01\" />\
David Sedlákda63c082019-06-04 13:52:23 +0200364 </import>";
David Sedlákb6e65972019-06-19 10:44:13 +0200365 /* first import */
David Sedlákda8ffa32019-07-08 14:17:10 +0200366 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
367 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200368 st->lysp_mod->mod->prefix = "b-mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200369 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákda63c082019-06-04 13:52:23 +0200370 assert_int_equal(ret, LY_SUCCESS);
David Sedlák619db942019-07-03 14:47:30 +0200371 assert_string_equal(st->lysp_mod->imports->name, "a");
372 assert_string_equal(st->lysp_mod->imports->prefix, "a_mod");
373 assert_string_equal(st->lysp_mod->imports->rev, "2015-01-01");
374 assert_string_equal(st->lysp_mod->imports->dsc, "import description");
375 assert_string_equal(st->lysp_mod->imports->ref, "import reference");
David Sedlák8f7a1172019-06-20 14:42:18 +0200376 LY_ARRAY_FREE(args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200377 args = NULL;
David Sedlák619db942019-07-03 14:47:30 +0200378 st = reset_state(state);
David Sedlákc67dcaa2019-06-04 14:49:05 +0200379
David Sedlákb6e65972019-06-19 10:44:13 +0200380 /* second invalid import */
David Sedlákda8ffa32019-07-08 14:17:10 +0200381 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
382 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200383 st->lysp_mod->mod->prefix = "a_mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200384 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákda63c082019-06-04 13:52:23 +0200385 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200386 logbuf_assert("Prefix \"a_mod\" already used as module prefix. Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200387 LY_ARRAY_FREE(args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200388 args = NULL;
389
David Sedlákb6e65972019-06-19 10:44:13 +0200390 st = reset_state(state);
391 /* import with unknown child element */
392 data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
393 <what value=\"a_mod\"/>\
394 </import>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200395 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
396 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200397 st->lysp_mod->mod->prefix = "invalid_mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200398 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákb6e65972019-06-19 10:44:13 +0200399 assert_int_equal(ret, LY_EVALID);
David Sedlák3ffbc522019-07-02 17:49:28 +0200400 logbuf_assert("Unexpected child element \"what\" of import element. Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200401 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200402
403 st->finished_correctly = true;
404}
405
406static void
407test_yin_parse_status(void **state)
408{
409 struct state *st = *state;
410 const char *prefix = NULL, *name = NULL;
411 size_t prefix_len = 0, name_len = 0;
412 LY_ERR ret = LY_SUCCESS;
413 uint16_t flags = 0;
414 struct lysp_ext_instance *exts;
David Sedlák8f7a1172019-06-20 14:42:18 +0200415 struct yin_arg_record *args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200416
417 /* try all valid values */
418 const char *data = "<status value=\"current\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200419 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
420 yin_load_attributes(st->yin_ctx, &data, &args);
421 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
422 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200423 assert_int_equal(ret, LY_SUCCESS);
424 assert_true(flags & LYS_STATUS_CURR);
David Sedlák8f7a1172019-06-20 14:42:18 +0200425 LY_ARRAY_FREE(args);
426 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200427
428 st = reset_state(state);
429 flags = 0;
430 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200431 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
432 yin_load_attributes(st->yin_ctx, &data, &args);
433 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
434 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200435 assert_int_equal(ret, LY_SUCCESS);
436 assert_true(flags & LYS_STATUS_DEPRC);
David Sedlák8f7a1172019-06-20 14:42:18 +0200437 LY_ARRAY_FREE(args);
438 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200439
440 st = reset_state(state);
441 flags = 0;
442 data = "<status value=\"obsolete\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200443 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
444 yin_load_attributes(st->yin_ctx, &data, &args);
445 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
446 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200447 assert_int_equal(ret, LY_SUCCESS);
448 assert_true(flags & LYS_STATUS_OBSLT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200449 LY_ARRAY_FREE(args);
450 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200451
452 /* duplicit definition (no reset_state() call) */
453 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200454 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
455 yin_load_attributes(st->yin_ctx, &data, &args);
456 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200457 assert_int_equal(ret, LY_EVALID);
458 logbuf_assert("Duplicate element \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200459 LY_ARRAY_FREE(args);
460 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200461
462 /* invalid status value */
463 st = reset_state(state);
464 flags = 0;
465 data = "<status value=\"dunno\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200466 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
467 yin_load_attributes(st->yin_ctx, &data, &args);
468 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200469 assert_int_equal(ret, LY_EVALID);
470 logbuf_assert("Invalid value \"dunno\" of \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200471 LY_ARRAY_FREE(args);
472
David Sedlák79e50cb2019-06-05 16:33:09 +0200473 st->finished_correctly = true;
David Sedlákda63c082019-06-04 13:52:23 +0200474}
475
David Sedlák554e36d2019-06-20 16:00:04 +0200476static void
477test_yin_parse_extension(void **state)
478{
479 struct state *st = *state;
480 const char *prefix = NULL, *name = NULL;
481 size_t prefix_len = 0, name_len = 0;
482 LY_ERR ret = LY_SUCCESS;
483 struct yin_arg_record *args = NULL;
484 struct lysp_ext *exts = NULL, *iter = NULL;
485
486 const char *data = "<extension name=\"b\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák9494eb22019-06-21 16:06:53 +0200487 <argument name=\"argname\"></argument>\
David Sedlák554e36d2019-06-20 16:00:04 +0200488 <description><text>desc</text></description>\
489 <reference><text>ref</text></reference>\
490 <status value=\"deprecated\"></status>\
491 </extension>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200492 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
493 yin_load_attributes(st->yin_ctx, &data, &args);
494 ret = yin_parse_extension(st->yin_ctx, &args, &data, &exts);
495 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák554e36d2019-06-20 16:00:04 +0200496 assert_int_equal(ret, LY_SUCCESS);
497 LY_ARRAY_FOR_ITER(exts, struct lysp_ext, iter) {
498 assert_string_equal(iter->name, "b");
499 assert_string_equal(iter->dsc, "desc");
500 assert_string_equal(iter->ref, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200501 assert_string_equal(iter->argument, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200502 assert_true(iter->flags & LYS_STATUS_DEPRC);
503 }
David Sedlák288c1472019-06-20 16:09:48 +0200504 lydict_remove(st->ctx, "b");
505 lydict_remove(st->ctx, "desc");
506 lydict_remove(st->ctx, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200507 lydict_remove(st->ctx, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200508 LY_ARRAY_FREE(args);
David Sedlák288c1472019-06-20 16:09:48 +0200509 LY_ARRAY_FREE(exts);
David Sedlák554e36d2019-06-20 16:00:04 +0200510 st->finished_correctly = true;
511}
512
David Sedlák2721d3d2019-06-21 15:37:41 +0200513static void
514test_yin_parse_yin_element_element(void **state)
515{
516 struct state *st = *state;
517 const char *prefix = NULL, *name = NULL;
518 size_t prefix_len = 0, name_len = 0;
519 LY_ERR ret = LY_SUCCESS;
520 uint16_t flags = 0;
David Sedlák3ffbc522019-07-02 17:49:28 +0200521 struct lysp_ext_instance *exts;
David Sedlák2721d3d2019-06-21 15:37:41 +0200522 struct yin_arg_record *args = NULL;
523
524 /* try all valid values */
525 const char *data = "<yin-element value=\"true\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200526 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
527 yin_load_attributes(st->yin_ctx, &data, &args);
528 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
529 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200530 assert_int_equal(ret, LY_SUCCESS);
531 assert_true(flags & LYS_YINELEM_TRUE);
532 LY_ARRAY_FREE(args);
533 args = NULL;
534
535 st = reset_state(state);
536 flags = 0;
537 data = "<yin-element value=\"false\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200538 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
539 yin_load_attributes(st->yin_ctx, &data, &args);
540 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
541 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200542 assert_int_equal(ret, LY_SUCCESS);
543 assert_true(flags & LYS_YINELEM_FALSE);
544 LY_ARRAY_FREE(args);
545 args = NULL;
546
547 /* invalid value */
548 st = reset_state(state);
549 flags = 0;
550 data = "<yin-element value=\"invalid\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200551 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
552 yin_load_attributes(st->yin_ctx, &data, &args);
553 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
David Sedlák2721d3d2019-06-21 15:37:41 +0200554 assert_int_equal(ret, LY_EVALID);
555 LY_ARRAY_FREE(args);
556 args = NULL;
557
558 st->finished_correctly = true;
559}
560
David Sedlákb1a78352019-06-28 16:16:29 +0200561static void
562test_yin_parse_element_generic(void **state)
563{
564 const char *prefix, *name;
565 struct state *st = *state;
566 struct lysp_ext_instance exts;
567 size_t prefix_len, name_len;
568 LY_ERR ret;
569
570 memset(&exts, 0, sizeof(exts));
571
572 const char *data = "<elem attr=\"value\">text_value</elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200573 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
574 ret = yin_parse_element_generic(st->yin_ctx, name, name_len, prefix, prefix_len, &data, &exts.child);
David Sedlákb1a78352019-06-28 16:16:29 +0200575 assert_int_equal(ret, LY_SUCCESS);
576 assert_string_equal(exts.child->stmt, "elem");
577 assert_string_equal(exts.child->arg, "text_value");
David Sedlákb1a78352019-06-28 16:16:29 +0200578 assert_string_equal(exts.child->child->stmt, "attr");
579 assert_string_equal(exts.child->child->arg, "value");
580 assert_true(exts.child->child->flags & LYS_YIN_ATTR);
David Sedlákb1a78352019-06-28 16:16:29 +0200581 lysp_ext_instance_free(st->ctx, &exts);
David Sedlák5392a212019-07-01 09:19:10 +0200582 st = reset_state(state);
583
584 data = "<elem></elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200585 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
586 ret = yin_parse_element_generic(st->yin_ctx, name, name_len, prefix, prefix_len, &data, &exts.child);
David Sedlák5392a212019-07-01 09:19:10 +0200587 assert_int_equal(ret, LY_SUCCESS);
588 assert_string_equal(exts.child->stmt, "elem");
589 assert_null(exts.child->child);
590 assert_null(exts.child->arg);
David Sedlákda8ffa32019-07-08 14:17:10 +0200591 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák5392a212019-07-01 09:19:10 +0200592 lysp_ext_instance_free(st->ctx, &exts);
593
David Sedlákb1a78352019-06-28 16:16:29 +0200594 st->finished_correctly = true;
595}
596
597static void
598test_yin_parse_extension_instance(void **state)
599{
600 LY_ERR ret;
601 struct state *st = *state;
602 const char *prefix, *name;
603 size_t prefix_len, name_len;
604 struct yin_arg_record *args = NULL;
605 struct lysp_ext_instance *exts = NULL;
David Sedlákb1a78352019-06-28 16:16:29 +0200606 const char *data = "<ext value1=\"test\" value=\"test2\"><subelem>text</subelem></ext>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200607 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
608 yin_load_attributes(st->yin_ctx, &data, &args);
609 ret = yin_parse_extension_instance(st->yin_ctx, &args, &data, name2fullname(name, prefix_len),
David Sedlák619db942019-07-03 14:47:30 +0200610 namelen2fulllen(name_len, prefix_len), LYEXT_SUBSTMT_CONTACT, 0, &exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200611 assert_int_equal(ret, LY_SUCCESS);
612 assert_string_equal(exts->name, "ext");
613 assert_int_equal(exts->insubstmt_index, 0);
614 assert_true(exts->insubstmt == LYEXT_SUBSTMT_CONTACT);
615 assert_true(exts->yin & LYS_YIN);
616 assert_string_equal(exts->child->stmt, "value1");
617 assert_string_equal(exts->child->arg, "test");
618 assert_null(exts->child->child);
619 assert_true(exts->child->flags & LYS_YIN_ATTR);
620 assert_string_equal(exts->child->next->stmt, "value");
621 assert_string_equal(exts->child->next->arg, "test2");
622 assert_null(exts->child->next->child);
623 assert_true(exts->child->next->flags & LYS_YIN_ATTR);
624
625 assert_string_equal(exts->child->next->next->stmt, "subelem");
626 assert_string_equal(exts->child->next->next->arg, "text");
627 assert_null(exts->child->next->next->child);
628 assert_null(exts->child->next->next->next);
629 assert_false(exts->child->next->next->flags & LYS_YIN_ATTR);
David Sedlákda8ffa32019-07-08 14:17:10 +0200630 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb1a78352019-06-28 16:16:29 +0200631 LY_ARRAY_FREE(args);
632 lysp_ext_instance_free(st->ctx, exts);
633 LY_ARRAY_FREE(exts);
David Sedlákf250ecf2019-07-01 11:02:05 +0200634 exts = NULL;
635 args = NULL;
636 st = reset_state(state);
637
638 data = "<extension-elem />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200639 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
640 yin_load_attributes(st->yin_ctx, &data, &args);
641 ret = yin_parse_extension_instance(st->yin_ctx, &args, &data, name, name_len, LYEXT_SUBSTMT_CONTACT, 0, &exts);
David Sedlákf250ecf2019-07-01 11:02:05 +0200642 assert_int_equal(ret, LY_SUCCESS);
643 assert_string_equal(exts->name, "extension-elem");
644 assert_null(exts->argument);
645 assert_null(exts->child);
646 assert_int_equal(exts->insubstmt, LYEXT_SUBSTMT_CONTACT);
647 assert_int_equal(exts->insubstmt_index, 0);
648 assert_true(exts->yin & LYS_YIN);
David Sedlákda8ffa32019-07-08 14:17:10 +0200649 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákf250ecf2019-07-01 11:02:05 +0200650 LY_ARRAY_FREE(args);
651 lysp_ext_instance_free(st->ctx, exts);
652 LY_ARRAY_FREE(exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200653 st->finished_correctly = true;
654}
655
David Sedlák555c7202019-07-04 12:14:12 +0200656static void
657test_yin_parse_content(void **state)
658{
659 struct state *st = *state;
660 LY_ERR ret = LY_SUCCESS;
661 struct sized_string name, prefix;
662 const char *data = "<prefix value=\"a_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
663 "<custom xmlns=\"my-ext\">"
664 "totally amazing extension"
665 "</custom>"
David Sedlák986cb412019-07-04 13:10:11 +0200666 "<extension name=\"ext\">"
667 "<argument name=\"argname\"></argument>"
668 "<description><text>desc</text></description>"
669 "<reference><text>ref</text></reference>"
670 "<status value=\"deprecated\"></status>"
671 "</extension>"
David Sedlák555c7202019-07-04 12:14:12 +0200672 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
David Sedlák5f8191e2019-07-08 16:35:52 +0200673 "<if-feature value=\"foo\"></if-feature>"
David Sedlák555c7202019-07-04 12:14:12 +0200674 "</prefix>";
675 struct lysp_ext_instance *exts = NULL;
David Sedlák5f8191e2019-07-08 16:35:52 +0200676 const char **if_features = NULL;
David Sedlák555c7202019-07-04 12:14:12 +0200677 struct yin_arg_record *attrs = NULL;
678 const char *value;
David Sedlák986cb412019-07-04 13:10:11 +0200679 struct lysp_ext *ext_def = NULL;
David Sedlák555c7202019-07-04 12:14:12 +0200680
David Sedlákda8ffa32019-07-08 14:17:10 +0200681 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
682 yin_load_attributes(st->yin_ctx, &data, &attrs);
David Sedlák555c7202019-07-04 12:14:12 +0200683
David Sedlák5f8191e2019-07-08 16:35:52 +0200684 struct yin_subelement subelems[4] = {{YANG_EXTENSION, &ext_def, 0},
685 {YANG_IF_FEATURE, &if_features, 0},
David Sedlákb0faad82019-07-04 14:28:59 +0200686 {YANG_CUSTOM, NULL, 0},
687 {YIN_TEXT, &value, 0}};
David Sedlák5f8191e2019-07-08 16:35:52 +0200688 ret = yin_parse_content(st->yin_ctx, subelems, 4, &data, YANG_PREFIX, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200689 assert_int_equal(ret, LY_SUCCESS);
690 assert_string_equal(exts->name, "custom");
691 assert_string_equal(exts->argument, "totally amazing extension");
692 assert_string_equal(value, "wsefsdf");
693 lysp_ext_instance_free(st->ctx, exts);
David Sedlák986cb412019-07-04 13:10:11 +0200694 lysp_ext_free(st->ctx, ext_def);
David Sedlák5f8191e2019-07-08 16:35:52 +0200695 FREE_STRING(st->ctx, *if_features);
696 LY_ARRAY_FREE(if_features);
David Sedlák555c7202019-07-04 12:14:12 +0200697 LY_ARRAY_FREE(exts);
David Sedlák986cb412019-07-04 13:10:11 +0200698 LY_ARRAY_FREE(ext_def);
David Sedlák555c7202019-07-04 12:14:12 +0200699 LY_ARRAY_FREE(attrs);
700 attrs = NULL;
701 lydict_remove(st->ctx, value);
702 st = reset_state(state);
703
704 /* test unique subelem */
705 const char *prefix_value;
706 struct yin_subelement subelems2[2] = {{YANG_PREFIX, &prefix_value, 0},
707 {YIN_TEXT, &value, YIN_SUBELEM_UNIQUE}};
708 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
709 "<prefix value=\"inv_mod\" />"
710 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
711 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
712 "</module>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200713 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
714 yin_load_attributes(st->yin_ctx, &data, &attrs);
715 ret = yin_parse_content(st->yin_ctx, subelems2, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200716 assert_int_equal(ret, LY_EVALID);
717 logbuf_assert("Redefinition of text element in module element. Line number 1.");
718 lydict_remove(st->ctx, prefix_value);
719 lydict_remove(st->ctx, value);
720 st = reset_state(state);
721 LY_ARRAY_FREE(attrs);
722 attrs = NULL;
723
724 /* test first subelem */
725 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
726 "<prefix value=\"inv_mod\" />"
727 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
728 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
729 "</module>";
730 struct yin_subelement subelems3[2] = {{YANG_PREFIX, &prefix_value, 0},
731 {YIN_TEXT, &value, YIN_SUBELEM_FIRST}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200732 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
733 yin_load_attributes(st->yin_ctx, &data, &attrs);
734 ret = yin_parse_content(st->yin_ctx, subelems3, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200735 assert_int_equal(ret, LY_EVALID);
736 logbuf_assert("Subelement text of module element must be defined as first subelement. Line number 1.");
737 lydict_remove(st->ctx, prefix_value);
738 st = reset_state(state);
739 LY_ARRAY_FREE(attrs);
740 attrs = NULL;
741
742 /* test mandatory subelem */
743 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
744 "</module>";
745 struct yin_subelement subelems4[1] = {{YANG_PREFIX, &prefix_value, YIN_SUBELEM_MANDATORY}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200746 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
747 yin_load_attributes(st->yin_ctx, &data, &attrs);
748 ret = yin_parse_content(st->yin_ctx, subelems4, 1, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200749 assert_int_equal(ret, LY_EVALID);
750 logbuf_assert("Missing mandatory subelement prefix of module element. Line number 1.");
751 LY_ARRAY_FREE(attrs);
752
753 st->finished_correctly = true;
754}
755
David Sedlák3b4db242018-10-19 16:11:01 +0200756int
757main(void)
758{
759
760 const struct CMUnitTest tests[] = {
David Sedlák392af4f2019-06-04 16:02:42 +0200761 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_f, teardown_f),
David Sedlák68a1af12019-03-08 13:46:54 +0100762 cmocka_unit_test_setup_teardown(test_meta, setup_f, teardown_f),
David Sedlákda63c082019-06-04 13:52:23 +0200763 cmocka_unit_test_setup_teardown(test_yin_parse_import, setup_f, teardown_f),
David Sedlákb6e65972019-06-19 10:44:13 +0200764 cmocka_unit_test_setup_teardown(test_yin_parse_status, setup_f, teardown_f),
David Sedlák8f7a1172019-06-20 14:42:18 +0200765 cmocka_unit_test_setup_teardown(test_yin_match_keyword, setup_f, teardown_f),
David Sedlák554e36d2019-06-20 16:00:04 +0200766 cmocka_unit_test_setup_teardown(test_yin_parse_extension, setup_f, teardown_f),
David Sedlák2721d3d2019-06-21 15:37:41 +0200767 cmocka_unit_test_setup_teardown(test_yin_parse_yin_element_element, setup_f, teardown_f),
David Sedlákb1a78352019-06-28 16:16:29 +0200768 cmocka_unit_test_setup_teardown(test_yin_parse_element_generic, setup_f, teardown_f),
769 cmocka_unit_test_setup_teardown(test_yin_parse_extension_instance, setup_f, teardown_f),
David Sedlák555c7202019-07-04 12:14:12 +0200770 cmocka_unit_test_setup_teardown(test_yin_parse_content, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200771 cmocka_unit_test(test_yin_match_argument_name),
David Sedlák3b4db242018-10-19 16:11:01 +0200772 };
773
774 return cmocka_run_group_tests(tests, NULL, NULL);
775}