blob: 0b7108c9c587b8c44f5daa247fe9c6a9cf6f84f2 [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ák32eee7b2019-07-09 12:38:44 +020033void lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when);
David Sedlák555c7202019-07-04 12:14:12 +020034
David Sedlák68a1af12019-03-08 13:46:54 +010035struct state {
David Sedlák3b4db242018-10-19 16:11:01 +020036 struct ly_ctx *ctx;
David Sedlák3017da42019-02-15 09:48:04 +010037 struct lys_module *mod;
David Sedlák619db942019-07-03 14:47:30 +020038 struct lysp_module *lysp_mod;
David Sedlákda8ffa32019-07-08 14:17:10 +020039 struct yin_parser_ctx *yin_ctx;
David Sedlák79e50cb2019-06-05 16:33:09 +020040 bool finished_correctly;
David Sedlák68a1af12019-03-08 13:46:54 +010041};
David Sedlák872c7b42018-10-26 13:15:20 +020042
David Sedlák79e50cb2019-06-05 16:33:09 +020043#define BUFSIZE 1024
44char logbuf[BUFSIZE] = {0};
45int store = -1; /* negative for infinite logging, positive for limited logging */
46
47/* set to 0 to printing error messages to stderr instead of checking them in code */
48#define ENABLE_LOGGER_CHECKING 1
49
50#if ENABLE_LOGGER_CHECKING
51static void
52logger(LY_LOG_LEVEL level, const char *msg, const char *path)
53{
54 (void) level; /* unused */
55 if (store) {
56 if (path && path[0]) {
57 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
58 } else {
59 strncpy(logbuf, msg, BUFSIZE - 1);
60 }
61 if (store > 0) {
62 --store;
63 }
64 }
65}
66#endif
67
68#if ENABLE_LOGGER_CHECKING
69# define logbuf_assert(str) assert_string_equal(logbuf, str)
70#else
71# define logbuf_assert(str)
72#endif
73
74#define TEST_DUP_GENERIC(PREFIX, MEMBER, VALUE1, VALUE2, FUNC, RESULT, LINE, CLEANUP) \
75 str = PREFIX MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
76 assert_int_equal(LY_EVALID, FUNC(&ctx, &str, RESULT)); \
77 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
78 CLEANUP
79
80
David Sedlák68a1af12019-03-08 13:46:54 +010081static int
82setup_f(void **state)
83{
84 struct state *st = NULL;
David Sedlák3b4db242018-10-19 16:11:01 +020085
David Sedlák79e50cb2019-06-05 16:33:09 +020086#if ENABLE_LOGGER_CHECKING
87 /* setup logger */
88 ly_set_log_clb(logger, 1);
89#endif
90
David Sedlák68a1af12019-03-08 13:46:54 +010091 /* allocate state variable */
92 (*state) = st = calloc(1, sizeof(*st));
93 if (!st) {
94 fprintf(stderr, "Memmory allocation failed");
95 return EXIT_FAILURE;
96 }
David Sedlák872c7b42018-10-26 13:15:20 +020097
David Sedlák68a1af12019-03-08 13:46:54 +010098 /* create new libyang context */
99 ly_ctx_new(NULL, 0, &st->ctx);
David Sedlák872c7b42018-10-26 13:15:20 +0200100
David Sedlák68a1af12019-03-08 13:46:54 +0100101 /* allocate new module */
102 st->mod = calloc(1, sizeof(*st->mod));
103 st->mod->ctx = st->ctx;
104
David Sedlák619db942019-07-03 14:47:30 +0200105 /* allocate new parsed module */
106 st->lysp_mod = calloc(1, sizeof(*st->lysp_mod));
107 st->lysp_mod->mod = calloc(1, sizeof(*st->lysp_mod->mod));
108 st->lysp_mod->mod->ctx = st->ctx;
109
110 /* allocate parser context */
David Sedlákda8ffa32019-07-08 14:17:10 +0200111 st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
112 st->yin_ctx->xml_ctx.ctx = st->ctx;
113 st->yin_ctx->xml_ctx.line = 1;
David Sedlák8f5bce02019-06-03 16:41:08 +0200114
David Sedlák68a1af12019-03-08 13:46:54 +0100115 return EXIT_SUCCESS;
David Sedlák3b4db242018-10-19 16:11:01 +0200116}
117
118static int
David Sedlák68a1af12019-03-08 13:46:54 +0100119teardown_f(void **state)
120{
121 struct state *st = *(struct state **)state;
David Sedlák619db942019-07-03 14:47:30 +0200122 struct lys_module *temp;
David Sedlák68a1af12019-03-08 13:46:54 +0100123
David Sedlák79e50cb2019-06-05 16:33:09 +0200124#if ENABLE_LOGGER_CHECKING
125 /* teardown logger */
126 if (!st->finished_correctly && logbuf[0] != '\0') {
127 fprintf(stderr, "%s\n", logbuf);
128 }
129#endif
130
David Sedlák619db942019-07-03 14:47:30 +0200131 temp = st->lysp_mod->mod;
132
David Sedlákda8ffa32019-07-08 14:17:10 +0200133 lyxml_context_clear(&st->yin_ctx->xml_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100134 lys_module_free(st->mod, NULL);
David Sedlák619db942019-07-03 14:47:30 +0200135 lysp_module_free(st->lysp_mod);
136 lys_module_free(temp, NULL);
David Sedlák68a1af12019-03-08 13:46:54 +0100137 ly_ctx_destroy(st->ctx, NULL);
David Sedlákda8ffa32019-07-08 14:17:10 +0200138 free(st->yin_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100139 free(st);
140
141 return EXIT_SUCCESS;
142}
143
David Sedlák392af4f2019-06-04 16:02:42 +0200144static struct state*
145reset_state(void **state)
146{
David Sedlák79e50cb2019-06-05 16:33:09 +0200147 ((struct state *)*state)->finished_correctly = true;
David Sedlák555c7202019-07-04 12:14:12 +0200148 logbuf[0] = '\0';
David Sedlák392af4f2019-06-04 16:02:42 +0200149 teardown_f(state);
150 setup_f(state);
151
152 return *state;
153}
154
David Sedlák79e50cb2019-06-05 16:33:09 +0200155void
156logbuf_clean(void)
157{
158 logbuf[0] = '\0';
159}
160
David Sedlák68a1af12019-03-08 13:46:54 +0100161static void
David Sedlák392af4f2019-06-04 16:02:42 +0200162test_yin_parse_module(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +0100163{
164 LY_ERR ret = LY_SUCCESS;
165 struct state *st = *state;
166
167 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200168 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
169 name=\"example-foo\"\
David Sedlák18730132019-03-15 15:51:34 +0100170 xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
171 xmlns:foo=\"urn:example:foo\"\
172 xmlns:myext=\"urn:example:extensions\">\
David Sedlákcd0c9512019-03-29 13:23:06 +0100173 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedláka7406952019-04-05 10:33:07 +0200174 <prefix xmlns:myxt=\"urn:emple:extensions\" value=\"foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlákd9d3a312019-06-04 09:47:10 +0200175 </module>",
David Sedlák68a1af12019-03-08 13:46:54 +0100176 st->mod);
177
178 assert_int_equal(ret, LY_SUCCESS);
179 assert_string_equal(st->mod->parsed->mod->name, "example-foo");
180 assert_string_equal(st->mod->parsed->mod->prefix, "foo");
David Sedlákcd0c9512019-03-29 13:23:06 +0100181 assert_string_equal(st->mod->parsed->mod->ns, "urn:example:foo");
David Sedlák392af4f2019-06-04 16:02:42 +0200182
183 st = reset_state(state);
184 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200185 "<module name=\"example-foo\">\
186 <invalid-tag uri=\"urn:example:foo\"\"/>\
187 </module>",
188 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200189 assert_int_equal(ret, LY_EVALID);
190
191 st = reset_state(state);
192 ret = yin_parse_module(st->ctx,
David Sedlák8f7a1172019-06-20 14:42:18 +0200193 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák57715b12019-06-17 13:05:22 +0200194 </module>",
David Sedlák2b214ac2019-06-06 16:11:03 +0200195 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200196 assert_int_equal(ret, LY_EVALID);
David Sedlák882a8072019-07-08 17:51:20 +0200197 logbuf_assert("Missing mandatory attribute name of module element. Line number 1.");
David Sedlák392af4f2019-06-04 16:02:42 +0200198
199 st = reset_state(state);
200 ret = yin_parse_module(st->ctx,
201 "",
202 st->mod);
203 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200204 logbuf_assert("Invalid keyword \"(null)\", expected \"module\" or \"submodule\". Line number 1.");
205 st->finished_correctly = true;
David Sedlák3b4db242018-10-19 16:11:01 +0200206}
207
208static void
David Sedlák1bccdfa2019-06-17 15:55:27 +0200209test_yin_match_keyword(void **state)
David Sedlák3b4db242018-10-19 16:11:01 +0200210{
David Sedlák8f7a1172019-06-20 14:42:18 +0200211 struct state *st = *state;
David Sedlák3b4db242018-10-19 16:11:01 +0200212
David Sedlák8f7a1172019-06-20 14:42:18 +0200213 const char *prefix, *name;
214 struct yin_arg_record *args = NULL;
215 size_t prefix_len, name_len;
216 /* create mock yin namespace in xml context */
217 const char *data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200218 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
219 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200220 LY_ARRAY_FREE(args);
221
David Sedlákc1771b12019-07-10 15:55:46 +0200222 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydatax", strlen("anydatax"), prefix, prefix_len, YANG_NONE), YANG_NONE);
223 assert_int_equal(yin_match_keyword(st->yin_ctx, "asdasd", strlen("asdasd"), prefix, prefix_len, YANG_NONE), YANG_NONE);
224 assert_int_equal(yin_match_keyword(st->yin_ctx, "", 0, prefix, prefix_len, YANG_NONE), YANG_NONE);
225 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydata", strlen("anydata"), prefix, prefix_len, YANG_NONE), YANG_ANYDATA);
226 assert_int_equal(yin_match_keyword(st->yin_ctx, "anyxml", strlen("anyxml"), prefix, prefix_len, YANG_NONE), YANG_ANYXML);
227 assert_int_equal(yin_match_keyword(st->yin_ctx, "argument", strlen("argument"), prefix, prefix_len, YANG_NONE), YANG_ARGUMENT);
228 assert_int_equal(yin_match_keyword(st->yin_ctx, "augment", strlen("augment"), prefix, prefix_len, YANG_NONE), YANG_AUGMENT);
229 assert_int_equal(yin_match_keyword(st->yin_ctx, "base", strlen("base"), prefix, prefix_len, YANG_NONE), YANG_BASE);
230 assert_int_equal(yin_match_keyword(st->yin_ctx, "belongs-to", strlen("belongs-to"), prefix, prefix_len, YANG_NONE), YANG_BELONGS_TO);
231 assert_int_equal(yin_match_keyword(st->yin_ctx, "bit", strlen("bit"), prefix, prefix_len, YANG_NONE), YANG_BIT);
232 assert_int_equal(yin_match_keyword(st->yin_ctx, "case", strlen("case"), prefix, prefix_len, YANG_NONE), YANG_CASE);
233 assert_int_equal(yin_match_keyword(st->yin_ctx, "choice", strlen("choice"), prefix, prefix_len, YANG_NONE), YANG_CHOICE);
234 assert_int_equal(yin_match_keyword(st->yin_ctx, "config", strlen("config"), prefix, prefix_len, YANG_NONE), YANG_CONFIG);
235 assert_int_equal(yin_match_keyword(st->yin_ctx, "contact", strlen("contact"), prefix, prefix_len, YANG_NONE), YANG_CONTACT);
236 assert_int_equal(yin_match_keyword(st->yin_ctx, "container", strlen("container"), prefix, prefix_len, YANG_NONE), YANG_CONTAINER);
237 assert_int_equal(yin_match_keyword(st->yin_ctx, "default", strlen("default"), prefix, prefix_len, YANG_NONE), YANG_DEFAULT);
238 assert_int_equal(yin_match_keyword(st->yin_ctx, "description", strlen("description"), prefix, prefix_len, YANG_NONE), YANG_DESCRIPTION);
239 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviate", strlen("deviate"), prefix, prefix_len, YANG_NONE), YANG_DEVIATE);
240 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviation", strlen("deviation"), prefix, prefix_len, YANG_NONE), YANG_DEVIATION);
241 assert_int_equal(yin_match_keyword(st->yin_ctx, "enum", strlen("enum"), prefix, prefix_len, YANG_NONE), YANG_ENUM);
242 assert_int_equal(yin_match_keyword(st->yin_ctx, "error-app-tag", strlen("error-app-tag"), prefix, prefix_len, YANG_NONE), YANG_ERROR_APP_TAG);
243 assert_int_equal(yin_match_keyword(st->yin_ctx, "error-message", strlen("error-message"), prefix, prefix_len, YANG_NONE), YANG_ERROR_MESSAGE);
244 assert_int_equal(yin_match_keyword(st->yin_ctx, "extension", strlen("extension"), prefix, prefix_len, YANG_NONE), YANG_EXTENSION);
245 assert_int_equal(yin_match_keyword(st->yin_ctx, "feature", strlen("feature"), prefix, prefix_len, YANG_NONE), YANG_FEATURE);
246 assert_int_equal(yin_match_keyword(st->yin_ctx, "fraction-digits", strlen("fraction-digits"), prefix, prefix_len, YANG_NONE), YANG_FRACTION_DIGITS);
247 assert_int_equal(yin_match_keyword(st->yin_ctx, "grouping", strlen("grouping"), prefix, prefix_len, YANG_NONE), YANG_GROUPING);
248 assert_int_equal(yin_match_keyword(st->yin_ctx, "identity", strlen("identity"), prefix, prefix_len, YANG_NONE), YANG_IDENTITY);
249 assert_int_equal(yin_match_keyword(st->yin_ctx, "if-feature", strlen("if-feature"), prefix, prefix_len, YANG_NONE), YANG_IF_FEATURE);
250 assert_int_equal(yin_match_keyword(st->yin_ctx, "import", strlen("import"), prefix, prefix_len, YANG_NONE), YANG_IMPORT);
251 assert_int_equal(yin_match_keyword(st->yin_ctx, "include", strlen("include"), prefix, prefix_len, YANG_NONE), YANG_INCLUDE);
252 assert_int_equal(yin_match_keyword(st->yin_ctx, "input", strlen("input"), prefix, prefix_len, YANG_NONE), YANG_INPUT);
253 assert_int_equal(yin_match_keyword(st->yin_ctx, "key", strlen("key"), prefix, prefix_len, YANG_NONE), YANG_KEY);
254 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf", strlen("leaf"), prefix, prefix_len, YANG_NONE), YANG_LEAF);
255 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf-list", strlen("leaf-list"), prefix, prefix_len, YANG_NONE), YANG_LEAF_LIST);
256 assert_int_equal(yin_match_keyword(st->yin_ctx, "length", strlen("length"), prefix, prefix_len, YANG_NONE), YANG_LENGTH);
257 assert_int_equal(yin_match_keyword(st->yin_ctx, "list", strlen("list"), prefix, prefix_len, YANG_NONE), YANG_LIST);
258 assert_int_equal(yin_match_keyword(st->yin_ctx, "mandatory", strlen("mandatory"), prefix, prefix_len, YANG_NONE), YANG_MANDATORY);
259 assert_int_equal(yin_match_keyword(st->yin_ctx, "max-elements", strlen("max-elements"), prefix, prefix_len, YANG_NONE), YANG_MAX_ELEMENTS);
260 assert_int_equal(yin_match_keyword(st->yin_ctx, "min-elements", strlen("min-elements"), prefix, prefix_len, YANG_NONE), YANG_MIN_ELEMENTS);
261 assert_int_equal(yin_match_keyword(st->yin_ctx, "modifier", strlen("modifier"), prefix, prefix_len, YANG_NONE), YANG_MODIFIER);
262 assert_int_equal(yin_match_keyword(st->yin_ctx, "module", strlen("module"), prefix, prefix_len, YANG_NONE), YANG_MODULE);
263 assert_int_equal(yin_match_keyword(st->yin_ctx, "must", strlen("must"), prefix, prefix_len, YANG_NONE), YANG_MUST);
264 assert_int_equal(yin_match_keyword(st->yin_ctx, "namespace", strlen("namespace"), prefix, prefix_len, YANG_NONE), YANG_NAMESPACE);
265 assert_int_equal(yin_match_keyword(st->yin_ctx, "notification", strlen("notification"), prefix, prefix_len, YANG_NONE), YANG_NOTIFICATION);
266 assert_int_equal(yin_match_keyword(st->yin_ctx, "ordered-by", strlen("ordered-by"), prefix, prefix_len, YANG_NONE), YANG_ORDERED_BY);
267 assert_int_equal(yin_match_keyword(st->yin_ctx, "organization", strlen("organization"), prefix, prefix_len, YANG_NONE), YANG_ORGANIZATION);
268 assert_int_equal(yin_match_keyword(st->yin_ctx, "output", strlen("output"), prefix, prefix_len, YANG_NONE), YANG_OUTPUT);
269 assert_int_equal(yin_match_keyword(st->yin_ctx, "path", strlen("path"), prefix, prefix_len, YANG_NONE), YANG_PATH);
270 assert_int_equal(yin_match_keyword(st->yin_ctx, "pattern", strlen("pattern"), prefix, prefix_len, YANG_NONE), YANG_PATTERN);
271 assert_int_equal(yin_match_keyword(st->yin_ctx, "position", strlen("position"), prefix, prefix_len, YANG_NONE), YANG_POSITION);
272 assert_int_equal(yin_match_keyword(st->yin_ctx, "prefix", strlen("prefix"), prefix, prefix_len, YANG_NONE), YANG_PREFIX);
273 assert_int_equal(yin_match_keyword(st->yin_ctx, "presence", strlen("presence"), prefix, prefix_len, YANG_NONE), YANG_PRESENCE);
274 assert_int_equal(yin_match_keyword(st->yin_ctx, "range", strlen("range"), prefix, prefix_len, YANG_NONE), YANG_RANGE);
275 assert_int_equal(yin_match_keyword(st->yin_ctx, "reference", strlen("reference"), prefix, prefix_len, YANG_NONE), YANG_REFERENCE);
276 assert_int_equal(yin_match_keyword(st->yin_ctx, "refine", strlen("refine"), prefix, prefix_len, YANG_NONE), YANG_REFINE);
277 assert_int_equal(yin_match_keyword(st->yin_ctx, "require-instance", strlen("require-instance"), prefix, prefix_len, YANG_NONE), YANG_REQUIRE_INSTANCE);
278 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision", strlen("revision"), prefix, prefix_len, YANG_NONE), YANG_REVISION);
279 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision-date", strlen("revision-date"), prefix, prefix_len, YANG_NONE), YANG_REVISION_DATE);
280 assert_int_equal(yin_match_keyword(st->yin_ctx, "rpc", strlen("rpc"), prefix, prefix_len, YANG_NONE), YANG_RPC);
281 assert_int_equal(yin_match_keyword(st->yin_ctx, "status", strlen("status"), prefix, prefix_len, YANG_NONE), YANG_STATUS);
282 assert_int_equal(yin_match_keyword(st->yin_ctx, "submodule", strlen("submodule"), prefix, prefix_len, YANG_NONE), YANG_SUBMODULE);
283 assert_int_equal(yin_match_keyword(st->yin_ctx, "type", strlen("type"), prefix, prefix_len, YANG_NONE), YANG_TYPE);
284 assert_int_equal(yin_match_keyword(st->yin_ctx, "typedef", strlen("typedef"), prefix, prefix_len, YANG_NONE), YANG_TYPEDEF);
285 assert_int_equal(yin_match_keyword(st->yin_ctx, "unique", strlen("unique"), prefix, prefix_len, YANG_NONE), YANG_UNIQUE);
286 assert_int_equal(yin_match_keyword(st->yin_ctx, "units", strlen("units"), prefix, prefix_len, YANG_NONE), YANG_UNITS);
287 assert_int_equal(yin_match_keyword(st->yin_ctx, "uses", strlen("uses"), prefix, prefix_len, YANG_NONE), YANG_USES);
288 assert_int_equal(yin_match_keyword(st->yin_ctx, "value", strlen("value"), prefix, prefix_len, YANG_NONE), YANG_VALUE);
289 assert_int_equal(yin_match_keyword(st->yin_ctx, "when", strlen("when"), prefix, prefix_len, YANG_NONE), YANG_WHEN);
290 assert_int_equal(yin_match_keyword(st->yin_ctx, "yang-version", strlen("yang-version"), prefix, prefix_len, YANG_NONE), YANG_YANG_VERSION);
291 assert_int_equal(yin_match_keyword(st->yin_ctx, "yin-element", strlen("yin-element"), prefix, prefix_len, YANG_NONE), YANG_YIN_ELEMENT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200292
293 st->finished_correctly = true;
David Sedlák872c7b42018-10-26 13:15:20 +0200294}
David Sedlák3b4db242018-10-19 16:11:01 +0200295
David Sedlák872c7b42018-10-26 13:15:20 +0200296static void
David Sedlák060b00e2019-06-19 11:12:06 +0200297test_yin_match_argument_name(void **state)
David Sedlák872c7b42018-10-26 13:15:20 +0200298{
David Sedlák68a1af12019-03-08 13:46:54 +0100299 (void)state; /* unused */
David Sedlák872c7b42018-10-26 13:15:20 +0200300
David Sedlák060b00e2019-06-19 11:12:06 +0200301 assert_int_equal(yin_match_argument_name("", 5), YIN_ARG_UNKNOWN);
302 assert_int_equal(yin_match_argument_name("qwertyasd", 5), YIN_ARG_UNKNOWN);
303 assert_int_equal(yin_match_argument_name("conditionasd", 8), YIN_ARG_UNKNOWN);
304 assert_int_equal(yin_match_argument_name("condition", 9), YIN_ARG_CONDITION);
305 assert_int_equal(yin_match_argument_name("date", 4), YIN_ARG_DATE);
306 assert_int_equal(yin_match_argument_name("module", 6), YIN_ARG_MODULE);
307 assert_int_equal(yin_match_argument_name("name", 4), YIN_ARG_NAME);
308 assert_int_equal(yin_match_argument_name("tag", 3), YIN_ARG_TAG);
309 assert_int_equal(yin_match_argument_name("target-node", 11), YIN_ARG_TARGET_NODE);
310 assert_int_equal(yin_match_argument_name("text", 4), YIN_ARG_TEXT);
311 assert_int_equal(yin_match_argument_name("uri", 3), YIN_ARG_URI);
312 assert_int_equal(yin_match_argument_name("value", 5), YIN_ARG_VALUE);
David Sedlák3b4db242018-10-19 16:11:01 +0200313}
314
David Sedlák68a1af12019-03-08 13:46:54 +0100315static void
316test_meta(void **state)
317{
318 LY_ERR ret = LY_SUCCESS;
319 struct state *st = *state;
320
David Sedlák2b214ac2019-06-06 16:11:03 +0200321 ret = yin_parse_module(st->ctx,"<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
322 name=\"example-foo\">\
David Sedlák21f87cd2019-07-03 16:53:23 +0200323 <prefix value=\"foo\">ignored</prefix>\
324 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlák15a92662019-06-18 11:55:15 +0200325 <organization xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"><text>organization...</text></organization>\
326 <contact><text>contact...</text></contact>\
327 <description><text>description...</text></description>\
328 <reference><text>reference...</text></reference>\
David Sedlák68a1af12019-03-08 13:46:54 +0100329 </module>", st->mod);
330
331 assert_int_equal(ret, LY_SUCCESS);
David Sedláka7406952019-04-05 10:33:07 +0200332 assert_string_equal(st->mod->parsed->mod->org, "organization...");
David Sedlák68a1af12019-03-08 13:46:54 +0100333 assert_string_equal(st->mod->parsed->mod->contact, "contact...");
334 assert_string_equal(st->mod->parsed->mod->dsc, "description...");
335 assert_string_equal(st->mod->parsed->mod->ref, "reference...");
David Sedlák68826732019-06-05 10:50:58 +0200336
337 st = reset_state(state);
338 ret = yin_parse_module(st->ctx,"<module name=\"example-foo\">\
339 <organization test=\"invalid-argument\">organization...</organization>\
340 </module>", st->mod);
341 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200342
343 st->finished_correctly = true;
David Sedlák68a1af12019-03-08 13:46:54 +0100344}
345
David Sedlák8f5bce02019-06-03 16:41:08 +0200346static void
David Sedlákda63c082019-06-04 13:52:23 +0200347test_yin_parse_import(void **state)
348{
349 struct state *st = *state;
350 const char *prefix = NULL, *name = NULL;
351 size_t prefix_len = 0, name_len = 0;
352 LY_ERR ret = LY_SUCCESS;
David Sedlák8f7a1172019-06-20 14:42:18 +0200353 struct yin_arg_record *args = NULL;
David Sedlákda63c082019-06-04 13:52:23 +0200354
David Sedlák2b214ac2019-06-06 16:11:03 +0200355 const char *data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákda63c082019-06-04 13:52:23 +0200356 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200357 <revision-date date=\"2015-01-01\"></revision-date>\
David Sedlákb6e65972019-06-19 10:44:13 +0200358 <description><text>import description</text></description>\
359 <reference><text>import reference</text></reference>\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200360 </import>\
361 \
David Sedlák2b214ac2019-06-06 16:11:03 +0200362 <import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
David Sedlákc67dcaa2019-06-04 14:49:05 +0200363 <prefix value=\"a_mod\"/>\
David Sedlák00250342019-06-21 14:19:39 +0200364 <revision-date date=\"2015-01-01\" />\
David Sedlákda63c082019-06-04 13:52:23 +0200365 </import>";
David Sedlákb6e65972019-06-19 10:44:13 +0200366 /* first import */
David Sedlákda8ffa32019-07-08 14:17:10 +0200367 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
368 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200369 st->lysp_mod->mod->prefix = "b-mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200370 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákda63c082019-06-04 13:52:23 +0200371 assert_int_equal(ret, LY_SUCCESS);
David Sedlák619db942019-07-03 14:47:30 +0200372 assert_string_equal(st->lysp_mod->imports->name, "a");
373 assert_string_equal(st->lysp_mod->imports->prefix, "a_mod");
374 assert_string_equal(st->lysp_mod->imports->rev, "2015-01-01");
375 assert_string_equal(st->lysp_mod->imports->dsc, "import description");
376 assert_string_equal(st->lysp_mod->imports->ref, "import reference");
David Sedlák8f7a1172019-06-20 14:42:18 +0200377 LY_ARRAY_FREE(args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200378 args = NULL;
David Sedlák619db942019-07-03 14:47:30 +0200379 st = reset_state(state);
David Sedlákc67dcaa2019-06-04 14:49:05 +0200380
David Sedlákb6e65972019-06-19 10:44:13 +0200381 /* second invalid import */
David Sedlákda8ffa32019-07-08 14:17:10 +0200382 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
383 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200384 st->lysp_mod->mod->prefix = "a_mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200385 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákda63c082019-06-04 13:52:23 +0200386 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200387 logbuf_assert("Prefix \"a_mod\" already used as module prefix. Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200388 LY_ARRAY_FREE(args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200389 args = NULL;
390
David Sedlákb6e65972019-06-19 10:44:13 +0200391 st = reset_state(state);
392 /* import with unknown child element */
393 data = "<import xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" module=\"a\">\
394 <what value=\"a_mod\"/>\
395 </import>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200396 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
397 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák619db942019-07-03 14:47:30 +0200398 st->lysp_mod->mod->prefix = "invalid_mod";
David Sedlákda8ffa32019-07-08 14:17:10 +0200399 ret = yin_parse_import(st->yin_ctx, &args, &data, st->lysp_mod);
David Sedlákb6e65972019-06-19 10:44:13 +0200400 assert_int_equal(ret, LY_EVALID);
David Sedlák3ffbc522019-07-02 17:49:28 +0200401 logbuf_assert("Unexpected child element \"what\" of import element. Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200402 LY_ARRAY_FREE(args);
David Sedlákb6e65972019-06-19 10:44:13 +0200403
404 st->finished_correctly = true;
405}
406
407static void
408test_yin_parse_status(void **state)
409{
410 struct state *st = *state;
411 const char *prefix = NULL, *name = NULL;
412 size_t prefix_len = 0, name_len = 0;
413 LY_ERR ret = LY_SUCCESS;
414 uint16_t flags = 0;
415 struct lysp_ext_instance *exts;
David Sedlák8f7a1172019-06-20 14:42:18 +0200416 struct yin_arg_record *args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200417
418 /* try all valid values */
419 const char *data = "<status value=\"current\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200420 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
421 yin_load_attributes(st->yin_ctx, &data, &args);
422 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
423 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200424 assert_int_equal(ret, LY_SUCCESS);
425 assert_true(flags & LYS_STATUS_CURR);
David Sedlák8f7a1172019-06-20 14:42:18 +0200426 LY_ARRAY_FREE(args);
427 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200428
429 st = reset_state(state);
430 flags = 0;
431 data = "<status value=\"deprecated\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200432 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
433 yin_load_attributes(st->yin_ctx, &data, &args);
434 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
435 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200436 assert_int_equal(ret, LY_SUCCESS);
437 assert_true(flags & LYS_STATUS_DEPRC);
David Sedlák8f7a1172019-06-20 14:42:18 +0200438 LY_ARRAY_FREE(args);
439 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200440
441 st = reset_state(state);
442 flags = 0;
443 data = "<status value=\"obsolete\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200444 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
445 yin_load_attributes(st->yin_ctx, &data, &args);
446 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
447 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb6e65972019-06-19 10:44:13 +0200448 assert_int_equal(ret, LY_SUCCESS);
449 assert_true(flags & LYS_STATUS_OBSLT);
David Sedlák8f7a1172019-06-20 14:42:18 +0200450 LY_ARRAY_FREE(args);
451 args = NULL;
David Sedlákb6e65972019-06-19 10:44:13 +0200452
David Sedlákb6e65972019-06-19 10:44:13 +0200453 /* invalid status value */
454 st = reset_state(state);
455 flags = 0;
456 data = "<status value=\"dunno\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200457 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
458 yin_load_attributes(st->yin_ctx, &data, &args);
459 ret = yin_parse_status(st->yin_ctx, &args, &data, &flags, &exts);
David Sedlákb6e65972019-06-19 10:44:13 +0200460 assert_int_equal(ret, LY_EVALID);
461 logbuf_assert("Invalid value \"dunno\" of \"status\". Line number 1.");
David Sedlák8f7a1172019-06-20 14:42:18 +0200462 LY_ARRAY_FREE(args);
463
David Sedlák79e50cb2019-06-05 16:33:09 +0200464 st->finished_correctly = true;
David Sedlákda63c082019-06-04 13:52:23 +0200465}
466
David Sedlák554e36d2019-06-20 16:00:04 +0200467static void
468test_yin_parse_extension(void **state)
469{
470 struct state *st = *state;
471 const char *prefix = NULL, *name = NULL;
472 size_t prefix_len = 0, name_len = 0;
473 LY_ERR ret = LY_SUCCESS;
474 struct yin_arg_record *args = NULL;
475 struct lysp_ext *exts = NULL, *iter = NULL;
476
477 const char *data = "<extension name=\"b\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák9494eb22019-06-21 16:06:53 +0200478 <argument name=\"argname\"></argument>\
David Sedlák554e36d2019-06-20 16:00:04 +0200479 <description><text>desc</text></description>\
480 <reference><text>ref</text></reference>\
481 <status value=\"deprecated\"></status>\
482 </extension>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200483 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
484 yin_load_attributes(st->yin_ctx, &data, &args);
485 ret = yin_parse_extension(st->yin_ctx, &args, &data, &exts);
486 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák554e36d2019-06-20 16:00:04 +0200487 assert_int_equal(ret, LY_SUCCESS);
488 LY_ARRAY_FOR_ITER(exts, struct lysp_ext, iter) {
489 assert_string_equal(iter->name, "b");
490 assert_string_equal(iter->dsc, "desc");
491 assert_string_equal(iter->ref, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200492 assert_string_equal(iter->argument, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200493 assert_true(iter->flags & LYS_STATUS_DEPRC);
494 }
David Sedlák288c1472019-06-20 16:09:48 +0200495 lydict_remove(st->ctx, "b");
496 lydict_remove(st->ctx, "desc");
497 lydict_remove(st->ctx, "ref");
David Sedlák9494eb22019-06-21 16:06:53 +0200498 lydict_remove(st->ctx, "argname");
David Sedlák554e36d2019-06-20 16:00:04 +0200499 LY_ARRAY_FREE(args);
David Sedlák288c1472019-06-20 16:09:48 +0200500 LY_ARRAY_FREE(exts);
David Sedlák554e36d2019-06-20 16:00:04 +0200501 st->finished_correctly = true;
502}
503
David Sedlák2721d3d2019-06-21 15:37:41 +0200504static void
505test_yin_parse_yin_element_element(void **state)
506{
507 struct state *st = *state;
508 const char *prefix = NULL, *name = NULL;
509 size_t prefix_len = 0, name_len = 0;
510 LY_ERR ret = LY_SUCCESS;
511 uint16_t flags = 0;
David Sedlák3ffbc522019-07-02 17:49:28 +0200512 struct lysp_ext_instance *exts;
David Sedlák2721d3d2019-06-21 15:37:41 +0200513 struct yin_arg_record *args = NULL;
514
515 /* try all valid values */
516 const char *data = "<yin-element value=\"true\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200517 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
518 yin_load_attributes(st->yin_ctx, &data, &args);
519 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
520 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200521 assert_int_equal(ret, LY_SUCCESS);
522 assert_true(flags & LYS_YINELEM_TRUE);
523 LY_ARRAY_FREE(args);
524 args = NULL;
525
526 st = reset_state(state);
527 flags = 0;
528 data = "<yin-element value=\"false\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200529 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
530 yin_load_attributes(st->yin_ctx, &data, &args);
531 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
532 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2721d3d2019-06-21 15:37:41 +0200533 assert_int_equal(ret, LY_SUCCESS);
534 assert_true(flags & LYS_YINELEM_FALSE);
535 LY_ARRAY_FREE(args);
536 args = NULL;
537
538 /* invalid value */
539 st = reset_state(state);
540 flags = 0;
541 data = "<yin-element value=\"invalid\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"/>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200542 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
543 yin_load_attributes(st->yin_ctx, &data, &args);
544 ret = yin_parse_yin_element_element(st->yin_ctx, args, &data, &flags, &exts);
David Sedlák2721d3d2019-06-21 15:37:41 +0200545 assert_int_equal(ret, LY_EVALID);
546 LY_ARRAY_FREE(args);
547 args = NULL;
548
549 st->finished_correctly = true;
550}
551
David Sedlákb1a78352019-06-28 16:16:29 +0200552static void
553test_yin_parse_element_generic(void **state)
554{
555 const char *prefix, *name;
556 struct state *st = *state;
557 struct lysp_ext_instance exts;
558 size_t prefix_len, name_len;
559 LY_ERR ret;
560
561 memset(&exts, 0, sizeof(exts));
562
563 const char *data = "<elem attr=\"value\">text_value</elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200564 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
565 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 +0200566 assert_int_equal(ret, LY_SUCCESS);
David Sedlák1fdb2522019-07-09 16:22:57 +0200567 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb1a78352019-06-28 16:16:29 +0200568 assert_string_equal(exts.child->stmt, "elem");
569 assert_string_equal(exts.child->arg, "text_value");
David Sedlákb1a78352019-06-28 16:16:29 +0200570 assert_string_equal(exts.child->child->stmt, "attr");
571 assert_string_equal(exts.child->child->arg, "value");
572 assert_true(exts.child->child->flags & LYS_YIN_ATTR);
David Sedlákb1a78352019-06-28 16:16:29 +0200573 lysp_ext_instance_free(st->ctx, &exts);
David Sedlák5392a212019-07-01 09:19:10 +0200574 st = reset_state(state);
575
576 data = "<elem></elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200577 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
578 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 +0200579 assert_int_equal(ret, LY_SUCCESS);
580 assert_string_equal(exts.child->stmt, "elem");
581 assert_null(exts.child->child);
582 assert_null(exts.child->arg);
David Sedlákda8ffa32019-07-08 14:17:10 +0200583 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák5392a212019-07-01 09:19:10 +0200584 lysp_ext_instance_free(st->ctx, &exts);
585
David Sedlákb1a78352019-06-28 16:16:29 +0200586 st->finished_correctly = true;
587}
588
589static void
590test_yin_parse_extension_instance(void **state)
591{
592 LY_ERR ret;
593 struct state *st = *state;
594 const char *prefix, *name;
595 size_t prefix_len, name_len;
596 struct yin_arg_record *args = NULL;
597 struct lysp_ext_instance *exts = NULL;
David Sedlákb1a78352019-06-28 16:16:29 +0200598 const char *data = "<ext value1=\"test\" value=\"test2\"><subelem>text</subelem></ext>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200599 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
600 yin_load_attributes(st->yin_ctx, &data, &args);
601 ret = yin_parse_extension_instance(st->yin_ctx, &args, &data, name2fullname(name, prefix_len),
David Sedlák619db942019-07-03 14:47:30 +0200602 namelen2fulllen(name_len, prefix_len), LYEXT_SUBSTMT_CONTACT, 0, &exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200603 assert_int_equal(ret, LY_SUCCESS);
604 assert_string_equal(exts->name, "ext");
605 assert_int_equal(exts->insubstmt_index, 0);
606 assert_true(exts->insubstmt == LYEXT_SUBSTMT_CONTACT);
607 assert_true(exts->yin & LYS_YIN);
608 assert_string_equal(exts->child->stmt, "value1");
609 assert_string_equal(exts->child->arg, "test");
610 assert_null(exts->child->child);
611 assert_true(exts->child->flags & LYS_YIN_ATTR);
612 assert_string_equal(exts->child->next->stmt, "value");
613 assert_string_equal(exts->child->next->arg, "test2");
614 assert_null(exts->child->next->child);
615 assert_true(exts->child->next->flags & LYS_YIN_ATTR);
616
617 assert_string_equal(exts->child->next->next->stmt, "subelem");
618 assert_string_equal(exts->child->next->next->arg, "text");
619 assert_null(exts->child->next->next->child);
620 assert_null(exts->child->next->next->next);
621 assert_false(exts->child->next->next->flags & LYS_YIN_ATTR);
David Sedlákda8ffa32019-07-08 14:17:10 +0200622 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb1a78352019-06-28 16:16:29 +0200623 LY_ARRAY_FREE(args);
624 lysp_ext_instance_free(st->ctx, exts);
625 LY_ARRAY_FREE(exts);
David Sedlákf250ecf2019-07-01 11:02:05 +0200626 exts = NULL;
627 args = NULL;
628 st = reset_state(state);
629
630 data = "<extension-elem />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200631 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
632 yin_load_attributes(st->yin_ctx, &data, &args);
633 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 +0200634 assert_int_equal(ret, LY_SUCCESS);
635 assert_string_equal(exts->name, "extension-elem");
636 assert_null(exts->argument);
637 assert_null(exts->child);
638 assert_int_equal(exts->insubstmt, LYEXT_SUBSTMT_CONTACT);
639 assert_int_equal(exts->insubstmt_index, 0);
640 assert_true(exts->yin & LYS_YIN);
David Sedlákda8ffa32019-07-08 14:17:10 +0200641 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákf250ecf2019-07-01 11:02:05 +0200642 LY_ARRAY_FREE(args);
643 lysp_ext_instance_free(st->ctx, exts);
644 LY_ARRAY_FREE(exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200645 st->finished_correctly = true;
646}
647
David Sedlák555c7202019-07-04 12:14:12 +0200648static void
649test_yin_parse_content(void **state)
650{
651 struct state *st = *state;
652 LY_ERR ret = LY_SUCCESS;
653 struct sized_string name, prefix;
654 const char *data = "<prefix value=\"a_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
655 "<custom xmlns=\"my-ext\">"
656 "totally amazing extension"
657 "</custom>"
David Sedlák986cb412019-07-04 13:10:11 +0200658 "<extension name=\"ext\">"
659 "<argument name=\"argname\"></argument>"
660 "<description><text>desc</text></description>"
661 "<reference><text>ref</text></reference>"
662 "<status value=\"deprecated\"></status>"
663 "</extension>"
David Sedlák555c7202019-07-04 12:14:12 +0200664 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
David Sedlák5f8191e2019-07-08 16:35:52 +0200665 "<if-feature value=\"foo\"></if-feature>"
David Sedlák32eee7b2019-07-09 12:38:44 +0200666 "<when condition=\"condition...\">"
667 "<reference><text>when_ref</text></reference>"
668 "<description><text>when_desc</text></description>"
669 "</when>"
David Sedláke1a30302019-07-10 13:49:38 +0200670 "<config value=\"true\"/>"
David Sedlákc1771b12019-07-10 15:55:46 +0200671 "<error-message>"
672 "<value>error-msg</value>"
673 "</error-message>"
David Sedlák2ce1be62019-07-10 16:15:09 +0200674 "<error-app-tag value=\"err-app-tag\"/>"
David Sedláka5b1d382019-07-10 16:31:09 +0200675 "<units name=\"radians\"></units>"
David Sedlák555c7202019-07-04 12:14:12 +0200676 "</prefix>";
677 struct lysp_ext_instance *exts = NULL;
David Sedlák5f8191e2019-07-08 16:35:52 +0200678 const char **if_features = NULL;
David Sedlák555c7202019-07-04 12:14:12 +0200679 struct yin_arg_record *attrs = NULL;
David Sedláka5b1d382019-07-10 16:31:09 +0200680 const char *value, *err_msg, *app_tag, *units;
David Sedlák986cb412019-07-04 13:10:11 +0200681 struct lysp_ext *ext_def = NULL;
David Sedlák32eee7b2019-07-09 12:38:44 +0200682 struct lysp_when *when_p = NULL;
David Sedláke1a30302019-07-10 13:49:38 +0200683 uint8_t config = 0;
David Sedlák555c7202019-07-04 12:14:12 +0200684
David Sedlákda8ffa32019-07-08 14:17:10 +0200685 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
686 yin_load_attributes(st->yin_ctx, &data, &attrs);
David Sedlák555c7202019-07-04 12:14:12 +0200687
David Sedláka5b1d382019-07-10 16:31:09 +0200688 struct yin_subelement subelems[9] = {{YANG_CONFIG, &config, 0},
David Sedlák2ce1be62019-07-10 16:15:09 +0200689 {YANG_ERROR_APP_TAG, &app_tag, 0},
David Sedlákc1771b12019-07-10 15:55:46 +0200690 {YANG_ERROR_MESSAGE, &err_msg, 0},
David Sedláke1a30302019-07-10 13:49:38 +0200691 {YANG_EXTENSION, &ext_def, 0},
David Sedlák5f8191e2019-07-08 16:35:52 +0200692 {YANG_IF_FEATURE, &if_features, 0},
David Sedláka5b1d382019-07-10 16:31:09 +0200693 {YANG_UNITS, &units, 0},
David Sedlák32eee7b2019-07-09 12:38:44 +0200694 {YANG_WHEN, &when_p, 0},
David Sedlákb0faad82019-07-04 14:28:59 +0200695 {YANG_CUSTOM, NULL, 0},
696 {YIN_TEXT, &value, 0}};
David Sedláka5b1d382019-07-10 16:31:09 +0200697 ret = yin_parse_content(st->yin_ctx, subelems, 9, &data, YANG_PREFIX, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200698 assert_int_equal(ret, LY_SUCCESS);
David Sedlák1fdb2522019-07-09 16:22:57 +0200699 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2ce1be62019-07-10 16:15:09 +0200700 /* check parsed values */
David Sedlák555c7202019-07-04 12:14:12 +0200701 assert_string_equal(exts->name, "custom");
702 assert_string_equal(exts->argument, "totally amazing extension");
703 assert_string_equal(value, "wsefsdf");
David Sedláka5b1d382019-07-10 16:31:09 +0200704 assert_string_equal(units, "radians");
David Sedlák32eee7b2019-07-09 12:38:44 +0200705 assert_string_equal(when_p->cond, "condition...");
706 assert_string_equal(when_p->dsc, "when_desc");
707 assert_string_equal(when_p->ref, "when_ref");
David Sedláke1a30302019-07-10 13:49:38 +0200708 assert_int_equal(config, LYS_CONFIG_W);
David Sedlákc1771b12019-07-10 15:55:46 +0200709 assert_string_equal(err_msg, "error-msg");
David Sedlák2ce1be62019-07-10 16:15:09 +0200710 assert_string_equal(app_tag, "err-app-tag");
711 /* cleanup */
David Sedlák555c7202019-07-04 12:14:12 +0200712 lysp_ext_instance_free(st->ctx, exts);
David Sedlák32eee7b2019-07-09 12:38:44 +0200713 lysp_when_free(st->ctx, when_p);
David Sedlák986cb412019-07-04 13:10:11 +0200714 lysp_ext_free(st->ctx, ext_def);
David Sedlák5f8191e2019-07-08 16:35:52 +0200715 FREE_STRING(st->ctx, *if_features);
David Sedlákc1771b12019-07-10 15:55:46 +0200716 FREE_STRING(st->ctx, err_msg);
David Sedlák2ce1be62019-07-10 16:15:09 +0200717 FREE_STRING(st->ctx, app_tag);
David Sedláka5b1d382019-07-10 16:31:09 +0200718 FREE_STRING(st->ctx, units);
David Sedlák5f8191e2019-07-08 16:35:52 +0200719 LY_ARRAY_FREE(if_features);
David Sedlák555c7202019-07-04 12:14:12 +0200720 LY_ARRAY_FREE(exts);
David Sedlák986cb412019-07-04 13:10:11 +0200721 LY_ARRAY_FREE(ext_def);
David Sedlák555c7202019-07-04 12:14:12 +0200722 LY_ARRAY_FREE(attrs);
David Sedlák32eee7b2019-07-09 12:38:44 +0200723 free(when_p);
David Sedlák555c7202019-07-04 12:14:12 +0200724 attrs = NULL;
725 lydict_remove(st->ctx, value);
726 st = reset_state(state);
727
728 /* test unique subelem */
729 const char *prefix_value;
730 struct yin_subelement subelems2[2] = {{YANG_PREFIX, &prefix_value, 0},
731 {YIN_TEXT, &value, YIN_SUBELEM_UNIQUE}};
732 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
733 "<prefix value=\"inv_mod\" />"
734 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
735 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
736 "</module>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200737 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
738 yin_load_attributes(st->yin_ctx, &data, &attrs);
739 ret = yin_parse_content(st->yin_ctx, subelems2, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200740 assert_int_equal(ret, LY_EVALID);
741 logbuf_assert("Redefinition of text element in module element. Line number 1.");
742 lydict_remove(st->ctx, prefix_value);
743 lydict_remove(st->ctx, value);
744 st = reset_state(state);
745 LY_ARRAY_FREE(attrs);
746 attrs = NULL;
747
748 /* test first subelem */
749 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
750 "<prefix value=\"inv_mod\" />"
751 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
752 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
753 "</module>";
754 struct yin_subelement subelems3[2] = {{YANG_PREFIX, &prefix_value, 0},
755 {YIN_TEXT, &value, YIN_SUBELEM_FIRST}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200756 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
757 yin_load_attributes(st->yin_ctx, &data, &attrs);
758 ret = yin_parse_content(st->yin_ctx, subelems3, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200759 assert_int_equal(ret, LY_EVALID);
760 logbuf_assert("Subelement text of module element must be defined as first subelement. Line number 1.");
761 lydict_remove(st->ctx, prefix_value);
762 st = reset_state(state);
763 LY_ARRAY_FREE(attrs);
764 attrs = NULL;
765
766 /* test mandatory subelem */
767 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
768 "</module>";
769 struct yin_subelement subelems4[1] = {{YANG_PREFIX, &prefix_value, YIN_SUBELEM_MANDATORY}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200770 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
771 yin_load_attributes(st->yin_ctx, &data, &attrs);
772 ret = yin_parse_content(st->yin_ctx, subelems4, 1, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200773 assert_int_equal(ret, LY_EVALID);
774 logbuf_assert("Missing mandatory subelement prefix of module element. Line number 1.");
775 LY_ARRAY_FREE(attrs);
776
777 st->finished_correctly = true;
778}
779
David Sedlák92147b02019-07-09 14:01:01 +0200780static void
781test_yin_parse_yangversion(void **state)
782{
783 struct state *st = *state;
784 LY_ERR ret = LY_SUCCESS;
785 struct sized_string name, prefix;
786 struct yin_arg_record *attrs = NULL;
787 uint8_t version;
788
789 const char *data = "<yang-version xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"1.0\">\n"
790 "</yang-version>";
791 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
792 yin_load_attributes(st->yin_ctx, &data, &attrs);
793 ret = yin_parse_yangversion(st->yin_ctx, attrs, &data, &version, NULL);
794 assert_int_equal(LY_SUCCESS, ret);
David Sedlák1fdb2522019-07-09 16:22:57 +0200795 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák92147b02019-07-09 14:01:01 +0200796 assert_true(version == LYS_VERSION_1_0);
797 assert_true(st->yin_ctx->mod_version == LYS_VERSION_1_0);
798 LY_ARRAY_FREE(attrs);
799 attrs = NULL;
800 st = reset_state(state);
801
802 data = "<yang-version xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"1.1\">\n"
803 "</yang-version>";
804 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
805 yin_load_attributes(st->yin_ctx, &data, &attrs);
806 ret = yin_parse_yangversion(st->yin_ctx, attrs, &data, &version, NULL);
807 assert_int_equal(LY_SUCCESS, ret);
David Sedlák1fdb2522019-07-09 16:22:57 +0200808 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák92147b02019-07-09 14:01:01 +0200809 assert_true(version == LYS_VERSION_1_1);
810 assert_true(st->yin_ctx->mod_version == LYS_VERSION_1_1);
811 LY_ARRAY_FREE(attrs);
812 attrs = NULL;
813 st = reset_state(state);
814
815 data = "<yang-version xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"randomvalue\">\n"
816 "</yang-version>";
817 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
818 yin_load_attributes(st->yin_ctx, &data, &attrs);
819 ret = yin_parse_yangversion(st->yin_ctx, attrs, &data, &version, NULL);
820 assert_int_equal(ret, LY_EVALID);
David Sedlák1fdb2522019-07-09 16:22:57 +0200821 logbuf_assert("Invalid value \"randomvalue\" of \"yang-version\". Line number 1.");
David Sedlák92147b02019-07-09 14:01:01 +0200822 LY_ARRAY_FREE(attrs);
823 attrs = NULL;
David Sedlák1fdb2522019-07-09 16:22:57 +0200824 st = reset_state(state);
825
826 data = "<yang-version xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
827 "</yang-version>";
828 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
829 yin_load_attributes(st->yin_ctx, &data, &attrs);
830 ret = yin_parse_yangversion(st->yin_ctx, attrs, &data, &version, NULL);
831 assert_int_equal(ret, LY_EVALID);
832 LY_ARRAY_FREE(attrs);
833 attrs = NULL;
834 logbuf_assert("Missing mandatory attribute value of yang-version element. Line number 1.");
835 st->finished_correctly = true;
836}
837
838static void
839test_yin_parse_mandatory(void **state)
840{
841 struct state *st = *state;
842 LY_ERR ret = LY_SUCCESS;
843 struct sized_string name, prefix;
844 struct yin_arg_record *attrs = NULL;
845 uint16_t man = 0;
846
847 const char *data = "<mandatory xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"true\">\n"
848 "</mandatory>";
849 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
850 yin_load_attributes(st->yin_ctx, &data, &attrs);
851 ret = yin_parse_mandatory(st->yin_ctx, attrs, &data, &man, NULL);
852 assert_int_equal(LY_SUCCESS, ret);
853 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
854 assert_true(man == LYS_MAND_TRUE);
855 LY_ARRAY_FREE(attrs);
856 attrs = NULL;
857 man = 0;
858 st = reset_state(state);
859
860 data = "<mandatory xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"false\" />";
861 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
862 yin_load_attributes(st->yin_ctx, &data, &attrs);
863 ret = yin_parse_mandatory(st->yin_ctx, attrs, &data, &man, NULL);
864 assert_int_equal(LY_SUCCESS, ret);
865 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
866 assert_true(man == LYS_MAND_FALSE);
867 LY_ARRAY_FREE(attrs);
868 attrs = NULL;
869 man = 0;
870 st = reset_state(state);
871
872 data = "<mandatory xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" value=\"randomvalue\">\n"
873 "</mandatory>";
874 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
875 yin_load_attributes(st->yin_ctx, &data, &attrs);
876 ret = yin_parse_mandatory(st->yin_ctx, attrs, &data, &man, NULL);
877 assert_int_equal(ret, LY_EVALID);
878 LY_ARRAY_FREE(attrs);
879 logbuf_assert("Invalid value \"randomvalue\" of \"mandatory\". Line number 1.");
880 attrs = NULL;
881 man = 0;
882 st = reset_state(state);
883
884 data = "<mandatory xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
885 "</mandatory>";
886 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
887 yin_load_attributes(st->yin_ctx, &data, &attrs);
888 ret = yin_parse_mandatory(st->yin_ctx, attrs, &data, &man, NULL);
889 assert_int_equal(ret, LY_EVALID);
890 LY_ARRAY_FREE(attrs);
891 logbuf_assert("Missing mandatory attribute value of mandatory element. Line number 1.");
David Sedlák92147b02019-07-09 14:01:01 +0200892 st->finished_correctly = true;
893}
894
David Sedlák4a650532019-07-10 11:55:18 +0200895static void
896test_validate_value(void **state)
897{
898 struct state *st = *state;
899 assert_int_equal(yin_validate_value(st->yin_ctx, Y_IDENTIF_ARG, "#invalid", 8), LY_EVALID);
900 logbuf_assert("Invalid identifier character '#'. Line number 1.");
901 assert_int_equal(yin_validate_value(st->yin_ctx, Y_STR_ARG, "", 0), LY_SUCCESS);
902 assert_int_equal(yin_validate_value(st->yin_ctx, Y_IDENTIF_ARG, "pre:b", 5), LY_EVALID);
903 assert_int_equal(yin_validate_value(st->yin_ctx, Y_PREF_IDENTIF_ARG, "pre:b", 5), LY_SUCCESS);
904 assert_int_equal(yin_validate_value(st->yin_ctx, Y_PREF_IDENTIF_ARG, "pre:pre:b", 9), LY_EVALID);
905
906 st->finished_correctly = true;
907}
908
David Sedlák3b4db242018-10-19 16:11:01 +0200909int
910main(void)
911{
912
913 const struct CMUnitTest tests[] = {
David Sedlák392af4f2019-06-04 16:02:42 +0200914 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_f, teardown_f),
David Sedlák68a1af12019-03-08 13:46:54 +0100915 cmocka_unit_test_setup_teardown(test_meta, setup_f, teardown_f),
David Sedlákda63c082019-06-04 13:52:23 +0200916 cmocka_unit_test_setup_teardown(test_yin_parse_import, setup_f, teardown_f),
David Sedlákb6e65972019-06-19 10:44:13 +0200917 cmocka_unit_test_setup_teardown(test_yin_parse_status, setup_f, teardown_f),
David Sedlák8f7a1172019-06-20 14:42:18 +0200918 cmocka_unit_test_setup_teardown(test_yin_match_keyword, setup_f, teardown_f),
David Sedlák554e36d2019-06-20 16:00:04 +0200919 cmocka_unit_test_setup_teardown(test_yin_parse_extension, setup_f, teardown_f),
David Sedlák2721d3d2019-06-21 15:37:41 +0200920 cmocka_unit_test_setup_teardown(test_yin_parse_yin_element_element, setup_f, teardown_f),
David Sedlákb1a78352019-06-28 16:16:29 +0200921 cmocka_unit_test_setup_teardown(test_yin_parse_element_generic, setup_f, teardown_f),
922 cmocka_unit_test_setup_teardown(test_yin_parse_extension_instance, setup_f, teardown_f),
David Sedlák555c7202019-07-04 12:14:12 +0200923 cmocka_unit_test_setup_teardown(test_yin_parse_content, setup_f, teardown_f),
David Sedlák92147b02019-07-09 14:01:01 +0200924 cmocka_unit_test_setup_teardown(test_yin_parse_yangversion, setup_f, teardown_f),
David Sedlák1fdb2522019-07-09 16:22:57 +0200925 cmocka_unit_test_setup_teardown(test_yin_parse_mandatory, setup_f, teardown_f),
David Sedlák4a650532019-07-10 11:55:18 +0200926 cmocka_unit_test_setup_teardown(test_validate_value, setup_f, teardown_f),
David Sedlák060b00e2019-06-19 11:12:06 +0200927 cmocka_unit_test(test_yin_match_argument_name),
David Sedlák3b4db242018-10-19 16:11:01 +0200928 };
929
930 return cmocka_run_group_tests(tests, NULL, NULL);
931}