blob: 59d1cd9ff006eda6b153be4df35977afd1842cf6 [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ák32488102019-07-15 17:44:10 +020034void lysp_type_free(struct ly_ctx *ctx, struct lysp_type *type);
David Sedlák555c7202019-07-04 12:14:12 +020035
David Sedlák68a1af12019-03-08 13:46:54 +010036struct state {
David Sedlák3b4db242018-10-19 16:11:01 +020037 struct ly_ctx *ctx;
David Sedlák3017da42019-02-15 09:48:04 +010038 struct lys_module *mod;
David Sedlák619db942019-07-03 14:47:30 +020039 struct lysp_module *lysp_mod;
David Sedlákda8ffa32019-07-08 14:17:10 +020040 struct yin_parser_ctx *yin_ctx;
David Sedlák79e50cb2019-06-05 16:33:09 +020041 bool finished_correctly;
David Sedlák68a1af12019-03-08 13:46:54 +010042};
David Sedlák872c7b42018-10-26 13:15:20 +020043
David Sedlák79e50cb2019-06-05 16:33:09 +020044#define BUFSIZE 1024
45char logbuf[BUFSIZE] = {0};
46int store = -1; /* negative for infinite logging, positive for limited logging */
47
48/* set to 0 to printing error messages to stderr instead of checking them in code */
49#define ENABLE_LOGGER_CHECKING 1
50
51#if ENABLE_LOGGER_CHECKING
52static void
53logger(LY_LOG_LEVEL level, const char *msg, const char *path)
54{
55 (void) level; /* unused */
56 if (store) {
57 if (path && path[0]) {
58 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
59 } else {
60 strncpy(logbuf, msg, BUFSIZE - 1);
61 }
62 if (store > 0) {
63 --store;
64 }
65 }
66}
67#endif
68
69#if ENABLE_LOGGER_CHECKING
70# define logbuf_assert(str) assert_string_equal(logbuf, str)
71#else
72# define logbuf_assert(str)
73#endif
74
75#define TEST_DUP_GENERIC(PREFIX, MEMBER, VALUE1, VALUE2, FUNC, RESULT, LINE, CLEANUP) \
76 str = PREFIX MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
77 assert_int_equal(LY_EVALID, FUNC(&ctx, &str, RESULT)); \
78 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
79 CLEANUP
80
David Sedlák8e7bda82019-07-16 17:57:50 +020081int
82setup_ly_ctx(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +010083{
84 struct state *st = NULL;
David Sedlák3b4db242018-10-19 16:11:01 +020085
David Sedlák68a1af12019-03-08 13:46:54 +010086 /* allocate state variable */
87 (*state) = st = calloc(1, sizeof(*st));
88 if (!st) {
89 fprintf(stderr, "Memmory allocation failed");
90 return EXIT_FAILURE;
91 }
David Sedlák872c7b42018-10-26 13:15:20 +020092
David Sedlák68a1af12019-03-08 13:46:54 +010093 /* create new libyang context */
94 ly_ctx_new(NULL, 0, &st->ctx);
David Sedlák872c7b42018-10-26 13:15:20 +020095
David Sedlák8e7bda82019-07-16 17:57:50 +020096 return EXIT_SUCCESS;
97}
98
99int
100destroy_ly_ctx(void **state)
101{
102 struct state *st = *state;
103 ly_ctx_destroy(st->ctx, NULL);
104 free(st);
105
106 return EXIT_SUCCESS;
107}
108
109static int
110setup_f(void **state)
111{
112 struct state *st = *state;
113
114#if ENABLE_LOGGER_CHECKING
115 /* setup logger */
116 ly_set_log_clb(logger, 1);
117#endif
118
David Sedlák68a1af12019-03-08 13:46:54 +0100119 /* allocate new module */
120 st->mod = calloc(1, sizeof(*st->mod));
121 st->mod->ctx = st->ctx;
122
David Sedlák619db942019-07-03 14:47:30 +0200123 /* allocate new parsed module */
124 st->lysp_mod = calloc(1, sizeof(*st->lysp_mod));
125 st->lysp_mod->mod = calloc(1, sizeof(*st->lysp_mod->mod));
126 st->lysp_mod->mod->ctx = st->ctx;
127
128 /* allocate parser context */
David Sedlákda8ffa32019-07-08 14:17:10 +0200129 st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
130 st->yin_ctx->xml_ctx.ctx = st->ctx;
131 st->yin_ctx->xml_ctx.line = 1;
David Sedlák8f5bce02019-06-03 16:41:08 +0200132
David Sedlák68a1af12019-03-08 13:46:54 +0100133 return EXIT_SUCCESS;
David Sedlák3b4db242018-10-19 16:11:01 +0200134}
135
136static int
David Sedlák68a1af12019-03-08 13:46:54 +0100137teardown_f(void **state)
138{
139 struct state *st = *(struct state **)state;
David Sedlák619db942019-07-03 14:47:30 +0200140 struct lys_module *temp;
David Sedlák68a1af12019-03-08 13:46:54 +0100141
David Sedlák79e50cb2019-06-05 16:33:09 +0200142#if ENABLE_LOGGER_CHECKING
143 /* teardown logger */
144 if (!st->finished_correctly && logbuf[0] != '\0') {
145 fprintf(stderr, "%s\n", logbuf);
146 }
147#endif
148
David Sedlák619db942019-07-03 14:47:30 +0200149 temp = st->lysp_mod->mod;
150
David Sedlákda8ffa32019-07-08 14:17:10 +0200151 lyxml_context_clear(&st->yin_ctx->xml_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100152 lys_module_free(st->mod, NULL);
David Sedlák619db942019-07-03 14:47:30 +0200153 lysp_module_free(st->lysp_mod);
154 lys_module_free(temp, NULL);
David Sedlákda8ffa32019-07-08 14:17:10 +0200155 free(st->yin_ctx);
David Sedlák68a1af12019-03-08 13:46:54 +0100156
157 return EXIT_SUCCESS;
158}
159
David Sedlák392af4f2019-06-04 16:02:42 +0200160static struct state*
161reset_state(void **state)
162{
David Sedlák79e50cb2019-06-05 16:33:09 +0200163 ((struct state *)*state)->finished_correctly = true;
David Sedlák555c7202019-07-04 12:14:12 +0200164 logbuf[0] = '\0';
David Sedlák392af4f2019-06-04 16:02:42 +0200165 teardown_f(state);
166 setup_f(state);
167
168 return *state;
169}
170
David Sedlák79e50cb2019-06-05 16:33:09 +0200171void
172logbuf_clean(void)
173{
174 logbuf[0] = '\0';
175}
176
David Sedlák68a1af12019-03-08 13:46:54 +0100177static void
David Sedlák392af4f2019-06-04 16:02:42 +0200178test_yin_parse_module(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +0100179{
180 LY_ERR ret = LY_SUCCESS;
181 struct state *st = *state;
182
183 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200184 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
185 name=\"example-foo\"\
David Sedlák18730132019-03-15 15:51:34 +0100186 xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\
187 xmlns:foo=\"urn:example:foo\"\
188 xmlns:myext=\"urn:example:extensions\">\
David Sedlákcd0c9512019-03-29 13:23:06 +0100189 <namespace uri=\"urn:example:foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedláka7406952019-04-05 10:33:07 +0200190 <prefix xmlns:myxt=\"urn:emple:extensions\" value=\"foo\" xmlns:myext=\"urn:example:extensions\"/>\
David Sedlákd9d3a312019-06-04 09:47:10 +0200191 </module>",
David Sedlák68a1af12019-03-08 13:46:54 +0100192 st->mod);
193
194 assert_int_equal(ret, LY_SUCCESS);
195 assert_string_equal(st->mod->parsed->mod->name, "example-foo");
196 assert_string_equal(st->mod->parsed->mod->prefix, "foo");
David Sedlákcd0c9512019-03-29 13:23:06 +0100197 assert_string_equal(st->mod->parsed->mod->ns, "urn:example:foo");
David Sedlák392af4f2019-06-04 16:02:42 +0200198
199 st = reset_state(state);
200 ret = yin_parse_module(st->ctx,
David Sedlák2b214ac2019-06-06 16:11:03 +0200201 "<module name=\"example-foo\">\
202 <invalid-tag uri=\"urn:example:foo\"\"/>\
203 </module>",
204 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200205 assert_int_equal(ret, LY_EVALID);
206
207 st = reset_state(state);
208 ret = yin_parse_module(st->ctx,
David Sedlák8f7a1172019-06-20 14:42:18 +0200209 "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\
David Sedlák57715b12019-06-17 13:05:22 +0200210 </module>",
David Sedlák2b214ac2019-06-06 16:11:03 +0200211 st->mod);
David Sedlák392af4f2019-06-04 16:02:42 +0200212 assert_int_equal(ret, LY_EVALID);
David Sedlák882a8072019-07-08 17:51:20 +0200213 logbuf_assert("Missing mandatory attribute name of module element. Line number 1.");
David Sedlák392af4f2019-06-04 16:02:42 +0200214
215 st = reset_state(state);
216 ret = yin_parse_module(st->ctx,
217 "",
218 st->mod);
219 assert_int_equal(ret, LY_EVALID);
David Sedlák79e50cb2019-06-05 16:33:09 +0200220 logbuf_assert("Invalid keyword \"(null)\", expected \"module\" or \"submodule\". Line number 1.");
221 st->finished_correctly = true;
David Sedlák3b4db242018-10-19 16:11:01 +0200222}
223
224static void
David Sedlák1bccdfa2019-06-17 15:55:27 +0200225test_yin_match_keyword(void **state)
David Sedlák3b4db242018-10-19 16:11:01 +0200226{
David Sedlák8f7a1172019-06-20 14:42:18 +0200227 struct state *st = *state;
David Sedlák3b4db242018-10-19 16:11:01 +0200228
David Sedlák8f7a1172019-06-20 14:42:18 +0200229 const char *prefix, *name;
230 struct yin_arg_record *args = NULL;
231 size_t prefix_len, name_len;
232 /* create mock yin namespace in xml context */
233 const char *data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200234 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
235 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák8f7a1172019-06-20 14:42:18 +0200236 LY_ARRAY_FREE(args);
237
David Sedlákc1771b12019-07-10 15:55:46 +0200238 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydatax", strlen("anydatax"), prefix, prefix_len, YANG_NONE), YANG_NONE);
239 assert_int_equal(yin_match_keyword(st->yin_ctx, "asdasd", strlen("asdasd"), prefix, prefix_len, YANG_NONE), YANG_NONE);
240 assert_int_equal(yin_match_keyword(st->yin_ctx, "", 0, prefix, prefix_len, YANG_NONE), YANG_NONE);
241 assert_int_equal(yin_match_keyword(st->yin_ctx, "anydata", strlen("anydata"), prefix, prefix_len, YANG_NONE), YANG_ANYDATA);
242 assert_int_equal(yin_match_keyword(st->yin_ctx, "anyxml", strlen("anyxml"), prefix, prefix_len, YANG_NONE), YANG_ANYXML);
243 assert_int_equal(yin_match_keyword(st->yin_ctx, "argument", strlen("argument"), prefix, prefix_len, YANG_NONE), YANG_ARGUMENT);
244 assert_int_equal(yin_match_keyword(st->yin_ctx, "augment", strlen("augment"), prefix, prefix_len, YANG_NONE), YANG_AUGMENT);
245 assert_int_equal(yin_match_keyword(st->yin_ctx, "base", strlen("base"), prefix, prefix_len, YANG_NONE), YANG_BASE);
246 assert_int_equal(yin_match_keyword(st->yin_ctx, "belongs-to", strlen("belongs-to"), prefix, prefix_len, YANG_NONE), YANG_BELONGS_TO);
247 assert_int_equal(yin_match_keyword(st->yin_ctx, "bit", strlen("bit"), prefix, prefix_len, YANG_NONE), YANG_BIT);
248 assert_int_equal(yin_match_keyword(st->yin_ctx, "case", strlen("case"), prefix, prefix_len, YANG_NONE), YANG_CASE);
249 assert_int_equal(yin_match_keyword(st->yin_ctx, "choice", strlen("choice"), prefix, prefix_len, YANG_NONE), YANG_CHOICE);
250 assert_int_equal(yin_match_keyword(st->yin_ctx, "config", strlen("config"), prefix, prefix_len, YANG_NONE), YANG_CONFIG);
251 assert_int_equal(yin_match_keyword(st->yin_ctx, "contact", strlen("contact"), prefix, prefix_len, YANG_NONE), YANG_CONTACT);
252 assert_int_equal(yin_match_keyword(st->yin_ctx, "container", strlen("container"), prefix, prefix_len, YANG_NONE), YANG_CONTAINER);
253 assert_int_equal(yin_match_keyword(st->yin_ctx, "default", strlen("default"), prefix, prefix_len, YANG_NONE), YANG_DEFAULT);
254 assert_int_equal(yin_match_keyword(st->yin_ctx, "description", strlen("description"), prefix, prefix_len, YANG_NONE), YANG_DESCRIPTION);
255 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviate", strlen("deviate"), prefix, prefix_len, YANG_NONE), YANG_DEVIATE);
256 assert_int_equal(yin_match_keyword(st->yin_ctx, "deviation", strlen("deviation"), prefix, prefix_len, YANG_NONE), YANG_DEVIATION);
257 assert_int_equal(yin_match_keyword(st->yin_ctx, "enum", strlen("enum"), prefix, prefix_len, YANG_NONE), YANG_ENUM);
258 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);
259 assert_int_equal(yin_match_keyword(st->yin_ctx, "error-message", strlen("error-message"), prefix, prefix_len, YANG_NONE), YANG_ERROR_MESSAGE);
260 assert_int_equal(yin_match_keyword(st->yin_ctx, "extension", strlen("extension"), prefix, prefix_len, YANG_NONE), YANG_EXTENSION);
261 assert_int_equal(yin_match_keyword(st->yin_ctx, "feature", strlen("feature"), prefix, prefix_len, YANG_NONE), YANG_FEATURE);
262 assert_int_equal(yin_match_keyword(st->yin_ctx, "fraction-digits", strlen("fraction-digits"), prefix, prefix_len, YANG_NONE), YANG_FRACTION_DIGITS);
263 assert_int_equal(yin_match_keyword(st->yin_ctx, "grouping", strlen("grouping"), prefix, prefix_len, YANG_NONE), YANG_GROUPING);
264 assert_int_equal(yin_match_keyword(st->yin_ctx, "identity", strlen("identity"), prefix, prefix_len, YANG_NONE), YANG_IDENTITY);
265 assert_int_equal(yin_match_keyword(st->yin_ctx, "if-feature", strlen("if-feature"), prefix, prefix_len, YANG_NONE), YANG_IF_FEATURE);
266 assert_int_equal(yin_match_keyword(st->yin_ctx, "import", strlen("import"), prefix, prefix_len, YANG_NONE), YANG_IMPORT);
267 assert_int_equal(yin_match_keyword(st->yin_ctx, "include", strlen("include"), prefix, prefix_len, YANG_NONE), YANG_INCLUDE);
268 assert_int_equal(yin_match_keyword(st->yin_ctx, "input", strlen("input"), prefix, prefix_len, YANG_NONE), YANG_INPUT);
269 assert_int_equal(yin_match_keyword(st->yin_ctx, "key", strlen("key"), prefix, prefix_len, YANG_NONE), YANG_KEY);
270 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf", strlen("leaf"), prefix, prefix_len, YANG_NONE), YANG_LEAF);
271 assert_int_equal(yin_match_keyword(st->yin_ctx, "leaf-list", strlen("leaf-list"), prefix, prefix_len, YANG_NONE), YANG_LEAF_LIST);
272 assert_int_equal(yin_match_keyword(st->yin_ctx, "length", strlen("length"), prefix, prefix_len, YANG_NONE), YANG_LENGTH);
273 assert_int_equal(yin_match_keyword(st->yin_ctx, "list", strlen("list"), prefix, prefix_len, YANG_NONE), YANG_LIST);
274 assert_int_equal(yin_match_keyword(st->yin_ctx, "mandatory", strlen("mandatory"), prefix, prefix_len, YANG_NONE), YANG_MANDATORY);
275 assert_int_equal(yin_match_keyword(st->yin_ctx, "max-elements", strlen("max-elements"), prefix, prefix_len, YANG_NONE), YANG_MAX_ELEMENTS);
276 assert_int_equal(yin_match_keyword(st->yin_ctx, "min-elements", strlen("min-elements"), prefix, prefix_len, YANG_NONE), YANG_MIN_ELEMENTS);
277 assert_int_equal(yin_match_keyword(st->yin_ctx, "modifier", strlen("modifier"), prefix, prefix_len, YANG_NONE), YANG_MODIFIER);
278 assert_int_equal(yin_match_keyword(st->yin_ctx, "module", strlen("module"), prefix, prefix_len, YANG_NONE), YANG_MODULE);
279 assert_int_equal(yin_match_keyword(st->yin_ctx, "must", strlen("must"), prefix, prefix_len, YANG_NONE), YANG_MUST);
280 assert_int_equal(yin_match_keyword(st->yin_ctx, "namespace", strlen("namespace"), prefix, prefix_len, YANG_NONE), YANG_NAMESPACE);
281 assert_int_equal(yin_match_keyword(st->yin_ctx, "notification", strlen("notification"), prefix, prefix_len, YANG_NONE), YANG_NOTIFICATION);
282 assert_int_equal(yin_match_keyword(st->yin_ctx, "ordered-by", strlen("ordered-by"), prefix, prefix_len, YANG_NONE), YANG_ORDERED_BY);
283 assert_int_equal(yin_match_keyword(st->yin_ctx, "organization", strlen("organization"), prefix, prefix_len, YANG_NONE), YANG_ORGANIZATION);
284 assert_int_equal(yin_match_keyword(st->yin_ctx, "output", strlen("output"), prefix, prefix_len, YANG_NONE), YANG_OUTPUT);
285 assert_int_equal(yin_match_keyword(st->yin_ctx, "path", strlen("path"), prefix, prefix_len, YANG_NONE), YANG_PATH);
286 assert_int_equal(yin_match_keyword(st->yin_ctx, "pattern", strlen("pattern"), prefix, prefix_len, YANG_NONE), YANG_PATTERN);
287 assert_int_equal(yin_match_keyword(st->yin_ctx, "position", strlen("position"), prefix, prefix_len, YANG_NONE), YANG_POSITION);
288 assert_int_equal(yin_match_keyword(st->yin_ctx, "prefix", strlen("prefix"), prefix, prefix_len, YANG_NONE), YANG_PREFIX);
289 assert_int_equal(yin_match_keyword(st->yin_ctx, "presence", strlen("presence"), prefix, prefix_len, YANG_NONE), YANG_PRESENCE);
290 assert_int_equal(yin_match_keyword(st->yin_ctx, "range", strlen("range"), prefix, prefix_len, YANG_NONE), YANG_RANGE);
291 assert_int_equal(yin_match_keyword(st->yin_ctx, "reference", strlen("reference"), prefix, prefix_len, YANG_NONE), YANG_REFERENCE);
292 assert_int_equal(yin_match_keyword(st->yin_ctx, "refine", strlen("refine"), prefix, prefix_len, YANG_NONE), YANG_REFINE);
293 assert_int_equal(yin_match_keyword(st->yin_ctx, "require-instance", strlen("require-instance"), prefix, prefix_len, YANG_NONE), YANG_REQUIRE_INSTANCE);
294 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision", strlen("revision"), prefix, prefix_len, YANG_NONE), YANG_REVISION);
295 assert_int_equal(yin_match_keyword(st->yin_ctx, "revision-date", strlen("revision-date"), prefix, prefix_len, YANG_NONE), YANG_REVISION_DATE);
296 assert_int_equal(yin_match_keyword(st->yin_ctx, "rpc", strlen("rpc"), prefix, prefix_len, YANG_NONE), YANG_RPC);
297 assert_int_equal(yin_match_keyword(st->yin_ctx, "status", strlen("status"), prefix, prefix_len, YANG_NONE), YANG_STATUS);
298 assert_int_equal(yin_match_keyword(st->yin_ctx, "submodule", strlen("submodule"), prefix, prefix_len, YANG_NONE), YANG_SUBMODULE);
299 assert_int_equal(yin_match_keyword(st->yin_ctx, "type", strlen("type"), prefix, prefix_len, YANG_NONE), YANG_TYPE);
300 assert_int_equal(yin_match_keyword(st->yin_ctx, "typedef", strlen("typedef"), prefix, prefix_len, YANG_NONE), YANG_TYPEDEF);
301 assert_int_equal(yin_match_keyword(st->yin_ctx, "unique", strlen("unique"), prefix, prefix_len, YANG_NONE), YANG_UNIQUE);
302 assert_int_equal(yin_match_keyword(st->yin_ctx, "units", strlen("units"), prefix, prefix_len, YANG_NONE), YANG_UNITS);
303 assert_int_equal(yin_match_keyword(st->yin_ctx, "uses", strlen("uses"), prefix, prefix_len, YANG_NONE), YANG_USES);
304 assert_int_equal(yin_match_keyword(st->yin_ctx, "value", strlen("value"), prefix, prefix_len, YANG_NONE), YANG_VALUE);
305 assert_int_equal(yin_match_keyword(st->yin_ctx, "when", strlen("when"), prefix, prefix_len, YANG_NONE), YANG_WHEN);
306 assert_int_equal(yin_match_keyword(st->yin_ctx, "yang-version", strlen("yang-version"), prefix, prefix_len, YANG_NONE), YANG_YANG_VERSION);
307 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 +0200308
309 st->finished_correctly = true;
David Sedlák872c7b42018-10-26 13:15:20 +0200310}
David Sedlák3b4db242018-10-19 16:11:01 +0200311
David Sedlák872c7b42018-10-26 13:15:20 +0200312static void
David Sedlák060b00e2019-06-19 11:12:06 +0200313test_yin_match_argument_name(void **state)
David Sedlák872c7b42018-10-26 13:15:20 +0200314{
David Sedlák68a1af12019-03-08 13:46:54 +0100315 (void)state; /* unused */
David Sedlák872c7b42018-10-26 13:15:20 +0200316
David Sedlák060b00e2019-06-19 11:12:06 +0200317 assert_int_equal(yin_match_argument_name("", 5), YIN_ARG_UNKNOWN);
318 assert_int_equal(yin_match_argument_name("qwertyasd", 5), YIN_ARG_UNKNOWN);
319 assert_int_equal(yin_match_argument_name("conditionasd", 8), YIN_ARG_UNKNOWN);
320 assert_int_equal(yin_match_argument_name("condition", 9), YIN_ARG_CONDITION);
321 assert_int_equal(yin_match_argument_name("date", 4), YIN_ARG_DATE);
322 assert_int_equal(yin_match_argument_name("module", 6), YIN_ARG_MODULE);
323 assert_int_equal(yin_match_argument_name("name", 4), YIN_ARG_NAME);
324 assert_int_equal(yin_match_argument_name("tag", 3), YIN_ARG_TAG);
325 assert_int_equal(yin_match_argument_name("target-node", 11), YIN_ARG_TARGET_NODE);
326 assert_int_equal(yin_match_argument_name("text", 4), YIN_ARG_TEXT);
327 assert_int_equal(yin_match_argument_name("uri", 3), YIN_ARG_URI);
328 assert_int_equal(yin_match_argument_name("value", 5), YIN_ARG_VALUE);
David Sedlák3b4db242018-10-19 16:11:01 +0200329}
330
David Sedlák68a1af12019-03-08 13:46:54 +0100331static void
David Sedlákb1a78352019-06-28 16:16:29 +0200332test_yin_parse_element_generic(void **state)
333{
334 const char *prefix, *name;
335 struct state *st = *state;
336 struct lysp_ext_instance exts;
337 size_t prefix_len, name_len;
338 LY_ERR ret;
339
340 memset(&exts, 0, sizeof(exts));
341
342 const char *data = "<elem attr=\"value\">text_value</elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200343 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
344 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 +0200345 assert_int_equal(ret, LY_SUCCESS);
David Sedlák1fdb2522019-07-09 16:22:57 +0200346 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb1a78352019-06-28 16:16:29 +0200347 assert_string_equal(exts.child->stmt, "elem");
348 assert_string_equal(exts.child->arg, "text_value");
David Sedlákb1a78352019-06-28 16:16:29 +0200349 assert_string_equal(exts.child->child->stmt, "attr");
350 assert_string_equal(exts.child->child->arg, "value");
351 assert_true(exts.child->child->flags & LYS_YIN_ATTR);
David Sedlákb1a78352019-06-28 16:16:29 +0200352 lysp_ext_instance_free(st->ctx, &exts);
David Sedlák5392a212019-07-01 09:19:10 +0200353 st = reset_state(state);
354
355 data = "<elem></elem>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200356 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
357 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 +0200358 assert_int_equal(ret, LY_SUCCESS);
359 assert_string_equal(exts.child->stmt, "elem");
360 assert_null(exts.child->child);
361 assert_null(exts.child->arg);
David Sedlákda8ffa32019-07-08 14:17:10 +0200362 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák5392a212019-07-01 09:19:10 +0200363 lysp_ext_instance_free(st->ctx, &exts);
364
David Sedlákb1a78352019-06-28 16:16:29 +0200365 st->finished_correctly = true;
366}
367
368static void
369test_yin_parse_extension_instance(void **state)
370{
371 LY_ERR ret;
372 struct state *st = *state;
373 const char *prefix, *name;
374 size_t prefix_len, name_len;
375 struct yin_arg_record *args = NULL;
376 struct lysp_ext_instance *exts = NULL;
David Sedlákb1a78352019-06-28 16:16:29 +0200377 const char *data = "<ext value1=\"test\" value=\"test2\"><subelem>text</subelem></ext>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200378 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
379 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák1f90d252019-07-10 17:09:32 +0200380 ret = yin_parse_extension_instance(st->yin_ctx, args, &data, name2fullname(name, prefix_len),
David Sedlák619db942019-07-03 14:47:30 +0200381 namelen2fulllen(name_len, prefix_len), LYEXT_SUBSTMT_CONTACT, 0, &exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200382 assert_int_equal(ret, LY_SUCCESS);
383 assert_string_equal(exts->name, "ext");
384 assert_int_equal(exts->insubstmt_index, 0);
385 assert_true(exts->insubstmt == LYEXT_SUBSTMT_CONTACT);
386 assert_true(exts->yin & LYS_YIN);
387 assert_string_equal(exts->child->stmt, "value1");
388 assert_string_equal(exts->child->arg, "test");
389 assert_null(exts->child->child);
390 assert_true(exts->child->flags & LYS_YIN_ATTR);
391 assert_string_equal(exts->child->next->stmt, "value");
392 assert_string_equal(exts->child->next->arg, "test2");
393 assert_null(exts->child->next->child);
394 assert_true(exts->child->next->flags & LYS_YIN_ATTR);
395
396 assert_string_equal(exts->child->next->next->stmt, "subelem");
397 assert_string_equal(exts->child->next->next->arg, "text");
398 assert_null(exts->child->next->next->child);
399 assert_null(exts->child->next->next->next);
400 assert_false(exts->child->next->next->flags & LYS_YIN_ATTR);
David Sedlákda8ffa32019-07-08 14:17:10 +0200401 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákb1a78352019-06-28 16:16:29 +0200402 LY_ARRAY_FREE(args);
403 lysp_ext_instance_free(st->ctx, exts);
404 LY_ARRAY_FREE(exts);
David Sedlákf250ecf2019-07-01 11:02:05 +0200405 exts = NULL;
406 args = NULL;
407 st = reset_state(state);
408
409 data = "<extension-elem />";
David Sedlákda8ffa32019-07-08 14:17:10 +0200410 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix, &prefix_len, &name, &name_len);
411 yin_load_attributes(st->yin_ctx, &data, &args);
David Sedlák1f90d252019-07-10 17:09:32 +0200412 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 +0200413 assert_int_equal(ret, LY_SUCCESS);
414 assert_string_equal(exts->name, "extension-elem");
415 assert_null(exts->argument);
416 assert_null(exts->child);
417 assert_int_equal(exts->insubstmt, LYEXT_SUBSTMT_CONTACT);
418 assert_int_equal(exts->insubstmt_index, 0);
419 assert_true(exts->yin & LYS_YIN);
David Sedlákda8ffa32019-07-08 14:17:10 +0200420 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlákf250ecf2019-07-01 11:02:05 +0200421 LY_ARRAY_FREE(args);
422 lysp_ext_instance_free(st->ctx, exts);
423 LY_ARRAY_FREE(exts);
David Sedlákb1a78352019-06-28 16:16:29 +0200424 st->finished_correctly = true;
425}
426
David Sedlák555c7202019-07-04 12:14:12 +0200427static void
428test_yin_parse_content(void **state)
429{
430 struct state *st = *state;
431 LY_ERR ret = LY_SUCCESS;
432 struct sized_string name, prefix;
433 const char *data = "<prefix value=\"a_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
434 "<custom xmlns=\"my-ext\">"
435 "totally amazing extension"
436 "</custom>"
David Sedlák986cb412019-07-04 13:10:11 +0200437 "<extension name=\"ext\">"
438 "<argument name=\"argname\"></argument>"
439 "<description><text>desc</text></description>"
440 "<reference><text>ref</text></reference>"
441 "<status value=\"deprecated\"></status>"
442 "</extension>"
David Sedlák555c7202019-07-04 12:14:12 +0200443 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
David Sedlák32488102019-07-15 17:44:10 +0200444 "<if-feature name=\"foo\"></if-feature>"
David Sedlák32eee7b2019-07-09 12:38:44 +0200445 "<when condition=\"condition...\">"
446 "<reference><text>when_ref</text></reference>"
447 "<description><text>when_desc</text></description>"
448 "</when>"
David Sedláke1a30302019-07-10 13:49:38 +0200449 "<config value=\"true\"/>"
David Sedlákc1771b12019-07-10 15:55:46 +0200450 "<error-message>"
451 "<value>error-msg</value>"
452 "</error-message>"
David Sedlák2ce1be62019-07-10 16:15:09 +0200453 "<error-app-tag value=\"err-app-tag\"/>"
David Sedláka5b1d382019-07-10 16:31:09 +0200454 "<units name=\"radians\"></units>"
David Sedláke7084ce2019-07-10 16:44:15 +0200455 "<default value=\"default-value\"/>"
David Sedlák5545f5d2019-07-11 11:55:16 +0200456 "<position value=\"25\"></position>"
457 "<value value=\"-5\"/>"
David Sedlákcf5569a2019-07-11 13:31:34 +0200458 "<require-instance value=\"true\"></require-instance>"
David Sedlákb7296dd2019-07-11 14:58:38 +0200459 "<range value=\"5..10\" />"
David Sedlák438ae432019-07-11 15:36:54 +0200460 "<length value=\"baf\"/>"
David Sedlákd3983112019-07-12 11:20:56 +0200461 "<pattern value='pattern'>"
462 "<modifier value='invert-match'/>"
463 "</pattern>"
David Sedlákfd5b9c32019-07-12 15:33:13 +0200464 "<enum name=\"yay\">"
465 "</enum>"
David Sedlák555c7202019-07-04 12:14:12 +0200466 "</prefix>";
467 struct lysp_ext_instance *exts = NULL;
David Sedlák5f8191e2019-07-08 16:35:52 +0200468 const char **if_features = NULL;
David Sedlák555c7202019-07-04 12:14:12 +0200469 struct yin_arg_record *attrs = NULL;
David Sedláke7084ce2019-07-10 16:44:15 +0200470 const char *value, *err_msg, *app_tag, *units, *def;
David Sedlák986cb412019-07-04 13:10:11 +0200471 struct lysp_ext *ext_def = NULL;
David Sedlák32eee7b2019-07-09 12:38:44 +0200472 struct lysp_when *when_p = NULL;
David Sedlákcf5569a2019-07-11 13:31:34 +0200473 struct lysp_type_enum pos_enum = {}, val_enum = {};
David Sedlákfd5b9c32019-07-12 15:33:13 +0200474 struct lysp_type req_type = {}, range_type = {}, len_type = {}, patter_type = {}, enum_type = {};
David Sedláke1a30302019-07-10 13:49:38 +0200475 uint8_t config = 0;
David Sedlák555c7202019-07-04 12:14:12 +0200476
David Sedlákda8ffa32019-07-08 14:17:10 +0200477 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
478 yin_load_attributes(st->yin_ctx, &data, &attrs);
David Sedlák555c7202019-07-04 12:14:12 +0200479
David Sedlákfd5b9c32019-07-12 15:33:13 +0200480 struct yin_subelement subelems[17] = {
David Sedlák438ae432019-07-11 15:36:54 +0200481 {YANG_CONFIG, &config, 0},
482 {YANG_DEFAULT, &def, 0},
David Sedlákfd5b9c32019-07-12 15:33:13 +0200483 {YANG_ENUM, &enum_type, 0},
David Sedlák438ae432019-07-11 15:36:54 +0200484 {YANG_ERROR_APP_TAG, &app_tag, 0},
485 {YANG_ERROR_MESSAGE, &err_msg, 0},
486 {YANG_EXTENSION, &ext_def, 0},
487 {YANG_IF_FEATURE, &if_features, 0},
488 {YANG_LENGTH, &len_type, 0},
David Sedlákd3983112019-07-12 11:20:56 +0200489 {YANG_PATTERN, &patter_type, 0},
David Sedlák438ae432019-07-11 15:36:54 +0200490 {YANG_RANGE, &range_type, 0},
491 {YANG_REQUIRE_INSTANCE, &req_type, 0},
492 {YANG_UNITS, &units, 0},
David Sedlák374d2b32019-07-17 15:06:55 +0200493 {YANG_POSITION, &pos_enum, 0},
David Sedlák438ae432019-07-11 15:36:54 +0200494 {YANG_VALUE, &val_enum, 0},
495 {YANG_WHEN, &when_p, 0},
496 {YANG_CUSTOM, NULL, 0},
497 {YIN_TEXT, &value, 0}
David Sedlákd3983112019-07-12 11:20:56 +0200498 };
David Sedlákfd5b9c32019-07-12 15:33:13 +0200499 ret = yin_parse_content(st->yin_ctx, subelems, 17, &data, YANG_PREFIX, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200500 assert_int_equal(ret, LY_SUCCESS);
David Sedlák1fdb2522019-07-09 16:22:57 +0200501 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
David Sedlák2ce1be62019-07-10 16:15:09 +0200502 /* check parsed values */
David Sedláke7084ce2019-07-10 16:44:15 +0200503 assert_string_equal(def, "default-value");
David Sedlák555c7202019-07-04 12:14:12 +0200504 assert_string_equal(exts->name, "custom");
505 assert_string_equal(exts->argument, "totally amazing extension");
506 assert_string_equal(value, "wsefsdf");
David Sedláka5b1d382019-07-10 16:31:09 +0200507 assert_string_equal(units, "radians");
David Sedlák32eee7b2019-07-09 12:38:44 +0200508 assert_string_equal(when_p->cond, "condition...");
509 assert_string_equal(when_p->dsc, "when_desc");
510 assert_string_equal(when_p->ref, "when_ref");
David Sedláke1a30302019-07-10 13:49:38 +0200511 assert_int_equal(config, LYS_CONFIG_W);
David Sedlák5545f5d2019-07-11 11:55:16 +0200512 assert_int_equal(pos_enum.value, 25);
513 assert_true(pos_enum.flags | LYS_SET_VALUE);
514 assert_int_equal(val_enum.value, -5);
515 assert_true(val_enum.flags | LYS_SET_VALUE);
David Sedlákcf5569a2019-07-11 13:31:34 +0200516 assert_int_equal(req_type.require_instance, 1);
517 assert_true(req_type.flags |= LYS_SET_REQINST);
David Sedlákb7296dd2019-07-11 14:58:38 +0200518 assert_string_equal(range_type.range->arg, "5..10");
519 assert_true(range_type.flags | LYS_SET_RANGE);
David Sedlákc1771b12019-07-10 15:55:46 +0200520 assert_string_equal(err_msg, "error-msg");
David Sedlák2ce1be62019-07-10 16:15:09 +0200521 assert_string_equal(app_tag, "err-app-tag");
David Sedlákfd5b9c32019-07-12 15:33:13 +0200522 assert_string_equal(enum_type.enums->name, "yay");
David Sedlák438ae432019-07-11 15:36:54 +0200523 assert_string_equal(len_type.length->arg, "baf");
524 assert_true(len_type.flags | LYS_SET_LENGTH);
David Sedlákd3983112019-07-12 11:20:56 +0200525 assert_string_equal(patter_type.patterns->arg, "\x015pattern");
526 assert_true(patter_type.flags | LYS_SET_PATTERN);
David Sedlák2ce1be62019-07-10 16:15:09 +0200527 /* cleanup */
David Sedlák555c7202019-07-04 12:14:12 +0200528 lysp_ext_instance_free(st->ctx, exts);
David Sedlák32eee7b2019-07-09 12:38:44 +0200529 lysp_when_free(st->ctx, when_p);
David Sedlák986cb412019-07-04 13:10:11 +0200530 lysp_ext_free(st->ctx, ext_def);
David Sedlák5f8191e2019-07-08 16:35:52 +0200531 FREE_STRING(st->ctx, *if_features);
David Sedlákc1771b12019-07-10 15:55:46 +0200532 FREE_STRING(st->ctx, err_msg);
David Sedlák2ce1be62019-07-10 16:15:09 +0200533 FREE_STRING(st->ctx, app_tag);
David Sedláka5b1d382019-07-10 16:31:09 +0200534 FREE_STRING(st->ctx, units);
David Sedlákd3983112019-07-12 11:20:56 +0200535 FREE_STRING(st->ctx, patter_type.patterns->arg);
David Sedláke7084ce2019-07-10 16:44:15 +0200536 FREE_STRING(st->ctx, def);
David Sedlákb7296dd2019-07-11 14:58:38 +0200537 FREE_STRING(st->ctx, range_type.range->arg);
David Sedlák438ae432019-07-11 15:36:54 +0200538 FREE_STRING(st->ctx, len_type.length->arg);
David Sedlákfd5b9c32019-07-12 15:33:13 +0200539 FREE_STRING(st->ctx, enum_type.enums->name);
David Sedlákb7296dd2019-07-11 14:58:38 +0200540 FREE_STRING(st->ctx, value);
David Sedlák5f8191e2019-07-08 16:35:52 +0200541 LY_ARRAY_FREE(if_features);
David Sedlák555c7202019-07-04 12:14:12 +0200542 LY_ARRAY_FREE(exts);
David Sedlák986cb412019-07-04 13:10:11 +0200543 LY_ARRAY_FREE(ext_def);
David Sedlák555c7202019-07-04 12:14:12 +0200544 LY_ARRAY_FREE(attrs);
David Sedlákd3983112019-07-12 11:20:56 +0200545 LY_ARRAY_FREE(patter_type.patterns);
David Sedlákfd5b9c32019-07-12 15:33:13 +0200546 LY_ARRAY_FREE(enum_type.enums);
David Sedlák32eee7b2019-07-09 12:38:44 +0200547 free(when_p);
David Sedlákb7296dd2019-07-11 14:58:38 +0200548 free(range_type.range);
David Sedlák438ae432019-07-11 15:36:54 +0200549 free(len_type.length);
David Sedlák555c7202019-07-04 12:14:12 +0200550 attrs = NULL;
David Sedlák555c7202019-07-04 12:14:12 +0200551 st = reset_state(state);
552
553 /* test unique subelem */
554 const char *prefix_value;
555 struct yin_subelement subelems2[2] = {{YANG_PREFIX, &prefix_value, 0},
556 {YIN_TEXT, &value, YIN_SUBELEM_UNIQUE}};
557 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
558 "<prefix value=\"inv_mod\" />"
559 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
560 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
561 "</module>";
David Sedlákda8ffa32019-07-08 14:17:10 +0200562 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
563 yin_load_attributes(st->yin_ctx, &data, &attrs);
564 ret = yin_parse_content(st->yin_ctx, subelems2, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200565 assert_int_equal(ret, LY_EVALID);
566 logbuf_assert("Redefinition of text element in module element. Line number 1.");
567 lydict_remove(st->ctx, prefix_value);
568 lydict_remove(st->ctx, value);
569 st = reset_state(state);
570 LY_ARRAY_FREE(attrs);
571 attrs = NULL;
572
573 /* test first subelem */
574 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
575 "<prefix value=\"inv_mod\" />"
576 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
577 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
578 "</module>";
579 struct yin_subelement subelems3[2] = {{YANG_PREFIX, &prefix_value, 0},
580 {YIN_TEXT, &value, YIN_SUBELEM_FIRST}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200581 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
582 yin_load_attributes(st->yin_ctx, &data, &attrs);
583 ret = yin_parse_content(st->yin_ctx, subelems3, 2, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200584 assert_int_equal(ret, LY_EVALID);
585 logbuf_assert("Subelement text of module element must be defined as first subelement. Line number 1.");
586 lydict_remove(st->ctx, prefix_value);
587 st = reset_state(state);
588 LY_ARRAY_FREE(attrs);
589 attrs = NULL;
590
591 /* test mandatory subelem */
592 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
593 "</module>";
594 struct yin_subelement subelems4[1] = {{YANG_PREFIX, &prefix_value, YIN_SUBELEM_MANDATORY}};
David Sedlákda8ffa32019-07-08 14:17:10 +0200595 lyxml_get_element(&st->yin_ctx->xml_ctx, &data, &prefix.value, &prefix.len, &name.value, &name.len);
596 yin_load_attributes(st->yin_ctx, &data, &attrs);
597 ret = yin_parse_content(st->yin_ctx, subelems4, 1, &data, YANG_MODULE, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200598 assert_int_equal(ret, LY_EVALID);
599 logbuf_assert("Missing mandatory subelement prefix of module element. Line number 1.");
600 LY_ARRAY_FREE(attrs);
601
602 st->finished_correctly = true;
603}
604
David Sedlák92147b02019-07-09 14:01:01 +0200605static void
David Sedlák4a650532019-07-10 11:55:18 +0200606test_validate_value(void **state)
607{
608 struct state *st = *state;
609 assert_int_equal(yin_validate_value(st->yin_ctx, Y_IDENTIF_ARG, "#invalid", 8), LY_EVALID);
610 logbuf_assert("Invalid identifier character '#'. Line number 1.");
611 assert_int_equal(yin_validate_value(st->yin_ctx, Y_STR_ARG, "", 0), LY_SUCCESS);
612 assert_int_equal(yin_validate_value(st->yin_ctx, Y_IDENTIF_ARG, "pre:b", 5), LY_EVALID);
613 assert_int_equal(yin_validate_value(st->yin_ctx, Y_PREF_IDENTIF_ARG, "pre:b", 5), LY_SUCCESS);
614 assert_int_equal(yin_validate_value(st->yin_ctx, Y_PREF_IDENTIF_ARG, "pre:pre:b", 9), LY_EVALID);
615
616 st->finished_correctly = true;
617}
618
David Sedlák32488102019-07-15 17:44:10 +0200619static int
620setup_element_test(void **state)
621{
David Sedlák8e7bda82019-07-16 17:57:50 +0200622 struct state *st = *state;
David Sedlák32488102019-07-15 17:44:10 +0200623
624#if ENABLE_LOGGER_CHECKING
625 /* setup logger */
626 ly_set_log_clb(logger, 1);
627#endif
628
629 /* reset logbuf */
630 logbuf[0] = '\0';
David Sedlák32488102019-07-15 17:44:10 +0200631
632 /* allocate parser context */
633 st->yin_ctx = calloc(1, sizeof(*st->yin_ctx));
634 st->yin_ctx->xml_ctx.ctx = st->ctx;
635 st->yin_ctx->xml_ctx.line = 1;
636
637 return EXIT_SUCCESS;
638}
639
640static int
641teardown_element_test(void **state)
642{
643 struct state *st = *(struct state **)state;
644
645#if ENABLE_LOGGER_CHECKING
646 /* teardown logger */
647 if (!st->finished_correctly && logbuf[0] != '\0') {
648 fprintf(stderr, "%s\n", logbuf);
649 }
650#endif
651
652 lyxml_context_clear(&st->yin_ctx->xml_ctx);
David Sedlák32488102019-07-15 17:44:10 +0200653 free(st->yin_ctx);
David Sedlák32488102019-07-15 17:44:10 +0200654
655 return EXIT_SUCCESS;
656}
657
658#define ELEMENT_WRAPPER_START "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
659#define ELEMENT_WRAPPER_END "</module>"
660
661/* helper function to simplify unit test of each element using parse_content function */
662LY_ERR
663test_element_helper(struct state *st, const char **data, void *dest, const char **text,
664 struct lysp_ext_instance **exts, bool valid)
665{
666 struct yin_arg_record *attrs = NULL;
667 struct sized_string name, prefix;
668 LY_ERR ret = LY_SUCCESS;
669 struct yin_subelement subelems[71] = {
670 {YANG_ACTION, dest, 0},
671 {YANG_ANYDATA, dest, 0},
672 {YANG_ANYXML, dest, 0},
673 {YANG_ARGUMENT,dest, 0},
674 {YANG_AUGMENT, dest, 0},
675 {YANG_BASE, dest, 0},
676 {YANG_BELONGS_TO, dest, 0},
677 {YANG_BIT, dest, 0},
678 {YANG_CASE, dest, 0},
679 {YANG_CHOICE, dest, 0},
680 {YANG_CONFIG, dest, 0},
681 {YANG_CONTACT, dest, 0},
682 {YANG_CONTAINER, dest, 0},
683 {YANG_DEFAULT, dest, 0},
684 {YANG_DESCRIPTION, dest, 0},
685 {YANG_DEVIATE, dest, 0},
686 {YANG_DEVIATION, dest, 0},
687 {YANG_ENUM, dest, 0},
688 {YANG_ERROR_APP_TAG, dest, 0},
689 {YANG_ERROR_MESSAGE, dest, 0},
690 {YANG_EXTENSION, dest, 0},
691 {YANG_FEATURE, dest, 0},
692 {YANG_FRACTION_DIGITS, dest, 0},
693 {YANG_GROUPING, dest, 0},
694 {YANG_IDENTITY, dest, 0},
695 {YANG_IF_FEATURE, dest, 0},
696 {YANG_IMPORT, dest, 0},
697 {YANG_INCLUDE, dest, 0},
698 {YANG_INPUT, dest, 0},
699 {YANG_KEY, dest, 0},
700 {YANG_LEAF, dest, 0},
701 {YANG_LEAF_LIST, dest, 0},
702 {YANG_LENGTH, dest, 0},
703 {YANG_LIST, dest, 0},
704 {YANG_MANDATORY, dest, 0},
705 {YANG_MAX_ELEMENTS, dest, 0},
706 {YANG_MIN_ELEMENTS, dest, 0},
707 {YANG_MODIFIER, dest, 0},
708 {YANG_MODULE, dest, 0},
709 {YANG_MUST, dest, 0},
710 {YANG_NAMESPACE, dest, 0},
711 {YANG_NOTIFICATION, dest, 0},
712 {YANG_ORDERED_BY, dest, 0},
713 {YANG_ORGANIZATION, dest, 0},
714 {YANG_OUTPUT, dest, 0},
715 {YANG_PATH, dest, 0},
716 {YANG_PATTERN, dest, 0},
David Sedlák32488102019-07-15 17:44:10 +0200717 {YANG_PREFIX, dest, 0},
718 {YANG_PRESENCE, dest, 0},
719 {YANG_RANGE, dest, 0},
720 {YANG_REFERENCE, dest, 0},
721 {YANG_REFINE, dest, 0},
722 {YANG_REQUIRE_INSTANCE, dest, 0},
723 {YANG_REVISION, dest, 0},
724 {YANG_REVISION_DATE, dest, 0},
725 {YANG_RPC, dest, 0},
726 {YANG_STATUS, dest, 0},
727 {YANG_SUBMODULE, dest, 0},
728 {YANG_TYPE, dest, 0},
729 {YANG_TYPEDEF, dest, 0},
730 {YANG_UNIQUE, dest, 0},
731 {YANG_UNITS, dest, 0},
732 {YANG_USES, dest, 0},
David Sedlák374d2b32019-07-17 15:06:55 +0200733 {YANG_POSITION, dest, 0},
David Sedlák32488102019-07-15 17:44:10 +0200734 {YANG_VALUE, dest, 0},
735 {YANG_WHEN, dest, 0},
736 {YANG_YANG_VERSION, dest, 0},
737 {YANG_YIN_ELEMENT, dest, 0},
738 {YANG_CUSTOM, dest, 0},
739 {YIN_TEXT, dest, 0},
740 {YIN_VALUE, dest, 0}
741 };
742 LY_CHECK_RET(lyxml_get_element(&st->yin_ctx->xml_ctx, data, &prefix.value, &prefix.len, &name.value, &name.len));\
743 LY_CHECK_RET(yin_load_attributes(st->yin_ctx, data, &attrs));\
David Sedlák8e7bda82019-07-16 17:57:50 +0200744 ret = yin_parse_content(st->yin_ctx, subelems, 71, data, yin_match_keyword(st->yin_ctx, name.value, name.len, prefix.value, prefix.len, YANG_NONE), text, exts);
David Sedlák32488102019-07-15 17:44:10 +0200745 LY_ARRAY_FREE(attrs);
746 if (valid) {
747 assert_int_equal(st->yin_ctx->xml_ctx.status, LYXML_END);
748 }
749 /* reset status */
750 st->yin_ctx->xml_ctx.status = LYXML_ELEMENT;
751 return ret;
752}
753
754static void
755test_enum_bit_elem(void **state)
756{
757 /* yin_parse_enum_bit is function that is being mainly tested by this test */
758 struct state *st = *state;
759 struct lysp_type type = {};
760 const char *data;
761 data = ELEMENT_WRAPPER_START
762 "<enum name=\"enum-name\">"
763 "<if-feature name=\"feature\" />"
764 "<value value=\"55\" />"
765 "<status value=\"deprecated\" />"
766 "<description><text>desc...</text></description>"
767 "<reference><text>ref...</text></reference>"
768 "</enum>"
769 ELEMENT_WRAPPER_END;
770 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
771 assert_string_equal(*type.enums->iffeatures, "feature");
772 assert_int_equal(type.enums->value, 55);
773 assert_true(type.enums->flags | LYS_STATUS_DEPRC && type.enums->flags | LYS_SET_VALUE);
774 assert_string_equal(type.enums->dsc, "desc...");
775 assert_string_equal(type.enums->ref, "ref...");
776 lysp_type_free(st->ctx, &type);
777 memset(&type, 0, sizeof type);
778
779 /* todo bit element test */
780 st->finished_correctly = true;
781}
782
783static void
784test_meta_elem(void **state)
785{
786 struct state *st = *state;
787 char *value = NULL;
788 const char *data;
789
790 /* organization element */
791 data = ELEMENT_WRAPPER_START
792 "<organization><text>organization...</text></organization>"
793 ELEMENT_WRAPPER_END;
794 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, true), LY_SUCCESS);
795 assert_string_equal(value, "organization...");
796 FREE_STRING(st->ctx, value);
797 value = NULL;
798 /* contact element */
799 data = ELEMENT_WRAPPER_START
800 "<contact><text>contact...</text></contact>"
801 ELEMENT_WRAPPER_END;
802 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, true), LY_SUCCESS);
803 assert_string_equal(value, "contact...");
804 FREE_STRING(st->ctx, value);
805 value = NULL;
806 /* description element */
807 data = ELEMENT_WRAPPER_START
808 "<description><text>description...</text></description>"
809 ELEMENT_WRAPPER_END;
810 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, true), LY_SUCCESS);
811 assert_string_equal(value, "description...");
812 FREE_STRING(st->ctx, value);
813 value = NULL;
814 /* reference element */
815 data = ELEMENT_WRAPPER_START
816 "<reference><text>reference...</text></reference>"
817 ELEMENT_WRAPPER_END;
818 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, true), LY_SUCCESS);
819 assert_string_equal(value, "reference...");
820 FREE_STRING(st->ctx, value);
821 value = NULL;
822
823 /* missing text subelement */
824 data = ELEMENT_WRAPPER_START
825 "<reference>reference...</reference>"
826 ELEMENT_WRAPPER_END;
827 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, false), LY_EVALID);
828 logbuf_assert("Missing mandatory subelement text of reference element. Line number 1.");
829
830 st->finished_correctly = true;
831}
832
833static void
834test_import_elem(void **state)
835{
836 struct state *st = *state;
837 const char *data;
838 struct lys_module *lys_mod = calloc(1, sizeof *lys_mod);
839 struct lysp_module *lysp_mod = calloc(1, sizeof *lysp_mod);
840 lys_mod->ctx = st->ctx;
841 lysp_mod->mod = lys_mod;
842
843 /* max subelems */
844 data = ELEMENT_WRAPPER_START
845 "<import module=\"a\">"
846 "<prefix value=\"a_mod\"/>"
847 "<revision-date date=\"2015-01-01\"></revision-date>"
848 "<description><text>import description</text></description>"
849 "<reference><text>import reference</text></reference>"
850 "</import>"
851 ELEMENT_WRAPPER_END;
852 assert_int_equal(test_element_helper(st, &data, lysp_mod, NULL, NULL, true), LY_SUCCESS);
853 assert_string_equal(lysp_mod->imports->name, "a");
854 assert_string_equal(lysp_mod->imports->prefix, "a_mod");
855 assert_string_equal(lysp_mod->imports->rev, "2015-01-01");
856 assert_string_equal(lysp_mod->imports->dsc, "import description");
857 assert_string_equal(lysp_mod->imports->ref, "import reference");
858 lysp_module_free(lysp_mod);
859 lys_module_free(lys_mod, NULL);
860
861 /* min subelems */
862 lys_mod = calloc(1, sizeof *lys_mod);
863 lysp_mod = calloc(1, sizeof *lysp_mod);
864 lys_mod->ctx = st->ctx;
865 lysp_mod->mod = lys_mod;
866 data = ELEMENT_WRAPPER_START
867 "<import module=\"a\">"
868 "<prefix value=\"a_mod\"/>"
869 "</import>"
870 ELEMENT_WRAPPER_END;
871 assert_int_equal(test_element_helper(st, &data, lysp_mod, NULL, NULL, true), LY_SUCCESS);
872 assert_string_equal(lysp_mod->imports->prefix, "a_mod");
873 lysp_module_free(lysp_mod);
874 lys_module_free(lys_mod, NULL);
875
876 /* invalid (missing prefix) */
877 lys_mod = calloc(1, sizeof *lys_mod);
878 lysp_mod = calloc(1, sizeof *lysp_mod);
879 lys_mod->ctx = st->ctx;
880 lysp_mod->mod = lys_mod;
881 data = ELEMENT_WRAPPER_START "<import module=\"a\">""</import>" ELEMENT_WRAPPER_END;
882 assert_int_equal(test_element_helper(st, &data, lysp_mod, NULL, NULL, false), LY_EVALID);
883 logbuf_assert("Missing mandatory subelement prefix of import element. Line number 1.");
884 lysp_module_free(lysp_mod);
885 lys_module_free(lys_mod, NULL);
886
887 /* invalid reused prefix */
888 lys_mod = calloc(1, sizeof *lys_mod);
889 lysp_mod = calloc(1, sizeof *lysp_mod);
890 lys_mod->ctx = st->ctx;
891 lysp_mod->mod = lys_mod;
892 data = ELEMENT_WRAPPER_START
893 "<import module=\"a\">"
894 "<prefix value=\"a_mod\"/>"
895 "</import>"
896 "<import module=\"a\">"
897 "<prefix value=\"a_mod\"/>"
898 "</import>"
899 ELEMENT_WRAPPER_END;
900 assert_int_equal(test_element_helper(st, &data, lysp_mod, NULL, NULL, false), LY_EVALID);
901 logbuf_assert("Prefix \"a_mod\" already used to import \"a\" module. Line number 1.");
902 lysp_module_free(lysp_mod);
903 lys_module_free(lys_mod, NULL);
904
905 st->finished_correctly = true;
906}
907
908static void
909test_status_elem(void **state)
910{
911 struct state *st = *state;
912 const char *data;
913 uint16_t flags = 0;
914
915 /* test valid values */
916 data = ELEMENT_WRAPPER_START "<status value=\"current\" />" ELEMENT_WRAPPER_END;
917 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
918 assert_true(flags | LYS_STATUS_CURR);
919
920 data = ELEMENT_WRAPPER_START "<status value=\"deprecated\" />" ELEMENT_WRAPPER_END;
921 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
922 assert_true(flags | LYS_STATUS_DEPRC);
923
924 data = ELEMENT_WRAPPER_START "<status value=\"obsolete\"></status>" ELEMENT_WRAPPER_END;
925 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
926 assert_true(flags | LYS_STATUS_OBSLT);
927
928 /* test invalid value */
929 data = ELEMENT_WRAPPER_START "<status value=\"invalid\"></status>" ELEMENT_WRAPPER_END;
930 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, false), LY_EVALID);
931 logbuf_assert("Invalid value \"invalid\" of \"status\". Line number 1.");
932 st->finished_correctly = true;
933}
934
935static void
936test_ext_elem(void **state)
937{
938 struct state *st = *state;
939 const char *data;
940 struct lysp_ext *ext = NULL;
941
942 /* max subelems */
943 data = ELEMENT_WRAPPER_START
944 "<extension name=\"ext_name\">"
945 "<argument name=\"arg\"></argument>"
946 "<status value=\"current\"/>"
947 "<description><text>ext_desc</text></description>"
948 "<reference><text>ext_ref</text></reference>"
949 "</extension>"
950 ELEMENT_WRAPPER_END;
951 assert_int_equal(test_element_helper(st, &data, &ext, NULL, NULL, true), LY_SUCCESS);
952 assert_string_equal(ext->name, "ext_name");
953 assert_string_equal(ext->argument, "arg");
954 assert_true(ext->flags | LYS_STATUS_CURR);
955 assert_string_equal(ext->dsc, "ext_desc");
956 assert_string_equal(ext->ref, "ext_ref");
957 lysp_ext_free(st->ctx, ext);
958 LY_ARRAY_FREE(ext);
959 ext = NULL;
960
961 /* min subelems */
962 data = ELEMENT_WRAPPER_START "<extension name=\"ext_name\"></extension>" ELEMENT_WRAPPER_END;
963 assert_int_equal(test_element_helper(st, &data, &ext, NULL, NULL, true), LY_SUCCESS);
964 assert_string_equal(ext->name, "ext_name");
965 lysp_ext_free(st->ctx, ext);
966 LY_ARRAY_FREE(ext);
967 ext = NULL;
968
969 st->finished_correctly = true;
970}
971
972static void
973test_yin_element_elem(void **state)
974{
975 struct state *st = *state;
976 const char *data;
977 uint16_t flags = 0;
978
979 data = ELEMENT_WRAPPER_START "<yin-element value=\"true\" />" ELEMENT_WRAPPER_END;
980 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
981 assert_true(flags | LYS_YINELEM_TRUE);
982
983 data = ELEMENT_WRAPPER_START "<yin-element value=\"false\" />" ELEMENT_WRAPPER_END;
984 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
985 assert_true(flags | LYS_YINELEM_TRUE);
986
987 data = ELEMENT_WRAPPER_START "<yin-element value=\"invalid\" />" ELEMENT_WRAPPER_END;
988 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, false), LY_EVALID);
989 assert_true(flags | LYS_YINELEM_TRUE);
990 logbuf_assert("Invalid value \"invalid\" of \"yin-element\". Line number 1.");
991 st->finished_correctly = true;
992}
993
994static void
995test_yangversion_elem(void **state)
996{
997 struct state *st = *state;
998 const char *data;
999 uint8_t version = 0;
1000
1001 /* valid values */
1002 data = ELEMENT_WRAPPER_START "<yang-version value=\"1.0\" />" ELEMENT_WRAPPER_END;
1003 assert_int_equal(test_element_helper(st, &data, &version, NULL, NULL, true), LY_SUCCESS);
1004 assert_true(version | LYS_VERSION_1_0);
1005 assert_int_equal(st->yin_ctx->mod_version, LYS_VERSION_1_0);
1006
1007 data = ELEMENT_WRAPPER_START "<yang-version value=\"1.1\" />" ELEMENT_WRAPPER_END;
1008 assert_int_equal(test_element_helper(st, &data, &version, NULL, NULL, true), LY_SUCCESS);
1009 assert_true(version | LYS_VERSION_1_1);
1010 assert_int_equal(st->yin_ctx->mod_version, LYS_VERSION_1_1);
1011
1012 /* invalid value */
1013 data = ELEMENT_WRAPPER_START "<yang-version value=\"version\" />" ELEMENT_WRAPPER_END;
1014 assert_int_equal(test_element_helper(st, &data, &version, NULL, NULL, false), LY_EVALID);
1015 logbuf_assert("Invalid value \"version\" of \"yang-version\". Line number 1.");
1016
1017 st->finished_correctly = true;
1018}
1019
1020static void
1021test_mandatory_elem(void **state)
1022{
1023 struct state *st = *state;
1024 const char *data;
1025 uint16_t man = 0;
1026
1027 /* valid values */
1028 data = ELEMENT_WRAPPER_START "<mandatory value=\"true\" />" ELEMENT_WRAPPER_END;
1029 assert_int_equal(test_element_helper(st, &data, &man, NULL, NULL, true), LY_SUCCESS);
1030 assert_int_equal(man, LYS_MAND_TRUE);
1031 man = 0;
1032
1033 data = ELEMENT_WRAPPER_START "<mandatory value=\"false\" />" ELEMENT_WRAPPER_END;
1034 assert_int_equal(test_element_helper(st, &data, &man, NULL, NULL, true), LY_SUCCESS);
1035 assert_int_equal(man, LYS_MAND_FALSE);
1036
1037 data = ELEMENT_WRAPPER_START "<mandatory value=\"invalid\" />" ELEMENT_WRAPPER_END;
1038 assert_int_equal(test_element_helper(st, &data, &man, NULL, NULL, false), LY_EVALID);
1039 logbuf_assert("Invalid value \"invalid\" of \"mandatory\". Line number 1.");
1040
1041 st->finished_correctly = true;
1042}
1043
David Sedlák8e7bda82019-07-16 17:57:50 +02001044static void
1045test_argument_elem(void **state)
1046{
1047 struct state *st = *state;
1048 const char *data;
1049 uint16_t flags = 0;
1050 const char *arg;
1051 struct yin_argument_meta arg_meta = {&flags, &arg};
1052 /* max subelems */
1053 data = ELEMENT_WRAPPER_START
1054 "<argument name=\"arg-name\">"
1055 "<yin-element value=\"true\" />"
1056 "</argument>"
1057 ELEMENT_WRAPPER_END;
1058 assert_int_equal(test_element_helper(st, &data, &arg_meta, NULL, NULL, true), LY_SUCCESS);
1059 assert_string_equal(arg, "arg-name");
1060 assert_true(flags | LYS_YINELEM_TRUE);
1061 flags = 0;
1062 FREE_STRING(st->ctx, arg);
1063 arg = NULL;
1064
1065 /* min subelems */
1066 data = ELEMENT_WRAPPER_START
1067 "<argument name=\"arg\">"
1068 "</argument>"
1069 ELEMENT_WRAPPER_END;
1070 assert_int_equal(test_element_helper(st, &data, &arg_meta, NULL, NULL, true), LY_SUCCESS);
1071 assert_string_equal(arg, "arg");
1072 assert_true(flags == 0);
1073 FREE_STRING(st->ctx, arg);
1074
1075 st->finished_correctly = true;
1076}
1077
1078static void
1079test_base_elem(void **state)
1080{
1081 struct state *st = *state;
1082 const char *data;
1083 const char **bases = NULL;
1084 struct lysp_type type = {};
1085
1086 /* as identity subelement */
1087 data = "<identity xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
1088 "<base name=\"base-name\"/>"
1089 "</identity>";
1090 assert_int_equal(test_element_helper(st, &data, &bases, NULL, NULL, true), LY_SUCCESS);
1091 assert_string_equal(*bases, "base-name");
1092 FREE_STRING(st->ctx, *bases);
1093 LY_ARRAY_FREE(bases);
1094
1095 /* as type subelement */
1096 data = "<type xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
1097 "<base name=\"base-name\"/>"
1098 "</type>";
1099 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1100 assert_string_equal(*type.bases, "base-name");
1101 assert_true(type.flags | LYS_SET_BASE);
1102 FREE_STRING(st->ctx, *type.bases);
1103 LY_ARRAY_FREE(type.bases);
1104
1105 st->finished_correctly = true;
1106}
1107
1108static void
1109test_belongsto_elem(void **state)
1110{
1111 struct state *st = *state;
1112 const char *data;
1113 struct lysp_submodule submod;
1114
1115 data = ELEMENT_WRAPPER_START
1116 "<belongs-to module=\"module-name\"><prefix value=\"pref\"/></belongs-to>"
1117 ELEMENT_WRAPPER_END;
1118 assert_int_equal(test_element_helper(st, &data, &submod, NULL, NULL, true), LY_SUCCESS);
1119 assert_string_equal(submod.belongsto, "module-name");
1120 assert_string_equal(submod.prefix, "pref");
1121 FREE_STRING(st->ctx, submod.belongsto);
1122 FREE_STRING(st->ctx, submod.prefix);
1123
1124 data = ELEMENT_WRAPPER_START "<belongs-to module=\"module-name\"></belongs-to>" ELEMENT_WRAPPER_END;
1125 assert_int_equal(test_element_helper(st, &data, &submod, NULL, NULL, false), LY_EVALID);
1126 logbuf_assert("Missing mandatory subelement prefix of belongs-to element. Line number 1.");
1127 FREE_STRING(st->ctx, submod.belongsto);
1128
1129 st->finished_correctly = true;
1130}
1131
1132static void
1133test_config_elem(void **state)
1134{
1135 struct state *st = *state;
1136 const char *data;
1137 uint16_t flags = 0;
1138
1139 data = ELEMENT_WRAPPER_START "<config value=\"true\"/>" ELEMENT_WRAPPER_END;
1140 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
1141 assert_true(flags | LYS_CONFIG_W);
1142 flags = 0;
1143
1144 data = ELEMENT_WRAPPER_START "<config value=\"false\"/>" ELEMENT_WRAPPER_END;
1145 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, true), LY_SUCCESS);
1146 assert_true(flags | LYS_CONFIG_R);
1147 flags = 0;
1148
1149 data = ELEMENT_WRAPPER_START "<config value=\"invalid\"/>" ELEMENT_WRAPPER_END;
1150 assert_int_equal(test_element_helper(st, &data, &flags, NULL, NULL, false), LY_EVALID);
1151 logbuf_assert("Invalid value \"invalid\" of \"config\". Line number 1.");
1152
1153 st->finished_correctly = true;
1154}
1155
1156static void
1157test_default_elem(void **state)
1158{
1159 struct state *st = *state;
1160 const char *data;
1161 const char *val = NULL;
1162
1163 data = ELEMENT_WRAPPER_START "<default value=\"defaul-value\"/>" ELEMENT_WRAPPER_END;
1164 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1165 assert_string_equal(val, "defaul-value");
1166 FREE_STRING(st->ctx, val);
1167 val = NULL;
1168
1169 data = ELEMENT_WRAPPER_START "<default/>" ELEMENT_WRAPPER_END;
1170 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, false), LY_EVALID);
1171 logbuf_assert("Missing mandatory attribute value of default element. Line number 1.");
1172
1173 st->finished_correctly = true;
1174}
1175
1176static void
1177test_err_app_tag_elem(void **state)
1178{
1179 struct state *st = *state;
1180 const char *data;
1181 const char *val = NULL;
1182
1183 data = ELEMENT_WRAPPER_START "<error-app-tag value=\"val\"/>" ELEMENT_WRAPPER_END;
1184 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1185 assert_string_equal(val, "val");
1186 FREE_STRING(st->ctx, val);
1187 val = NULL;
1188
1189 data = ELEMENT_WRAPPER_START "<error-app-tag/>" ELEMENT_WRAPPER_END;
1190 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, false), LY_EVALID);
1191 logbuf_assert("Missing mandatory attribute value of error-app-tag element. Line number 1.");
1192
1193 st->finished_correctly = true;
1194}
1195
1196static void
1197test_err_msg_elem(void **state)
1198{
1199 struct state *st = *state;
1200 const char *data;
1201 const char *val = NULL;
1202
1203 data = ELEMENT_WRAPPER_START "<error-message><value>val</value></error-message>" ELEMENT_WRAPPER_END;
1204 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1205 assert_string_equal(val, "val");
1206 FREE_STRING(st->ctx, val);
1207
1208 data = ELEMENT_WRAPPER_START "<error-message></error-message>" ELEMENT_WRAPPER_END;
1209 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, false), LY_EVALID);
1210 logbuf_assert("Missing mandatory subelement value of error-message element. Line number 1.");
1211
1212 st->finished_correctly = true;
1213}
1214
1215static void
1216test_fracdigits_elem(void **state)
1217{
1218 struct state *st = *state;
1219 const char *data;
1220 struct lysp_type type = {};
1221
1222 /* valid value */
1223 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"10\"></fraction-digits>" ELEMENT_WRAPPER_END;
1224 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1225 assert_int_equal(type.fraction_digits, 10);
1226 assert_true(type.flags | LYS_SET_FRDIGITS);
1227
1228 /* invalid values */
1229 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"-1\"></fraction-digits>" ELEMENT_WRAPPER_END;
1230 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1231 logbuf_assert("Invalid value \"-1\" of \"fraction-digits\". Line number 1.");
1232
1233 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"02\"></fraction-digits>" ELEMENT_WRAPPER_END;
1234 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1235 logbuf_assert("Invalid value \"02\" of \"fraction-digits\". Line number 1.");
1236
1237 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"1p\"></fraction-digits>" ELEMENT_WRAPPER_END;
1238 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1239 logbuf_assert("Invalid value \"1p\" of \"fraction-digits\". Line number 1.");
1240
1241 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"19\"></fraction-digits>" ELEMENT_WRAPPER_END;
1242 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1243 logbuf_assert("Invalid value \"19\" of \"fraction-digits\". Line number 1.");
1244
1245 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"999999999999999999\"></fraction-digits>" ELEMENT_WRAPPER_END;
1246 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1247 logbuf_assert("Invalid value \"999999999999999999\" of \"fraction-digits\". Line number 1.");
1248
1249 st->finished_correctly = true;
1250}
1251
1252static void
1253test_iffeature_elem(void **state)
1254{
1255 struct state *st = *state;
1256 const char *data;
1257 const char **iffeatures = NULL;
1258
1259 data = ELEMENT_WRAPPER_START "<if-feature name=\"local-storage\"></if-feature>" ELEMENT_WRAPPER_END;
1260 assert_int_equal(test_element_helper(st, &data, &iffeatures, NULL, NULL, true), LY_SUCCESS);
1261 assert_string_equal(*iffeatures, "local-storage");
1262 FREE_STRING(st->ctx, *iffeatures);
1263 LY_ARRAY_FREE(iffeatures);
1264 iffeatures = NULL;
1265
1266 data = ELEMENT_WRAPPER_START "<if-feature/>" ELEMENT_WRAPPER_END;
1267 assert_int_equal(test_element_helper(st, &data, &iffeatures, NULL, NULL, false), LY_EVALID);
1268 logbuf_assert("Missing mandatory attribute name of if-feature element. Line number 1.");
1269 LY_ARRAY_FREE(iffeatures);
1270 iffeatures = NULL;
1271
1272 st->finished_correctly = true;
1273}
1274
1275static void
1276test_length_elem(void **state)
1277{
1278 struct state *st = *state;
1279 const char *data;
1280 struct lysp_type type = {};
1281
1282 /* max subelems */
1283 data = ELEMENT_WRAPPER_START
1284 "<length value=\"length-str\">"
1285 "<error-message><value>err-msg</value></error-message>"
1286 "<error-app-tag value=\"err-app-tag\"/>"
1287 "<description><text>desc</text></description>"
1288 "<reference><text>ref</text></reference>"
1289 "</length>"
1290 ELEMENT_WRAPPER_END;
1291 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1292 assert_string_equal(type.length->arg, "length-str");
1293 assert_string_equal(type.length->emsg, "err-msg");
1294 assert_string_equal(type.length->eapptag, "err-app-tag");
1295 assert_string_equal(type.length->dsc, "desc");
1296 assert_string_equal(type.length->ref, "ref");
1297 assert_true(type.flags | LYS_SET_LENGTH);
1298 lysp_type_free(st->ctx, &type);
1299 memset(&type, 0, sizeof(type));
1300
1301 /* min subelems */
1302 data = ELEMENT_WRAPPER_START
1303 "<length value=\"length-str\">"
1304 "</length>"
1305 ELEMENT_WRAPPER_END;
1306 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1307 assert_string_equal(type.length->arg, "length-str");
1308 lysp_type_free(st->ctx, &type);
1309 assert_true(type.flags | LYS_SET_LENGTH);
1310 memset(&type, 0, sizeof(type));
1311
1312 data = ELEMENT_WRAPPER_START "<length></length>" ELEMENT_WRAPPER_END;
1313 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1314 logbuf_assert("Missing mandatory attribute value of length element. Line number 1.");
1315 lysp_type_free(st->ctx, &type);
1316 memset(&type, 0, sizeof(type));
1317
1318 st->finished_correctly = true;
1319}
1320
1321static void
1322test_modifier_elem(void **state)
1323{
1324 struct state *st = *state;
1325 const char *data;
1326 const char *pat = lydict_insert(st->ctx, "\006pattern", 8);
1327
1328 data = ELEMENT_WRAPPER_START "<modifier value=\"invert-match\" />" ELEMENT_WRAPPER_END;
1329 assert_int_equal(test_element_helper(st, &data, &pat, NULL, NULL, true), LY_SUCCESS);
1330 assert_string_equal(pat, "\x015pattern");
1331 FREE_STRING(st->ctx, pat);
1332
1333 pat = lydict_insert(st->ctx, "\006pattern", 8);
1334 data = ELEMENT_WRAPPER_START "<modifier value=\"invert\" />" ELEMENT_WRAPPER_END;
1335 assert_int_equal(test_element_helper(st, &data, &pat, NULL, NULL, false), LY_EVALID);
1336 logbuf_assert("Invalid value \"invert\" of \"modifier\". Line number 1.");
1337 FREE_STRING(st->ctx, pat);
1338
1339 st->finished_correctly = true;
1340}
1341
1342static void
1343test_namespace_elem(void **state)
1344{
1345 struct state *st = *state;
1346 const char *data;
1347 const char *ns;
1348
1349 data = ELEMENT_WRAPPER_START "<namespace uri=\"ns\"/>" ELEMENT_WRAPPER_END;
1350 assert_int_equal(test_element_helper(st, &data, &ns, NULL, NULL, true), LY_SUCCESS);
1351 assert_string_equal(ns, "ns");
1352 FREE_STRING(st->ctx, ns);
1353
1354 data = ELEMENT_WRAPPER_START "<namespace/>" ELEMENT_WRAPPER_END;
1355 assert_int_equal(test_element_helper(st, &data, &ns, NULL, NULL, false), LY_EVALID);
1356 logbuf_assert("Missing mandatory attribute uri of namespace element. Line number 1.");
1357
1358 st->finished_correctly = true;
1359}
1360
1361static void
1362test_path_elem(void **state)
1363{
1364 struct state *st = *state;
1365 const char *data;
1366 struct lysp_type type = {};
1367
1368 data = ELEMENT_WRAPPER_START "<path value=\"path-val\"/>" ELEMENT_WRAPPER_END;
1369 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1370 assert_string_equal("path-val", type.path);
1371 assert_true(type.flags | LYS_SET_PATH);
1372 lysp_type_free(st->ctx, &type);
1373
1374 st->finished_correctly = true;
1375}
1376
1377static void
1378test_pattern_elem(void **state)
1379{
1380 struct state *st = *state;
1381 const char *data;
1382 struct lysp_type type = {};
1383
1384 /* max subelems */
1385 data = ELEMENT_WRAPPER_START
1386 "<pattern value=\"super_pattern\">"
1387 "<modifier value=\"invert-match\"/>"
1388 "<error-message><value>err-msg-value</value></error-message>"
1389 "<error-app-tag value=\"err-app-tag-value\"/>"
1390 "<description><text>pattern-desc</text></description>"
1391 "<reference><text>pattern-ref</text></reference>"
1392 "</pattern>"
1393 ELEMENT_WRAPPER_END;
1394 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1395 assert_true(type.flags | LYS_SET_PATTERN);
1396 assert_string_equal(type.patterns->arg, "\x015super_pattern");
1397 assert_string_equal(type.patterns->dsc, "pattern-desc");
1398 assert_string_equal(type.patterns->eapptag, "err-app-tag-value");
1399 assert_string_equal(type.patterns->emsg, "err-msg-value");
1400 assert_string_equal(type.patterns->dsc, "pattern-desc");
1401 assert_string_equal(type.patterns->ref, "pattern-ref");
1402 lysp_type_free(st->ctx, &type);
1403 memset(&type, 0, sizeof(type));
1404
1405 /* min subelems */
1406 data = ELEMENT_WRAPPER_START "<pattern value=\"pattern\"> </pattern>" ELEMENT_WRAPPER_END;
1407 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1408 assert_string_equal(type.patterns->arg, "\x006pattern");
1409 lysp_type_free(st->ctx, &type);
1410 memset(&type, 0, sizeof(type));
1411
1412 st->finished_correctly = true;
1413}
1414
1415static void
1416test_value_position_elem(void **state)
1417{
1418 struct state *st = *state;
1419 const char *data;
1420 struct lysp_type_enum en = {};
1421
1422 /* valid values */
1423 data = ELEMENT_WRAPPER_START "<value value=\"55\" />" ELEMENT_WRAPPER_END;
1424 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1425 assert_int_equal(en.value, 55);
1426 assert_true(en.flags | LYS_SET_VALUE);
1427 memset(&en, 0, sizeof(en));
1428
1429 data = ELEMENT_WRAPPER_START "<value value=\"-55\"/>" ELEMENT_WRAPPER_END;
1430 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1431 assert_int_equal(en.value, -55);
1432 assert_true(en.flags | LYS_SET_VALUE);
1433 memset(&en, 0, sizeof(en));
1434
1435 data = ELEMENT_WRAPPER_START "<value value=\"0\"/>" ELEMENT_WRAPPER_END;
1436 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1437 assert_int_equal(en.value, 0);
1438 assert_true(en.flags | LYS_SET_VALUE);
1439 memset(&en, 0, sizeof(en));
1440
1441 data = ELEMENT_WRAPPER_START "<value value=\"-0\"/>" ELEMENT_WRAPPER_END;
1442 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1443 assert_int_equal(en.value, 0);
1444 assert_true(en.flags | LYS_SET_VALUE);
1445 memset(&en, 0, sizeof(en));
1446
1447 /* valid positions */
1448 data = ELEMENT_WRAPPER_START "<position value=\"55\" />" ELEMENT_WRAPPER_END;
1449 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1450 assert_int_equal(en.value, 55);
1451 assert_true(en.flags | LYS_SET_VALUE);
1452 memset(&en, 0, sizeof(en));
1453
1454 data = ELEMENT_WRAPPER_START "<position value=\"0\" />" ELEMENT_WRAPPER_END;
1455 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, true), LY_SUCCESS);
1456 assert_int_equal(en.value, 0);
1457 assert_true(en.flags | LYS_SET_VALUE);
1458 memset(&en, 0, sizeof(en));
1459
1460 /* invalid values */
1461 data = ELEMENT_WRAPPER_START "<value value=\"99999999999999999999999\"/>" ELEMENT_WRAPPER_END;
1462 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1463 logbuf_assert("Invalid value \"99999999999999999999999\" of \"value\". Line number 1.");
1464
1465 data = ELEMENT_WRAPPER_START "<value value=\"1k\"/>" ELEMENT_WRAPPER_END;
1466 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1467 logbuf_assert("Invalid value \"1k\" of \"value\". Line number 1.");
1468
David Sedlák69f01612019-07-17 11:41:08 +02001469 data = ELEMENT_WRAPPER_START "<value value=\"\"/>" ELEMENT_WRAPPER_END;
1470 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1471 logbuf_assert("Invalid value \"\" of \"value\". Line number 1.");
1472
David Sedlák8e7bda82019-07-16 17:57:50 +02001473 /*invalid positions */
1474 data = ELEMENT_WRAPPER_START "<position value=\"-5\"/>" ELEMENT_WRAPPER_END;
1475 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1476 logbuf_assert("Invalid value \"-5\" of \"position\". Line number 1.");
1477
1478 data = ELEMENT_WRAPPER_START "<position value=\"-0\"/>" ELEMENT_WRAPPER_END;
1479 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1480 logbuf_assert("Invalid value \"-0\" of \"position\". Line number 1.");
1481
1482 data = ELEMENT_WRAPPER_START "<position value=\"99999999999999999999\"/>" ELEMENT_WRAPPER_END;
1483 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1484 logbuf_assert("Invalid value \"99999999999999999999\" of \"position\". Line number 1.");
1485
David Sedlák69f01612019-07-17 11:41:08 +02001486 data = ELEMENT_WRAPPER_START "<position value=\"\"/>" ELEMENT_WRAPPER_END;
1487 assert_int_equal(test_element_helper(st, &data, &en, NULL, NULL, false), LY_EVALID);
1488 logbuf_assert("Invalid value \"\" of \"position\". Line number 1.");
1489
1490 st->finished_correctly = true;
1491}
1492
1493static void
1494test_prefix_elem(void **state)
1495{
1496 struct state *st = *state;
1497 const char *data;
1498 const char *value = NULL;
1499
1500 data = ELEMENT_WRAPPER_START "<prefix value=\"pref\"/>" ELEMENT_WRAPPER_END;
1501 assert_int_equal(test_element_helper(st, &data, &value, NULL, NULL, true), LY_SUCCESS);
1502 assert_string_equal(value, "pref");
1503 FREE_STRING(st->ctx, value);
1504
1505 st->finished_correctly = true;
1506}
1507
1508static void
1509test_range_elem(void **state)
1510{
1511 struct state *st = *state;
1512 const char *data;
1513 struct lysp_type type = {};
1514
1515 /* max subelems */
1516 data = ELEMENT_WRAPPER_START
1517 "<range value=\"range-str\">"
1518 "<error-message><value>err-msg</value></error-message>"
1519 "<error-app-tag value=\"err-app-tag\" />"
1520 "<description><text>desc</text></description>"
1521 "<reference><text>ref</text></reference>"
1522 "</range>"
1523 ELEMENT_WRAPPER_END;
1524 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1525 assert_string_equal(type.range->arg, "range-str");
1526 assert_string_equal(type.range->dsc, "desc");
1527 assert_string_equal(type.range->eapptag, "err-app-tag");
1528 assert_string_equal(type.range->emsg, "err-msg");
1529 assert_string_equal(type.range->ref, "ref");
1530 assert_true(type.flags | LYS_SET_RANGE);
1531 lysp_type_free(st->ctx, &type);
1532 memset(&type, 0, sizeof(type));
1533
1534 /* min subelems */
1535 data = ELEMENT_WRAPPER_START "<range value=\"range-str\"/>" ELEMENT_WRAPPER_END;
1536 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1537 assert_string_equal(type.range->arg, "range-str");
1538 lysp_type_free(st->ctx, &type);
1539 memset(&type, 0, sizeof(type));
1540
1541 st->finished_correctly = true;
1542}
1543
1544static void
1545test_reqinstance_elem(void **state)
1546{
1547 struct state *st = *state;
1548 const char *data;
1549 struct lysp_type type = {};
1550
1551 data = ELEMENT_WRAPPER_START "<require-instance value=\"true\"/>" ELEMENT_WRAPPER_END;
1552 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1553 assert_int_equal(type.require_instance, 1);
1554 assert_true(type.flags | LYS_SET_REQINST);
1555 memset(&type, 0, sizeof(type));
1556
1557 data = ELEMENT_WRAPPER_START "<require-instance value=\"false\"/>" ELEMENT_WRAPPER_END;
1558 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1559 assert_int_equal(type.require_instance, 0);
1560 assert_true(type.flags | LYS_SET_REQINST);
1561 memset(&type, 0, sizeof(type));
1562
1563 data = ELEMENT_WRAPPER_START "<require-instance value=\"invalid\"/>" ELEMENT_WRAPPER_END;
1564 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, false), LY_EVALID);
1565 memset(&type, 0, sizeof(type));
1566 logbuf_assert("Invalid value \"invalid\" of \"require-instance\". Line number 1.");
1567
1568 st->finished_correctly = true;
1569}
1570
1571static void
1572test_revision_date_elem(void **state)
1573{
1574 struct state *st = *state;
1575 const char *data;
1576 char rev[LY_REV_SIZE];
1577
1578 data = ELEMENT_WRAPPER_START "<revision-date date=\"2000-01-01\"/>" ELEMENT_WRAPPER_END;
1579 assert_int_equal(test_element_helper(st, &data, rev, NULL, NULL, true), LY_SUCCESS);
1580 assert_string_equal(rev, "2000-01-01");
1581
1582 data = ELEMENT_WRAPPER_START "<revision-date date=\"2000-50-05\"/>" ELEMENT_WRAPPER_END;
1583 assert_int_equal(test_element_helper(st, &data, rev, NULL, NULL, false), LY_EVALID);
1584 logbuf_assert("Invalid value \"2000-50-05\" of \"revision-date\". Line number 1.");
1585
1586 st->finished_correctly = true;
1587}
1588
1589static void
1590test_unique_elem(void **state)
1591{
1592 struct state *st = *state;
1593 const char *data;
1594 const char **values = NULL;
1595
1596 data = ELEMENT_WRAPPER_START "<unique tag=\"tag\"/>" ELEMENT_WRAPPER_END;
1597 assert_int_equal(test_element_helper(st, &data, &values, NULL, NULL, true), LY_SUCCESS);
1598 assert_string_equal(*values, "tag");
1599 FREE_STRING(st->ctx, *values);
1600 LY_ARRAY_FREE(values);
1601
1602 st->finished_correctly = true;
1603}
1604
1605static void
1606test_units_elem(void **state)
1607{
1608 struct state *st = *state;
1609 const char *data;
1610 const char *values = NULL;
1611
1612 data = ELEMENT_WRAPPER_START "<units name=\"name\"/>" ELEMENT_WRAPPER_END;
1613 assert_int_equal(test_element_helper(st, &data, &values, NULL, NULL, true), LY_SUCCESS);
1614 assert_string_equal(values, "name");
1615 FREE_STRING(st->ctx, values);
1616
1617 st->finished_correctly = true;
1618}
1619
1620static void
1621test_when_elem(void **state)
1622{
1623 struct state *st = *state;
1624 const char *data;
1625 struct lysp_when *when = NULL;
1626
1627 data = ELEMENT_WRAPPER_START
1628 "<when condition=\"cond\">"
1629 "<description><text>desc</text></description>"
1630 "<reference><text>ref</text></reference>"
1631 "</when>"
1632 ELEMENT_WRAPPER_END;
1633 assert_int_equal(test_element_helper(st, &data, &when, NULL, NULL, true), LY_SUCCESS);
1634 assert_string_equal(when->cond, "cond");
1635 assert_string_equal(when->dsc, "desc");
1636 assert_string_equal(when->ref, "ref");
1637 lysp_when_free(st->ctx, when);
1638 free(when);
1639 when = NULL;
1640
1641 data = ELEMENT_WRAPPER_START "<when condition=\"cond\" />" ELEMENT_WRAPPER_END;
1642 assert_int_equal(test_element_helper(st, &data, &when, NULL, NULL, true), LY_SUCCESS);
1643 assert_string_equal(when->cond, "cond");
1644 lysp_when_free(st->ctx, when);
1645 free(when);
1646 when = NULL;
1647
1648 st->finished_correctly = true;
1649}
1650
1651static void
1652test_yin_text_value_elem(void **state)
1653{
1654 struct state *st = *state;
1655 const char *data;
1656 const char *val;
1657
1658 data = ELEMENT_WRAPPER_START "<text>text</text>" ELEMENT_WRAPPER_END;
1659 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1660 assert_string_equal(val, "text");
1661 FREE_STRING(st->ctx, val);
1662
1663 data = "<error-message xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <value>text</value> </error-message>";
1664 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1665 assert_string_equal(val, "text");
1666 FREE_STRING(st->ctx, val);
1667
1668 data = ELEMENT_WRAPPER_START "<text></text>" ELEMENT_WRAPPER_END;
1669 assert_int_equal(test_element_helper(st, &data, &val, NULL, NULL, true), LY_SUCCESS);
1670 assert_string_equal("", val);
1671 FREE_STRING(st->ctx, val);
1672
David Sedlák8e7bda82019-07-16 17:57:50 +02001673 st->finished_correctly = true;
1674}
David Sedlák32488102019-07-15 17:44:10 +02001675
David Sedlák374d2b32019-07-17 15:06:55 +02001676static void
1677test_type_elem(void **state)
1678{
1679 struct state *st = *state;
1680 const char *data;
1681 struct lysp_type type = {};
1682
1683 /* max subelems */
1684 data = ELEMENT_WRAPPER_START
1685 "<type name=\"type-name\">"
1686 "<base name=\"base-name\"/>"
1687 "<bit name=\"bit\"/>"
1688 "<enum name=\"enum\"/>"
1689 "<fraction-digits value=\"2\"/>"
1690 "<length value=\"length\"/>"
1691 "<path value=\"path\"/>"
1692 "<pattern value=\"pattern\"/>"
1693 "<range value=\"range\" />"
1694 "<require-instance value=\"true\"/>"
1695 "<type name=\"sub-type-name\"/>"
1696 "</type>"
1697 ELEMENT_WRAPPER_END;
1698 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1699 assert_string_equal(type.name, "type-name");
1700 assert_string_equal(*type.bases, "base-name");
1701 assert_string_equal(type.bits->name, "bit");
1702 assert_string_equal(type.enums->name, "enum");
1703 assert_int_equal(type.fraction_digits, 2);
1704 assert_string_equal(type.length->arg, "length");
1705 assert_string_equal(type.path, "path");
1706 assert_string_equal(type.patterns->arg, "\006pattern");
1707 assert_string_equal(type.range->arg, "range");
1708 assert_int_equal(type.require_instance, 1);
1709 assert_string_equal(type.types->name, "sub-type-name");
1710 lysp_type_free(st->ctx, &type);
1711 assert_true(type.flags | LYS_SET_BASE);
1712 assert_true(type.flags | LYS_SET_BIT);
1713 assert_true(type.flags | LYS_SET_ENUM);
1714 assert_true(type.flags | LYS_SET_FRDIGITS);
1715 assert_true(type.flags | LYS_SET_LENGTH);
1716 assert_true(type.flags | LYS_SET_PATH);
1717 assert_true(type.flags | LYS_SET_PATTERN);
1718 assert_true(type.flags | LYS_SET_RANGE);
1719 assert_true(type.flags | LYS_SET_REQINST);
1720 assert_true(type.flags | LYS_SET_TYPE);
1721 memset(&type, 0, sizeof(type));
1722
1723 /* min subelems */
1724 data = ELEMENT_WRAPPER_START "<type name=\"type-name\"/>" ELEMENT_WRAPPER_END;
1725 assert_int_equal(test_element_helper(st, &data, &type, NULL, NULL, true), LY_SUCCESS);
1726 lysp_type_free(st->ctx, &type);
1727 memset(&type, 0, sizeof(type));
1728
1729 st->finished_correctly = true;
1730}
1731
David Sedlák1af868e2019-07-17 17:03:14 +02001732static void
1733test_max_elems_elem(void **state)
1734{
1735 struct state *st = *state;
1736 const char *data;
1737 struct lysp_node_list list = {};
1738 struct lysp_node_leaflist llist = {};
1739 struct lysp_refine refine = {};
1740
1741 data = "<refine xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"unbounded\"/> </refine>";
1742 assert_int_equal(test_element_helper(st, &data, &refine, NULL, NULL, true), LY_SUCCESS);
1743 assert_int_equal(refine.max, 0);
1744 assert_true(refine.flags | LYS_SET_MAX);
1745
1746 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"5\"/> </list>";
1747 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, true), LY_SUCCESS);
1748 assert_int_equal(list.max, 5);
1749 assert_true(list.flags | LYS_SET_MAX);
1750
1751 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"85\"/> </leaf-list>";
1752 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, true), LY_SUCCESS);
1753 assert_int_equal(llist.max, 85);
1754 assert_true(llist.flags | LYS_SET_MAX);
1755
1756 data = "<refine xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"10\"/> </refine>";
1757 assert_int_equal(test_element_helper(st, &data, &refine, NULL, NULL, true), LY_SUCCESS);
1758 assert_int_equal(refine.max, 10);
1759 assert_true(refine.flags | LYS_SET_MAX);
1760
1761 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"0\"/> </list>";
1762 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, false), LY_EVALID);
1763 logbuf_assert("Invalid value \"0\" of \"max-elements\". Line number 1.");
1764
1765 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"-10\"/> </list>";
1766 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, false), LY_EVALID);
1767 logbuf_assert("Invalid value \"-10\" of \"max-elements\". Line number 1.");
1768
1769 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"k\"/> </list>";
1770 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, false), LY_EVALID);
1771 logbuf_assert("Invalid value \"k\" of \"max-elements\". Line number 1.");
1772
1773 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"u12\"/> </list>";
1774 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, false), LY_EVALID);
1775 logbuf_assert("Invalid value \"u12\" of \"max-elements\". Line number 1.");
1776
1777 st->finished_correctly = true;
1778}
1779
David Sedlák09e18c92019-07-18 11:17:11 +02001780static void
1781test_min_elems_elem(void **state)
1782{
1783 struct state *st = *state;
1784 const char *data;
1785 struct lysp_node_list list = {};
1786 struct lysp_node_leaflist llist = {};
1787 struct lysp_refine refine = {};
1788
1789 data = "<refine xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"0\"/> </refine>";
1790 assert_int_equal(test_element_helper(st, &data, &refine, NULL, NULL, true), LY_SUCCESS);
1791 assert_int_equal(refine.min, 0);
1792 assert_true(refine.flags | LYS_SET_MIN);
1793
1794 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"41\"/> </list>";
1795 assert_int_equal(test_element_helper(st, &data, &list, NULL, NULL, true), LY_SUCCESS);
1796 assert_int_equal(list.min, 41);
1797 assert_true(list.flags | LYS_SET_MIN);
1798
1799 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"50\"/> </leaf-list>";
1800 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, true), LY_SUCCESS);
1801 assert_int_equal(llist.min, 50);
1802 assert_true(llist.flags | LYS_SET_MIN);
1803
1804 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"-5\"/> </leaf-list>";
1805 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, false), LY_EVALID);
1806 logbuf_assert("Value \"-5\" is out of \"min-elements\" bounds. Line number 1.");
1807
1808 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"99999999999999999\"/> </leaf-list>";
1809 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, false), LY_EVALID);
1810 logbuf_assert("Value \"99999999999999999\" is out of \"min-elements\" bounds. Line number 1.");
1811
1812 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"5k\"/> </leaf-list>";
1813 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, false), LY_EVALID);
1814 logbuf_assert("Invalid value \"5k\" of \"min-elements\". Line number 1.");
1815
1816 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"05\"/> </leaf-list>";
1817 assert_int_equal(test_element_helper(st, &data, &llist, NULL, NULL, false), LY_EVALID);
1818 logbuf_assert("Invalid value \"05\" of \"min-elements\". Line number 1.");
1819
1820 st->finished_correctly = true;
1821}
1822
David Sedlák3b4db242018-10-19 16:11:01 +02001823int
1824main(void)
1825{
1826
1827 const struct CMUnitTest tests[] = {
David Sedlák392af4f2019-06-04 16:02:42 +02001828 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup_f, teardown_f),
David Sedlák8f7a1172019-06-20 14:42:18 +02001829 cmocka_unit_test_setup_teardown(test_yin_match_keyword, setup_f, teardown_f),
David Sedlákb1a78352019-06-28 16:16:29 +02001830 cmocka_unit_test_setup_teardown(test_yin_parse_element_generic, setup_f, teardown_f),
1831 cmocka_unit_test_setup_teardown(test_yin_parse_extension_instance, setup_f, teardown_f),
David Sedlák555c7202019-07-04 12:14:12 +02001832 cmocka_unit_test_setup_teardown(test_yin_parse_content, setup_f, teardown_f),
David Sedlák4a650532019-07-10 11:55:18 +02001833 cmocka_unit_test_setup_teardown(test_validate_value, setup_f, teardown_f),
David Sedlák32488102019-07-15 17:44:10 +02001834
David Sedlák8e7bda82019-07-16 17:57:50 +02001835 cmocka_unit_test(test_yin_match_argument_name),
David Sedlák32488102019-07-15 17:44:10 +02001836 cmocka_unit_test_setup_teardown(test_enum_bit_elem, setup_element_test, teardown_element_test),
1837 cmocka_unit_test_setup_teardown(test_meta_elem, setup_element_test, teardown_element_test),
1838 cmocka_unit_test_setup_teardown(test_import_elem, setup_element_test, teardown_element_test),
1839 cmocka_unit_test_setup_teardown(test_status_elem, setup_element_test, teardown_element_test),
1840 cmocka_unit_test_setup_teardown(test_ext_elem, setup_element_test, teardown_element_test),
1841 cmocka_unit_test_setup_teardown(test_yin_element_elem, setup_element_test, teardown_element_test),
1842 cmocka_unit_test_setup_teardown(test_yangversion_elem, setup_element_test, teardown_element_test),
1843 cmocka_unit_test_setup_teardown(test_mandatory_elem, setup_element_test, teardown_element_test),
David Sedlák8e7bda82019-07-16 17:57:50 +02001844 cmocka_unit_test_setup_teardown(test_argument_elem, setup_element_test, teardown_element_test),
1845 cmocka_unit_test_setup_teardown(test_base_elem, setup_element_test, teardown_element_test),
1846 cmocka_unit_test_setup_teardown(test_belongsto_elem, setup_element_test, teardown_element_test),
1847 cmocka_unit_test_setup_teardown(test_config_elem, setup_element_test, teardown_element_test),
1848 cmocka_unit_test_setup_teardown(test_default_elem, setup_element_test, teardown_element_test),
1849 cmocka_unit_test_setup_teardown(test_err_app_tag_elem, setup_element_test, teardown_element_test),
1850 cmocka_unit_test_setup_teardown(test_err_msg_elem, setup_element_test, teardown_element_test),
1851 cmocka_unit_test_setup_teardown(test_fracdigits_elem, setup_element_test, teardown_element_test),
1852 cmocka_unit_test_setup_teardown(test_iffeature_elem, setup_element_test, teardown_element_test),
1853 cmocka_unit_test_setup_teardown(test_length_elem, setup_element_test, teardown_element_test),
1854 cmocka_unit_test_setup_teardown(test_modifier_elem, setup_element_test, teardown_element_test),
1855 cmocka_unit_test_setup_teardown(test_namespace_elem, setup_element_test, teardown_element_test),
1856 cmocka_unit_test_setup_teardown(test_path_elem, setup_element_test, teardown_element_test),
1857 cmocka_unit_test_setup_teardown(test_pattern_elem, setup_element_test, teardown_element_test),
1858 cmocka_unit_test_setup_teardown(test_value_position_elem, setup_element_test, teardown_element_test),
David Sedlák69f01612019-07-17 11:41:08 +02001859 cmocka_unit_test_setup_teardown(test_prefix_elem, setup_element_test, teardown_element_test),
1860 cmocka_unit_test_setup_teardown(test_range_elem, setup_element_test, teardown_element_test),
1861 cmocka_unit_test_setup_teardown(test_reqinstance_elem, setup_element_test, teardown_element_test),
1862 cmocka_unit_test_setup_teardown(test_revision_date_elem, setup_element_test, teardown_element_test),
1863 cmocka_unit_test_setup_teardown(test_unique_elem, setup_element_test, teardown_element_test),
1864 cmocka_unit_test_setup_teardown(test_units_elem, setup_element_test, teardown_element_test),
1865 cmocka_unit_test_setup_teardown(test_when_elem, setup_element_test, teardown_element_test),
1866 cmocka_unit_test_setup_teardown(test_yin_text_value_elem, setup_element_test, teardown_element_test),
David Sedlák374d2b32019-07-17 15:06:55 +02001867 cmocka_unit_test_setup_teardown(test_type_elem, setup_element_test, teardown_element_test),
David Sedlák1af868e2019-07-17 17:03:14 +02001868 cmocka_unit_test_setup_teardown(test_max_elems_elem, setup_element_test, teardown_element_test),
David Sedlák09e18c92019-07-18 11:17:11 +02001869 cmocka_unit_test_setup_teardown(test_min_elems_elem, setup_element_test, teardown_element_test),
David Sedlák3b4db242018-10-19 16:11:01 +02001870 };
1871
David Sedlák8e7bda82019-07-16 17:57:50 +02001872 return cmocka_run_group_tests(tests, setup_ly_ctx, destroy_ly_ctx);
David Sedlák3b4db242018-10-19 16:11:01 +02001873}