blob: 7a979e4755b663b3d453efee5b9b2a80601b4b2c [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);
338 yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák8f5bce02019-06-03 16:41:08 +0200339 assert_string_equal(res, "content");
340 lydict_remove(st->ctx, "content");
David Sedlák15a92662019-06-18 11:55:15 +0200341 st = reset_state(state);
David Sedlák8f7a1172019-06-20 14:42:18 +0200342 LY_ARRAY_FREE(args);
343 args = NULL;
David Sedlák8f5bce02019-06-03 16:41:08 +0200344
David Sedlák8f5bce02019-06-03 16:41:08 +0200345 data = "<elem xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">another-content</elem>";
346 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200347 yin_load_attributes(st->xml_ctx, &data, &args);
348 yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák8f5bce02019-06-03 16:41:08 +0200349 assert_string_equal(res, "another-content");
350 lydict_remove(st->ctx, "another-content");
David Sedlák15a92662019-06-18 11:55:15 +0200351 st = reset_state(state);
David Sedlák8f7a1172019-06-20 14:42:18 +0200352 LY_ARRAY_FREE(args);
353 args = NULL;
David Sedlák8f5bce02019-06-03 16:41:08 +0200354
David Sedlák7ff55a92019-06-17 11:11:41 +0200355 data = "<elem invalid=\"invalid\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">text</elem>";
David Sedlák8f5bce02019-06-03 16:41:08 +0200356 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200357 yin_load_attributes(st->xml_ctx, &data, &args);
358 ret = yin_parse_text_element(st->xml_ctx, &args, &data, &res);
David Sedlák8f5bce02019-06-03 16:41:08 +0200359 assert_int_equal(ret, LY_EVALID);
David Sedlák8f7a1172019-06-20 14:42:18 +0200360 LY_ARRAY_FREE(args);
361 args = NULL;
David Sedlák79e50cb2019-06-05 16:33:09 +0200362
363 st->finished_correctly = true;
David Sedlák8f5bce02019-06-03 16:41:08 +0200364}
365
David Sedlákd9d3a312019-06-04 09:47:10 +0200366static void
David Sedlákda63c082019-06-04 13:52:23 +0200367test_yin_parse_import(void **state)
368{
369 struct state *st = *state;
370 const char *prefix = NULL, *name = NULL;
371 size_t prefix_len = 0, name_len = 0;
372 LY_ERR ret = LY_SUCCESS;
373 struct lysp_import *imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200374 struct yin_arg_record *args = NULL;
David Sedlákda63c082019-06-04 13:52:23 +0200375
David Sedlák2b214ac2019-06-06 16:11:03 +0200376 const char *data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákda63c082019-06-04 13:52:23 +0200377 <prefix value=\"a_mod\"/>\
378 <revision-date date=\"2015-01-01\"/>\
David Sedlákb6e65972019-06-19 10:44:13 +0200379 <description><text>import description</text></description>\
380 <reference><text>import reference</text></reference>\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200381 </import>\
382 \
David Sedlák2b214ac2019-06-06 16:11:03 +0200383 <import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200384 <prefix value=\"a_mod\"/>\
385 <revision-date date=\"2015-01-01\"/>\
David Sedlákda63c082019-06-04 13:52:23 +0200386 </import>";
David Sedlákb6e65972019-06-19 10:44:13 +0200387 /* first import */
David Sedlákda63c082019-06-04 13:52:23 +0200388 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200389 yin_load_attributes(st->xml_ctx, &data, &args);
390 ret = yin_parse_import(st->xml_ctx, &args, "b-mod", &data, &imports);
David Sedlákda63c082019-06-04 13:52:23 +0200391 assert_int_equal(ret, LY_SUCCESS);
392 assert_string_equal(imports->name, "a");
393 assert_string_equal(imports->prefix, "a_mod");
394 assert_string_equal(imports->rev, "2015-01-01");
David Sedlákb6e65972019-06-19 10:44:13 +0200395 assert_string_equal(imports->dsc, "import description");
396 assert_string_equal(imports->ref, "import reference");
David Sedlákda63c082019-06-04 13:52:23 +0200397 lydict_remove(st->ctx, imports->name);
398 lydict_remove(st->ctx, imports->prefix);
David Sedlákb6e65972019-06-19 10:44:13 +0200399 lydict_remove(st->ctx, imports->dsc);
400 lydict_remove(st->ctx, imports->ref);
David Sedlákda63c082019-06-04 13:52:23 +0200401 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200402 LY_ARRAY_FREE(args);
David Sedlákda63c082019-06-04 13:52:23 +0200403 imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200404 args = NULL;
David Sedlákc67dcaa2019-06-04 14:49:05 +0200405
David Sedlákb6e65972019-06-19 10:44:13 +0200406 /* second invalid import */
David Sedlákda63c082019-06-04 13:52:23 +0200407 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200408 yin_load_attributes(st->xml_ctx, &data, &args);
409 ret = yin_parse_import(st->xml_ctx, &args, "a_mod", &data, &imports);
David Sedlákda63c082019-06-04 13:52:23 +0200410 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200411 logbuf_assert("Prefix \"a_mod\" already used as module prefix. Line number 1.");
David Sedlákb6e65972019-06-19 10:44:13 +0200412 /* cleanup is supposed to be done by caller function */
David Sedlákda63c082019-06-04 13:52:23 +0200413 lydict_remove(st->ctx, imports->name);
414 lydict_remove(st->ctx, imports->prefix);
415 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200416 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200417 imports = NULL;
David Sedlák8f7a1172019-06-20 14:42:18 +0200418 args = NULL;
419
David Sedlákb6e65972019-06-19 10:44:13 +0200420 st = reset_state(state);
421 /* import with unknown child element */
422 data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
423 <what value=\"a_mod\"/>\
424 </import>";
425 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200426 yin_load_attributes(st->xml_ctx, &data, &args);
427 ret = yin_parse_import(st->xml_ctx, &args, "invalid_mod", &data, &imports);
David Sedlákb6e65972019-06-19 10:44:13 +0200428 assert_int_equal(ret, LY_EVALID);
429 logbuf_assert("Unexpected child element \"what\" of import element.");
430 /* cleanup is supposed to be done by caller function */
431 lydict_remove(st->ctx, imports->name);
432 LY_ARRAY_FREE(imports);
David Sedlák8f7a1172019-06-20 14:42:18 +0200433 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200434
435 st->finished_correctly = true;
436}
437
438static void
439test_yin_parse_status(void **state)
440{
441 struct state *st = *state;
442 const char *prefix = NULL, *name = NULL;
443 size_t prefix_len = 0, name_len = 0;
444 LY_ERR ret = LY_SUCCESS;
445 uint16_t flags = 0;
446 struct lysp_ext_instance *exts;
David Sedlák8f7a1172019-06-20 14:42:18 +0200447 struct yin_arg_record *args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200448
449 /* try all valid values */
450 const char *data = "<status value=\"current\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
451 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200452 yin_load_attributes(st->xml_ctx, &data, &args);
453 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200454 assert_int_equal(ret, LY_SUCCESS);
455 assert_true(flags & LYS_STATUS_CURR);
David Sedlák8f7a1172019-06-20 14:42:18 +0200456 LY_ARRAY_FREE(args);
457 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200458
459 st = reset_state(state);
460 flags = 0;
461 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
462 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200463 yin_load_attributes(st->xml_ctx, &data, &args);
464 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200465 assert_int_equal(ret, LY_SUCCESS);
466 assert_true(flags & LYS_STATUS_DEPRC);
David Sedlák8f7a1172019-06-20 14:42:18 +0200467 LY_ARRAY_FREE(args);
468 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200469
470 st = reset_state(state);
471 flags = 0;
472 data = "<status value=\"obsolete\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
473 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200474 yin_load_attributes(st->xml_ctx, &data, &args);
475 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200476 assert_int_equal(ret, LY_SUCCESS);
477 assert_true(flags & LYS_STATUS_OBSLT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200478 LY_ARRAY_FREE(args);
479 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200480
481 /* duplicit definition (no reset_state() call) */
482 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
483 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200484 yin_load_attributes(st->xml_ctx, &data, &args);
485 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200486 assert_int_equal(ret, LY_EVALID);
487 logbuf_assert("Duplicate element \"status\". Line number 1.");
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 /* invalid status value */
492 st = reset_state(state);
493 flags = 0;
494 data = "<status value=\"dunno\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
495 lyxml_get_element(st->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
David Sedlák8f7a1172019-06-20 14:42:18 +0200496 yin_load_attributes(st->xml_ctx, &data, &args);
497 ret = yin_parse_status(st->xml_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200498 assert_int_equal(ret, LY_EVALID);
499 logbuf_assert("Invalid value \"dunno\" of \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200500 LY_ARRAY_FREE(args);
501
David Sedlák79e50cb2019-06-05 16:33:09 +0200502 st->finished_correctly = true;
David Sedlákda63c082019-06-04 13:52:23 +0200503}
504
David Sedlák3b4db242018-10-19 16:11:01 +0200505int
506main(void)
507{
508
509 const struct CMUnitTest tests[] = {
David Sedlák392af4f2019-06-04 16:02:42 +0200510 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_f, teardown_f),
David Sedlák68a1af12019-03-08 13:46:54 +0100511 cmocka_unit_test_setup_teardown(test_meta, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200512 cmocka_unit_test_setup_teardown(test_yin_parse_text_element, setup_f, teardown_f),
David Sedlákda63c082019-06-04 13:52:23 +0200513 cmocka_unit_test_setup_teardown(test_yin_parse_import, setup_f, teardown_f),
David Sedlákb6e65972019-06-19 10:44:13 +0200514 cmocka_unit_test_setup_teardown(test_yin_parse_status, setup_f, teardown_f),
David Sedlák8f7a1172019-06-20 14:42:18 +0200515 cmocka_unit_test_setup_teardown(test_yin_match_keyword, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200516 cmocka_unit_test(test_yin_match_argument_name),
David Sedlák3b4db242018-10-19 16:11:01 +0200517 };
518
519 return cmocka_run_group_tests(tests, NULL, NULL);
520}