blob: 761cd93703c3f19c223bea9f68930219b15193c9 [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ák68a1af12019-03-08 13:46:54 +010030struct state {
David Sedlák3b4db242018-10-19 16:11:01 +020031 struct ly_ctx *ctx;
David Sedlák3017da42019-02-15 09:48:04 +010032 struct lys_module *mod;
David Sedlák8f5bce02019-06-03 16:41:08 +020033 struct lyxml_context *xml_ctx;
David Sedlák79e50cb2019-06-05 16:33:09 +020034 bool finished_correctly;
David Sedlák68a1af12019-03-08 13:46:54 +010035};
David Sedlák872c7b42018-10-26 13:15:20 +020036
David Sedlák79e50cb2019-06-05 16:33:09 +020037#define BUFSIZE 1024
38char logbuf[BUFSIZE] = {0};
39int store = -1; /* negative for infinite logging, positive for limited logging */
40
41/* set to 0 to printing error messages to stderr instead of checking them in code */
42#define ENABLE_LOGGER_CHECKING 1
43
44#if ENABLE_LOGGER_CHECKING
45static void
46logger(LY_LOG_LEVEL level, const char *msg, const char *path)
47{
48 (void) level; /* unused */
49 if (store) {
50 if (path && path[0]) {
51 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
52 } else {
53 strncpy(logbuf, msg, BUFSIZE - 1);
54 }
55 if (store > 0) {
56 --store;
57 }
58 }
59}
60#endif
61
62#if ENABLE_LOGGER_CHECKING
63# define logbuf_assert(str) assert_string_equal(logbuf, str)
64#else
65# define logbuf_assert(str)
66#endif
67
68#define TEST_DUP_GENERIC(PREFIX, MEMBER, VALUE1, VALUE2, FUNC, RESULT, LINE, CLEANUP) \
69 str = PREFIX MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
70 assert_int_equal(LY_EVALID, FUNC(&ctx, &str, RESULT)); \
71 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
72 CLEANUP
73
74
David Sedlák68a1af12019-03-08 13:46:54 +010075static int
76setup_f(void **state)
77{
78 struct state *st = NULL;
David Sedlák3b4db242018-10-19 16:11:01 +020079
David Sedlák79e50cb2019-06-05 16:33:09 +020080#if ENABLE_LOGGER_CHECKING
81 /* setup logger */
82 ly_set_log_clb(logger, 1);
83#endif
84
David Sedlák68a1af12019-03-08 13:46:54 +010085 /* allocate state variable */
86 (*state) = st = calloc(1, sizeof(*st));
87 if (!st) {
88 fprintf(stderr, "Memmory allocation failed");
89 return EXIT_FAILURE;
90 }
David Sedlák872c7b42018-10-26 13:15:20 +020091
David Sedlák68a1af12019-03-08 13:46:54 +010092 /* create new libyang context */
93 ly_ctx_new(NULL, 0, &st->ctx);
David Sedlák872c7b42018-10-26 13:15:20 +020094
David Sedlák68a1af12019-03-08 13:46:54 +010095 /* allocate new module */
96 st->mod = calloc(1, sizeof(*st->mod));
97 st->mod->ctx = st->ctx;
98
David Sedlák8f5bce02019-06-03 16:41:08 +020099 st->xml_ctx = calloc(1, sizeof(struct lys_parser_ctx));
100 st->xml_ctx->ctx = st->ctx;
101 st->xml_ctx->line = 1;
102
David Sedlák68a1af12019-03-08 13:46:54 +0100103 return EXIT_SUCCESS;
David Sedlák3b4db242018-10-19 16:11:01 +0200104}
105
106static int
David Sedlák68a1af12019-03-08 13:46:54 +0100107teardown_f(void **state)
108{
109 struct state *st = *(struct state **)state;
110
David Sedlák79e50cb2019-06-05 16:33:09 +0200111#if ENABLE_LOGGER_CHECKING
112 /* teardown logger */
113 if (!st->finished_correctly && logbuf[0] != '\0') {
114 fprintf(stderr, "%s\n", logbuf);
115 }
116#endif
117
David Sedlák8f5bce02019-06-03 16:41:08 +0200118 lyxml_context_clear(st->xml_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100119 lys_module_free(st->mod, NULL);
120 ly_ctx_destroy(st->ctx, NULL);
David Sedlák8f5bce02019-06-03 16:41:08 +0200121 free(st->xml_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100122 free(st);
123
124 return EXIT_SUCCESS;
125}
126
David Sedlák392af4f2019-06-04 16:02:42 +0200127static struct state*
128reset_state(void **state)
129{
David Sedlák79e50cb2019-06-05 16:33:09 +0200130 ((struct state *)*state)->finished_correctly = true;
David Sedlák392af4f2019-06-04 16:02:42 +0200131 teardown_f(state);
132 setup_f(state);
133
134 return *state;
135}
136
David Sedlák79e50cb2019-06-05 16:33:09 +0200137void
138logbuf_clean(void)
139{
140 logbuf[0] = '\0';
141}
142
David Sedlák68a1af12019-03-08 13:46:54 +0100143static void
David Sedlák392af4f2019-06-04 16:02:42 +0200144test_yin_parse_module(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +0100145{
146 LY_ERR ret = LY_SUCCESS;
147 struct state *st = *state;
148
149 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200150 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
151 name=\"example-foo\"\
David Sedlák18730132019-03-15 15:51:34 +0100152 xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
153 xmlns:foo=\"urn:example:foo\"\
154 xmlns:myext=\"urn:example:extensions\">\
David Sedlákcd0c9512019-03-29 13:23:06 +0100155 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedláka7406952019-04-05 10:33:07 +0200156 <prefix xmlns:myxt=\"urn:emple:extensions\" value=\"foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlákd9d3a312019-06-04 09:47:10 +0200157 </module>",
David Sedlák68a1af12019-03-08 13:46:54 +0100158 st->mod);
159
160 assert_int_equal(ret, LY_SUCCESS);
161 assert_string_equal(st->mod->parsed->mod->name, "example-foo");
162 assert_string_equal(st->mod->parsed->mod->prefix, "foo");
David Sedlákcd0c9512019-03-29 13:23:06 +0100163 assert_string_equal(st->mod->parsed->mod->ns, "urn:example:foo");
David Sedlák392af4f2019-06-04 16:02:42 +0200164
165 st = reset_state(state);
166 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200167 "<module name=\"example-foo\">\
168 <invalid-tag uri=\"urn:example:foo\"\"/>\
169 </module>",
170 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200171 assert_int_equal(ret, LY_EVALID);
172
173 st = reset_state(state);
174 ret = yin_parse_module(st->ctx,
David Sedlák8f7a1172019-06-20 14:42:18 +0200175 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák57715b12019-06-17 13:05:22 +0200176 </module>",
David Sedlák2b214ac2019-06-06 16:11:03 +0200177 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200178 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200179 logbuf_assert("Missing argument name of a module Line number 1.");
David Sedlák392af4f2019-06-04 16:02:42 +0200180
181 st = reset_state(state);
182 ret = yin_parse_module(st->ctx,
183 "",
184 st->mod);
185 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200186 logbuf_assert("Invalid keyword \"(null)\", expected \"module\" or \"submodule\". Line number 1.");
187 st->finished_correctly = true;
David Sedlák3b4db242018-10-19 16:11:01 +0200188}
189
190static void
David Sedlák1bccdfa2019-06-17 15:55:27 +0200191test_yin_match_keyword(void **state)
David Sedlák3b4db242018-10-19 16:11:01 +0200192{
David Sedlák8f7a1172019-06-20 14:42:18 +0200193 struct state *st = *state;
David Sedlák3b4db242018-10-19 16:11:01 +0200194
David Sedlák8f7a1172019-06-20 14:42:18 +0200195 const char *prefix, *name;
196 struct yin_arg_record *args = NULL;
197 size_t prefix_len, name_len;
198 /* create mock yin namespace in xml context */
199 const char *data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" />";
200 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
201 yin_load_attributes(st->xml_ctx, &data, &args);
202 LY_ARRAY_FREE(args);
203
204 assert_int_equal(yin_match_keyword(st->xml_ctx, "anydatax", strlen("anydatax"), prefix, prefix_len), YANG_NONE);
205 assert_int_equal(yin_match_keyword(st->xml_ctx, "asdasd", strlen("asdasd"), prefix, prefix_len), YANG_NONE);
206 assert_int_equal(yin_match_keyword(st->xml_ctx, "", 0, prefix, prefix_len), YANG_NONE);
207 assert_int_equal(yin_match_keyword(st->xml_ctx, "anydata", strlen("anydata"), prefix, prefix_len), YANG_ANYDATA);
208 assert_int_equal(yin_match_keyword(st->xml_ctx, "anyxml", strlen("anyxml"), prefix, prefix_len), YANG_ANYXML);
209 assert_int_equal(yin_match_keyword(st->xml_ctx, "argument", strlen("argument"), prefix, prefix_len), YANG_ARGUMENT);
210 assert_int_equal(yin_match_keyword(st->xml_ctx, "augment", strlen("augment"), prefix, prefix_len), YANG_AUGMENT);
211 assert_int_equal(yin_match_keyword(st->xml_ctx, "base", strlen("base"), prefix, prefix_len), YANG_BASE);
212 assert_int_equal(yin_match_keyword(st->xml_ctx, "belongs-to", strlen("belongs-to"), prefix, prefix_len), YANG_BELONGS_TO);
213 assert_int_equal(yin_match_keyword(st->xml_ctx, "bit", strlen("bit"), prefix, prefix_len), YANG_BIT);
214 assert_int_equal(yin_match_keyword(st->xml_ctx, "case", strlen("case"), prefix, prefix_len), YANG_CASE);
215 assert_int_equal(yin_match_keyword(st->xml_ctx, "choice", strlen("choice"), prefix, prefix_len), YANG_CHOICE);
216 assert_int_equal(yin_match_keyword(st->xml_ctx, "config", strlen("config"), prefix, prefix_len), YANG_CONFIG);
217 assert_int_equal(yin_match_keyword(st->xml_ctx, "contact", strlen("contact"), prefix, prefix_len), YANG_CONTACT);
218 assert_int_equal(yin_match_keyword(st->xml_ctx, "container", strlen("container"), prefix, prefix_len), YANG_CONTAINER);
219 assert_int_equal(yin_match_keyword(st->xml_ctx, "default", strlen("default"), prefix, prefix_len), YANG_DEFAULT);
220 assert_int_equal(yin_match_keyword(st->xml_ctx, "description", strlen("description"), prefix, prefix_len), YANG_DESCRIPTION);
221 assert_int_equal(yin_match_keyword(st->xml_ctx, "deviate", strlen("deviate"), prefix, prefix_len), YANG_DEVIATE);
222 assert_int_equal(yin_match_keyword(st->xml_ctx, "deviation", strlen("deviation"), prefix, prefix_len), YANG_DEVIATION);
223 assert_int_equal(yin_match_keyword(st->xml_ctx, "enum", strlen("enum"), prefix, prefix_len), YANG_ENUM);
224 assert_int_equal(yin_match_keyword(st->xml_ctx, "error-app-tag", strlen("error-app-tag"), prefix, prefix_len), YANG_ERROR_APP_TAG);
225 assert_int_equal(yin_match_keyword(st->xml_ctx, "error-message", strlen("error-message"), prefix, prefix_len), YANG_ERROR_MESSAGE);
226 assert_int_equal(yin_match_keyword(st->xml_ctx, "extension", strlen("extension"), prefix, prefix_len), YANG_EXTENSION);
227 assert_int_equal(yin_match_keyword(st->xml_ctx, "feature", strlen("feature"), prefix, prefix_len), YANG_FEATURE);
228 assert_int_equal(yin_match_keyword(st->xml_ctx, "fraction-digits", strlen("fraction-digits"), prefix, prefix_len), YANG_FRACTION_DIGITS);
229 assert_int_equal(yin_match_keyword(st->xml_ctx, "grouping", strlen("grouping"), prefix, prefix_len), YANG_GROUPING);
230 assert_int_equal(yin_match_keyword(st->xml_ctx, "identity", strlen("identity"), prefix, prefix_len), YANG_IDENTITY);
231 assert_int_equal(yin_match_keyword(st->xml_ctx, "if-feature", strlen("if-feature"), prefix, prefix_len), YANG_IF_FEATURE);
232 assert_int_equal(yin_match_keyword(st->xml_ctx, "import", strlen("import"), prefix, prefix_len), YANG_IMPORT);
233 assert_int_equal(yin_match_keyword(st->xml_ctx, "include", strlen("include"), prefix, prefix_len), YANG_INCLUDE);
234 assert_int_equal(yin_match_keyword(st->xml_ctx, "input", strlen("input"), prefix, prefix_len), YANG_INPUT);
235 assert_int_equal(yin_match_keyword(st->xml_ctx, "key", strlen("key"), prefix, prefix_len), YANG_KEY);
236 assert_int_equal(yin_match_keyword(st->xml_ctx, "leaf", strlen("leaf"), prefix, prefix_len), YANG_LEAF);
237 assert_int_equal(yin_match_keyword(st->xml_ctx, "leaf-list", strlen("leaf-list"), prefix, prefix_len), YANG_LEAF_LIST);
238 assert_int_equal(yin_match_keyword(st->xml_ctx, "length", strlen("length"), prefix, prefix_len), YANG_LENGTH);
239 assert_int_equal(yin_match_keyword(st->xml_ctx, "list", strlen("list"), prefix, prefix_len), YANG_LIST);
240 assert_int_equal(yin_match_keyword(st->xml_ctx, "mandatory", strlen("mandatory"), prefix, prefix_len), YANG_MANDATORY);
241 assert_int_equal(yin_match_keyword(st->xml_ctx, "max-elements", strlen("max-elements"), prefix, prefix_len), YANG_MAX_ELEMENTS);
242 assert_int_equal(yin_match_keyword(st->xml_ctx, "min-elements", strlen("min-elements"), prefix, prefix_len), YANG_MIN_ELEMENTS);
243 assert_int_equal(yin_match_keyword(st->xml_ctx, "modifier", strlen("modifier"), prefix, prefix_len), YANG_MODIFIER);
244 assert_int_equal(yin_match_keyword(st->xml_ctx, "module", strlen("module"), prefix, prefix_len), YANG_MODULE);
245 assert_int_equal(yin_match_keyword(st->xml_ctx, "must", strlen("must"), prefix, prefix_len), YANG_MUST);
246 assert_int_equal(yin_match_keyword(st->xml_ctx, "namespace", strlen("namespace"), prefix, prefix_len), YANG_NAMESPACE);
247 assert_int_equal(yin_match_keyword(st->xml_ctx, "notification", strlen("notification"), prefix, prefix_len), YANG_NOTIFICATION);
248 assert_int_equal(yin_match_keyword(st->xml_ctx, "ordered-by", strlen("ordered-by"), prefix, prefix_len), YANG_ORDERED_BY);
249 assert_int_equal(yin_match_keyword(st->xml_ctx, "organization", strlen("organization"), prefix, prefix_len), YANG_ORGANIZATION);
250 assert_int_equal(yin_match_keyword(st->xml_ctx, "output", strlen("output"), prefix, prefix_len), YANG_OUTPUT);
251 assert_int_equal(yin_match_keyword(st->xml_ctx, "path", strlen("path"), prefix, prefix_len), YANG_PATH);
252 assert_int_equal(yin_match_keyword(st->xml_ctx, "pattern", strlen("pattern"), prefix, prefix_len), YANG_PATTERN);
253 assert_int_equal(yin_match_keyword(st->xml_ctx, "position", strlen("position"), prefix, prefix_len), YANG_POSITION);
254 assert_int_equal(yin_match_keyword(st->xml_ctx, "prefix", strlen("prefix"), prefix, prefix_len), YANG_PREFIX);
255 assert_int_equal(yin_match_keyword(st->xml_ctx, "presence", strlen("presence"), prefix, prefix_len), YANG_PRESENCE);
256 assert_int_equal(yin_match_keyword(st->xml_ctx, "range", strlen("range"), prefix, prefix_len), YANG_RANGE);
257 assert_int_equal(yin_match_keyword(st->xml_ctx, "reference", strlen("reference"), prefix, prefix_len), YANG_REFERENCE);
258 assert_int_equal(yin_match_keyword(st->xml_ctx, "refine", strlen("refine"), prefix, prefix_len), YANG_REFINE);
259 assert_int_equal(yin_match_keyword(st->xml_ctx, "require-instance", strlen("require-instance"), prefix, prefix_len), YANG_REQUIRE_INSTANCE);
260 assert_int_equal(yin_match_keyword(st->xml_ctx, "revision", strlen("revision"), prefix, prefix_len), YANG_REVISION);
261 assert_int_equal(yin_match_keyword(st->xml_ctx, "revision-date", strlen("revision-date"), prefix, prefix_len), YANG_REVISION_DATE);
262 assert_int_equal(yin_match_keyword(st->xml_ctx, "rpc", strlen("rpc"), prefix, prefix_len), YANG_RPC);
263 assert_int_equal(yin_match_keyword(st->xml_ctx, "status", strlen("status"), prefix, prefix_len), YANG_STATUS);
264 assert_int_equal(yin_match_keyword(st->xml_ctx, "submodule", strlen("submodule"), prefix, prefix_len), YANG_SUBMODULE);
265 assert_int_equal(yin_match_keyword(st->xml_ctx, "type", strlen("type"), prefix, prefix_len), YANG_TYPE);
266 assert_int_equal(yin_match_keyword(st->xml_ctx, "typedef", strlen("typedef"), prefix, prefix_len), YANG_TYPEDEF);
267 assert_int_equal(yin_match_keyword(st->xml_ctx, "unique", strlen("unique"), prefix, prefix_len), YANG_UNIQUE);
268 assert_int_equal(yin_match_keyword(st->xml_ctx, "units", strlen("units"), prefix, prefix_len), YANG_UNITS);
269 assert_int_equal(yin_match_keyword(st->xml_ctx, "uses", strlen("uses"), prefix, prefix_len), YANG_USES);
270 assert_int_equal(yin_match_keyword(st->xml_ctx, "value", strlen("value"), prefix, prefix_len), YANG_VALUE);
271 assert_int_equal(yin_match_keyword(st->xml_ctx, "when", strlen("when"), prefix, prefix_len), YANG_WHEN);
272 assert_int_equal(yin_match_keyword(st->xml_ctx, "yang-version", strlen("yang-version"), prefix, prefix_len), YANG_YANG_VERSION);
273 assert_int_equal(yin_match_keyword(st->xml_ctx, "yin-element", strlen("yin-element"), prefix, prefix_len), YANG_YIN_ELEMENT);
274
275 st->finished_correctly = true;
David Sedlák872c7b42018-10-26 13:15:20 +0200276}
David Sedlák3b4db242018-10-19 16:11:01 +0200277
David Sedlák872c7b42018-10-26 13:15:20 +0200278static void
David Sedlák060b00e2019-06-19 11:12:06 +0200279test_yin_match_argument_name(void **state)
David Sedlák872c7b42018-10-26 13:15:20 +0200280{
David Sedlák68a1af12019-03-08 13:46:54 +0100281 (void)state; /* unused */
David Sedlák872c7b42018-10-26 13:15:20 +0200282
David Sedlák060b00e2019-06-19 11:12:06 +0200283 assert_int_equal(yin_match_argument_name("", 5), YIN_ARG_UNKNOWN);
284 assert_int_equal(yin_match_argument_name("qwertyasd", 5), YIN_ARG_UNKNOWN);
285 assert_int_equal(yin_match_argument_name("conditionasd", 8), YIN_ARG_UNKNOWN);
286 assert_int_equal(yin_match_argument_name("condition", 9), YIN_ARG_CONDITION);
287 assert_int_equal(yin_match_argument_name("date", 4), YIN_ARG_DATE);
288 assert_int_equal(yin_match_argument_name("module", 6), YIN_ARG_MODULE);
289 assert_int_equal(yin_match_argument_name("name", 4), YIN_ARG_NAME);
290 assert_int_equal(yin_match_argument_name("tag", 3), YIN_ARG_TAG);
291 assert_int_equal(yin_match_argument_name("target-node", 11), YIN_ARG_TARGET_NODE);
292 assert_int_equal(yin_match_argument_name("text", 4), YIN_ARG_TEXT);
293 assert_int_equal(yin_match_argument_name("uri", 3), YIN_ARG_URI);
294 assert_int_equal(yin_match_argument_name("value", 5), YIN_ARG_VALUE);
David Sedlák3b4db242018-10-19 16:11:01 +0200295}
296
David Sedlák68a1af12019-03-08 13:46:54 +0100297static void
298test_meta(void **state)
299{
300 LY_ERR ret = LY_SUCCESS;
301 struct state *st = *state;
302
David Sedlák2b214ac2019-06-06 16:11:03 +0200303 ret = yin_parse_module(st->ctx,"<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
304 name=\"example-foo\">\
David Sedlák15a92662019-06-18 11:55:15 +0200305 <organization xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"><text>organization...</text></organization>\
306 <contact><text>contact...</text></contact>\
307 <description><text>description...</text></description>\
308 <reference><text>reference...</text></reference>\
David Sedlák68a1af12019-03-08 13:46:54 +0100309 </module>", st->mod);
310
311 assert_int_equal(ret, LY_SUCCESS);
David Sedláka7406952019-04-05 10:33:07 +0200312 assert_string_equal(st->mod->parsed->mod->org, "organization...");
David Sedlák68a1af12019-03-08 13:46:54 +0100313 assert_string_equal(st->mod->parsed->mod->contact, "contact...");
314 assert_string_equal(st->mod->parsed->mod->dsc, "description...");
315 assert_string_equal(st->mod->parsed->mod->ref, "reference...");
David Sedlák68826732019-06-05 10:50:58 +0200316
317 st = reset_state(state);
318 ret = yin_parse_module(st->ctx,"<module name=\"example-foo\">\
319 <organization test=\"invalid-argument\">organization...</organization>\
320 </module>", st->mod);
321 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200322
323 st->finished_correctly = true;
David Sedlák68a1af12019-03-08 13:46:54 +0100324}
325
David Sedlák8f5bce02019-06-03 16:41:08 +0200326static void
David Sedlák060b00e2019-06-19 11:12:06 +0200327test_yin_parse_text_element(void **state)
David Sedlák8f5bce02019-06-03 16:41:08 +0200328{
329 struct state *st = *state;
330 const char *res = NULL, *prefix = NULL, *name = NULL;
331 size_t prefix_len = 0, name_len = 0;
332 LY_ERR ret = LY_SUCCESS;
David Sedlák8f7a1172019-06-20 14:42:18 +0200333 struct yin_arg_record *args = NULL;
David Sedlák8f5bce02019-06-03 16:41:08 +0200334
335 const char *data = "<elem>content</elem>";
336 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200337 yin_load_attributes(st->xml_ctx, &data, &args);
David Sedlák00250342019-06-21 14:19:39 +0200338 ret = yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák4af339b2019-06-24 15:37:29 +0200339 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák00250342019-06-21 14:19:39 +0200340 assert_int_equal(ret, LY_SUCCESS);
David Sedlák8f5bce02019-06-03 16:41:08 +0200341 assert_string_equal(res, "content");
342 lydict_remove(st->ctx, "content");
David Sedlák15a92662019-06-18 11:55:15 +0200343 st = reset_state(state);
David Sedlák8f7a1172019-06-20 14:42:18 +0200344 LY_ARRAY_FREE(args);
345 args = NULL;
David Sedlák8f5bce02019-06-03 16:41:08 +0200346
David Sedlák8f5bce02019-06-03 16:41:08 +0200347 data = "<elem xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">another-content</elem>";
348 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200349 yin_load_attributes(st->xml_ctx, &data, &args);
David Sedlák00250342019-06-21 14:19:39 +0200350 ret = yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák4af339b2019-06-24 15:37:29 +0200351 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák00250342019-06-21 14:19:39 +0200352 assert_int_equal(ret, LY_SUCCESS);
David Sedlák8f5bce02019-06-03 16:41:08 +0200353 assert_string_equal(res, "another-content");
354 lydict_remove(st->ctx, "another-content");
David Sedlák15a92662019-06-18 11:55:15 +0200355 st = reset_state(state);
David Sedlák8f7a1172019-06-20 14:42:18 +0200356 LY_ARRAY_FREE(args);
357 args = NULL;
David Sedlák8f5bce02019-06-03 16:41:08 +0200358
David Sedlák00250342019-06-21 14:19:39 +0200359 data = "<elem unknown=\"unknown\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">text</elem>";
David Sedlák8f5bce02019-06-03 16:41:08 +0200360 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200361 yin_load_attributes(st->xml_ctx, &data, &args);
362 ret = yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák4af339b2019-06-24 15:37:29 +0200363 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák00250342019-06-21 14:19:39 +0200364 assert_int_equal(ret, LY_SUCCESS);
365 assert_string_equal(res, "text");
366 lydict_remove(st->ctx, "text");
David Sedlák8f7a1172019-06-20 14:42:18 +0200367 LY_ARRAY_FREE(args);
368 args = NULL;
David Sedlák79e50cb2019-06-05 16:33:09 +0200369
370 st->finished_correctly = true;
David Sedlák8f5bce02019-06-03 16:41:08 +0200371}
372
David Sedlákd9d3a312019-06-04 09:47:10 +0200373static void
David Sedlákda63c082019-06-04 13:52:23 +0200374test_yin_parse_import(void **state)
375{
376 struct state *st = *state;
377 const char *prefix = NULL, *name = NULL;
378 size_t prefix_len = 0, name_len = 0;
379 LY_ERR ret = LY_SUCCESS;
380 struct lysp_import *imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200381 struct yin_arg_record *args = NULL;
David Sedlákda63c082019-06-04 13:52:23 +0200382
David Sedlák2b214ac2019-06-06 16:11:03 +0200383 const char *data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákda63c082019-06-04 13:52:23 +0200384 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200385 <revision-date date=\"2015-01-01\"></revision-date>\
David Sedlákb6e65972019-06-19 10:44:13 +0200386 <description><text>import description</text></description>\
387 <reference><text>import reference</text></reference>\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200388 </import>\
389 \
David Sedlák2b214ac2019-06-06 16:11:03 +0200390 <import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200391 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200392 <revision-date date=\"2015-01-01\" />\
David Sedlákda63c082019-06-04 13:52:23 +0200393 </import>";
David Sedlákb6e65972019-06-19 10:44:13 +0200394 /* first import */
David Sedlákda63c082019-06-04 13:52:23 +0200395 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200396 yin_load_attributes(st->xml_ctx, &data, &args);
397 ret = yin_parse_import(st->xml_ctx, &args, "b-mod", &data, &imports);
David Sedlákda63c082019-06-04 13:52:23 +0200398 assert_int_equal(ret, LY_SUCCESS);
399 assert_string_equal(imports->name, "a");
400 assert_string_equal(imports->prefix, "a_mod");
401 assert_string_equal(imports->rev, "2015-01-01");
David Sedlákb6e65972019-06-19 10:44:13 +0200402 assert_string_equal(imports->dsc, "import description");
403 assert_string_equal(imports->ref, "import reference");
David Sedlákda63c082019-06-04 13:52:23 +0200404 lydict_remove(st->ctx, imports->name);
405 lydict_remove(st->ctx, imports->prefix);
David Sedlákb6e65972019-06-19 10:44:13 +0200406 lydict_remove(st->ctx, imports->dsc);
407 lydict_remove(st->ctx, imports->ref);
David Sedlákda63c082019-06-04 13:52:23 +0200408 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200409 LY_ARRAY_FREE(args);
David Sedlákda63c082019-06-04 13:52:23 +0200410 imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200411 args = NULL;
David Sedlákc67dcaa2019-06-04 14:49:05 +0200412
David Sedlákb6e65972019-06-19 10:44:13 +0200413 /* second invalid import */
David Sedlákda63c082019-06-04 13:52:23 +0200414 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200415 yin_load_attributes(st->xml_ctx, &data, &args);
416 ret = yin_parse_import(st->xml_ctx, &args, "a_mod", &data, &imports);
David Sedlákda63c082019-06-04 13:52:23 +0200417 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200418 logbuf_assert("Prefix \"a_mod\" already used as module prefix. Line number 1.");
David Sedlákb6e65972019-06-19 10:44:13 +0200419 /* cleanup is supposed to be done by caller function */
David Sedlákda63c082019-06-04 13:52:23 +0200420 lydict_remove(st->ctx, imports->name);
421 lydict_remove(st->ctx, imports->prefix);
422 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200423 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200424 imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200425 args = NULL;
426
David Sedlákb6e65972019-06-19 10:44:13 +0200427 st = reset_state(state);
428 /* import with unknown child element */
429 data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
430 <what value=\"a_mod\"/>\
431 </import>";
432 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200433 yin_load_attributes(st->xml_ctx, &data, &args);
434 ret = yin_parse_import(st->xml_ctx, &args, "invalid_mod", &data, &imports);
David Sedlákb6e65972019-06-19 10:44:13 +0200435 assert_int_equal(ret, LY_EVALID);
436 logbuf_assert("Unexpected child element \"what\" of import element.");
437 /* cleanup is supposed to be done by caller function */
438 lydict_remove(st->ctx, imports->name);
439 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200440 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200441
442 st->finished_correctly = true;
443}
444
445static void
446test_yin_parse_status(void **state)
447{
448 struct state *st = *state;
449 const char *prefix = NULL, *name = NULL;
450 size_t prefix_len = 0, name_len = 0;
451 LY_ERR ret = LY_SUCCESS;
452 uint16_t flags = 0;
453 struct lysp_ext_instance *exts;
David Sedlák8f7a1172019-06-20 14:42:18 +0200454 struct yin_arg_record *args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200455
456 /* try all valid values */
457 const char *data = "<status value=\"current\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
458 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200459 yin_load_attributes(st->xml_ctx, &data, &args);
460 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200461 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200462 assert_int_equal(ret, LY_SUCCESS);
463 assert_true(flags & LYS_STATUS_CURR);
David Sedlák8f7a1172019-06-20 14:42:18 +0200464 LY_ARRAY_FREE(args);
465 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200466
467 st = reset_state(state);
468 flags = 0;
469 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
470 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200471 yin_load_attributes(st->xml_ctx, &data, &args);
472 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200473 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200474 assert_int_equal(ret, LY_SUCCESS);
475 assert_true(flags & LYS_STATUS_DEPRC);
David Sedlák8f7a1172019-06-20 14:42:18 +0200476 LY_ARRAY_FREE(args);
477 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200478
479 st = reset_state(state);
480 flags = 0;
481 data = "<status value=\"obsolete\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
482 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200483 yin_load_attributes(st->xml_ctx, &data, &args);
484 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200485 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200486 assert_int_equal(ret, LY_SUCCESS);
487 assert_true(flags & LYS_STATUS_OBSLT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200488 LY_ARRAY_FREE(args);
489 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200490
491 /* duplicit definition (no reset_state() call) */
492 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
493 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200494 yin_load_attributes(st->xml_ctx, &data, &args);
495 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200496 assert_int_equal(ret, LY_EVALID);
497 logbuf_assert("Duplicate element \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200498 LY_ARRAY_FREE(args);
499 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200500
501 /* invalid status value */
502 st = reset_state(state);
503 flags = 0;
504 data = "<status value=\"dunno\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
505 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200506 yin_load_attributes(st->xml_ctx, &data, &args);
507 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200508 assert_int_equal(ret, LY_EVALID);
509 logbuf_assert("Invalid value \"dunno\" of \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200510 LY_ARRAY_FREE(args);
511
David Sedlák79e50cb2019-06-05 16:33:09 +0200512 st->finished_correctly = true;
David Sedlákda63c082019-06-04 13:52:23 +0200513}
514
David Sedlák554e36d2019-06-20 16:00:04 +0200515static void
516test_yin_parse_extension(void **state)
517{
518 struct state *st = *state;
519 const char *prefix = NULL, *name = NULL;
520 size_t prefix_len = 0, name_len = 0;
521 LY_ERR ret = LY_SUCCESS;
522 struct yin_arg_record *args = NULL;
523 struct lysp_ext *exts = NULL, *iter = NULL;
524
525 const char *data = "<extension name=\"b\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák9494eb22019-06-21 16:06:53 +0200526 <argument name=\"argname\"></argument>\
David Sedlák554e36d2019-06-20 16:00:04 +0200527 <description><text>desc</text></description>\
528 <reference><text>ref</text></reference>\
529 <status value=\"deprecated\"></status>\
530 </extension>";
531 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
532 yin_load_attributes(st->xml_ctx, &data, &args);
533 ret = yin_parse_extension(st->xml_ctx, &args, &data, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200534 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák554e36d2019-06-20 16:00:04 +0200535 assert_int_equal(ret, LY_SUCCESS);
536 LY_ARRAY_FOR_ITER(exts, struct lysp_ext, iter) {
537 assert_string_equal(iter->name, "b");
538 assert_string_equal(iter->dsc, "desc");
539 assert_string_equal(iter->ref, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200540 assert_string_equal(iter->argument, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200541 assert_true(iter->flags & LYS_STATUS_DEPRC);
542 }
David Sedlák288c1472019-06-20 16:09:48 +0200543 lydict_remove(st->ctx, "b");
544 lydict_remove(st->ctx, "desc");
545 lydict_remove(st->ctx, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200546 lydict_remove(st->ctx, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200547 LY_ARRAY_FREE(args);
David Sedlák288c1472019-06-20 16:09:48 +0200548 LY_ARRAY_FREE(exts);
David Sedlák554e36d2019-06-20 16:00:04 +0200549 st->finished_correctly = true;
550}
551
David Sedlák2721d3d2019-06-21 15:37:41 +0200552static void
553test_yin_parse_yin_element_element(void **state)
554{
555 struct state *st = *state;
556 const char *prefix = NULL, *name = NULL;
557 size_t prefix_len = 0, name_len = 0;
558 LY_ERR ret = LY_SUCCESS;
559 uint16_t flags = 0;
560 struct lysp_ext *exts;
561 struct yin_arg_record *args = NULL;
562
563 /* try all valid values */
564 const char *data = "<yin-element value=\"true\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
565 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
566 yin_load_attributes(st->xml_ctx, &data, &args);
567 ret = yin_parse_yin_element_element(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200568 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200569 assert_int_equal(ret, LY_SUCCESS);
570 assert_true(flags & LYS_YINELEM_TRUE);
571 LY_ARRAY_FREE(args);
572 args = NULL;
573
574 st = reset_state(state);
575 flags = 0;
576 data = "<yin-element value=\"false\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
577 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
578 yin_load_attributes(st->xml_ctx, &data, &args);
579 ret = yin_parse_yin_element_element(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlák4af339b2019-06-24 15:37:29 +0200580 assert_int_equal(st->xml_ctx->status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200581 assert_int_equal(ret, LY_SUCCESS);
582 assert_true(flags & LYS_YINELEM_FALSE);
583 LY_ARRAY_FREE(args);
584 args = NULL;
585
586 /* invalid value */
587 st = reset_state(state);
588 flags = 0;
589 data = "<yin-element value=\"invalid\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
590 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
591 yin_load_attributes(st->xml_ctx, &data, &args);
592 ret = yin_parse_yin_element_element(st->xml_ctx, &args, &data, &flags, &exts);
593 assert_int_equal(ret, LY_EVALID);
594 LY_ARRAY_FREE(args);
595 args = NULL;
596
597 st->finished_correctly = true;
598}
599
David Sedlák3b4db242018-10-19 16:11:01 +0200600int
601main(void)
602{
603
604 const struct CMUnitTest tests[] = {
David Sedlák392af4f2019-06-04 16:02:42 +0200605 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_f, teardown_f),
David Sedlák68a1af12019-03-08 13:46:54 +0100606 cmocka_unit_test_setup_teardown(test_meta, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200607 cmocka_unit_test_setup_teardown(test_yin_parse_text_element, setup_f, teardown_f),
David Sedlákda63c082019-06-04 13:52:23 +0200608 cmocka_unit_test_setup_teardown(test_yin_parse_import, setup_f, teardown_f),
David Sedlákb6e65972019-06-19 10:44:13 +0200609 cmocka_unit_test_setup_teardown(test_yin_parse_status, setup_f, teardown_f),
David Sedlák8f7a1172019-06-20 14:42:18 +0200610 cmocka_unit_test_setup_teardown(test_yin_match_keyword, setup_f, teardown_f),
David Sedlák554e36d2019-06-20 16:00:04 +0200611 cmocka_unit_test_setup_teardown(test_yin_parse_extension, setup_f, teardown_f),
David Sedlák2721d3d2019-06-21 15:37:41 +0200612 cmocka_unit_test_setup_teardown(test_yin_parse_yin_element_element, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200613 cmocka_unit_test(test_yin_match_argument_name),
David Sedlák3b4db242018-10-19 16:11:01 +0200614 };
615
616 return cmocka_run_group_tests(tests, NULL, NULL);
617}