blob: 329fcdac907b069b3a787d7c841c677db7dad74c [file] [log] [blame]
David Sedlákb1ce3f82019-06-05 14:37:26 +02001/**
Michal Vasko12ef5362022-09-16 15:13:58 +02002 * @file test_yin.c
David Sedlákb1ce3f82019-06-05 14:37:26 +02003 * @author David Sedlák <xsedla1d@stud.fit.vutbr.cz>
Michal Vasko12ef5362022-09-16 15:13:58 +02004 * @author Michal Vasko <mvasko@cesnet.cz>
5 * @brief unit tests for YIN parser and printer
David Sedlákb1ce3f82019-06-05 14:37:26 +02006 *
Michal Vasko12ef5362022-09-16 15:13:58 +02007 * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
David Sedlákb1ce3f82019-06-05 14:37:26 +02008 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
Radek Iša56ca9e42020-09-08 18:42:00 +020015#define _UTEST_MAIN_
16#include "utests.h"
David Sedlákb1ce3f82019-06-05 14:37:26 +020017
Radek Krejcib4ac5a92020-11-23 17:54:33 +010018#include <stdbool.h>
David Sedlák3b4db242018-10-19 16:11:01 +020019#include <stdio.h>
20#include <string.h>
21
Michal Vaskoafac7822020-10-20 14:22:26 +020022#include "in.h"
Michal Vasko8f702ee2024-02-20 15:44:24 +010023#include "ly_common.h"
Radek Krejci70593c12020-06-13 20:48:09 +020024#include "parser_internal.h"
Michal Vasko405cc9e2020-12-01 12:01:27 +010025#include "schema_compile.h"
Radek Krejci8df109d2021-04-23 12:19:08 +020026#include "tree.h"
Radek Krejci859a15a2021-03-05 20:56:59 +010027#include "tree_edit.h"
Radek Krejci70593c12020-06-13 20:48:09 +020028#include "tree_schema.h"
29#include "tree_schema_internal.h"
30#include "xml.h"
31#include "xpath.h"
David Sedlák3b4db242018-10-19 16:11:01 +020032
Michal Vaskoafac7822020-10-20 14:22:26 +020033/* copied from parser_yin.c */
34enum yin_argument {
35 YIN_ARG_UNKNOWN = 0, /**< parsed argument can not be matched with any supported yin argument keyword */
36 YIN_ARG_NAME, /**< argument name */
37 YIN_ARG_TARGET_NODE, /**< argument target-node */
38 YIN_ARG_MODULE, /**< argument module */
39 YIN_ARG_VALUE, /**< argument value */
40 YIN_ARG_TEXT, /**< argument text */
41 YIN_ARG_CONDITION, /**< argument condition */
42 YIN_ARG_URI, /**< argument uri */
43 YIN_ARG_DATE, /**< argument data */
44 YIN_ARG_TAG, /**< argument tag */
45 YIN_ARG_NONE /**< empty (special value) */
46};
47
48struct yin_subelement {
49 enum ly_stmt type; /**< type of keyword */
50 void *dest; /**< meta infromation passed to responsible function (mostly information about where parsed subelement should be stored) */
51 uint16_t flags; /**< describes constraints of subelement can be set to YIN_SUBELEM_MANDATORY, YIN_SUBELEM_UNIQUE, YIN_SUBELEM_FIRST, YIN_SUBELEM_VER2, and YIN_SUBELEM_DEFAULT_TEXT */
52};
53
54struct import_meta {
55 const char *prefix; /**< module prefix. */
56 struct lysp_import **imports; /**< imports to add to. */
57};
58
59struct yin_argument_meta {
60 uint16_t *flags; /**< Argument flags */
61 const char **argument; /**< Argument value */
62};
63
64struct tree_node_meta {
65 struct lysp_node *parent; /**< parent node */
66 struct lysp_node **nodes; /**< linked list of siblings */
67};
68
69struct include_meta {
70 const char *name; /**< Module/submodule name. */
71 struct lysp_include **includes; /**< [Sized array](@ref sizedarrays) of parsed includes to add to. */
72};
73
74struct inout_meta {
75 struct lysp_node *parent; /**< Parent node. */
Radek Krejci2a9fc652021-01-22 17:44:34 +010076 struct lysp_node_action_inout *inout_p; /**< inout_p Input/output pointer to write to. */
Michal Vaskoafac7822020-10-20 14:22:26 +020077};
78
79struct minmax_dev_meta {
80 uint32_t *lim; /**< min/max value to write to. */
81 uint16_t *flags; /**< min/max flags to write to. */
82 struct lysp_ext_instance **exts; /**< extension instances to add to. */
83};
84
85#define YIN_SUBELEM_MANDATORY 0x01
86#define YIN_SUBELEM_UNIQUE 0x02
87#define YIN_SUBELEM_FIRST 0x04
88#define YIN_SUBELEM_VER2 0x08
89
90#define YIN_SUBELEM_PARSED 0x80
91
David Sedlák555c7202019-07-04 12:14:12 +020092/* prototypes of static functions */
Michal Vaskoafac7822020-10-20 14:22:26 +020093enum yin_argument yin_match_argument_name(const char *name, size_t len);
Michal Vasko2bf4af42023-01-04 12:08:38 +010094
Michal Vaskod0625d72022-10-06 15:02:50 +020095LY_ERR yin_parse_content(struct lysp_yin_ctx *ctx, struct yin_subelement *subelem_info, size_t subelem_info_size,
Michal Vasko193dacd2022-10-13 08:43:05 +020096 const void *parent, enum ly_stmt parent_stmt, const char **text_content, struct lysp_ext_instance **exts);
Michal Vaskod0625d72022-10-06 15:02:50 +020097LY_ERR yin_validate_value(struct lysp_yin_ctx *ctx, enum yang_arg val_type);
98enum ly_stmt yin_match_keyword(struct lysp_yin_ctx *ctx, const char *name, size_t name_len,
Michal Vaskoafac7822020-10-20 14:22:26 +020099 const char *prefix, size_t prefix_len, enum ly_stmt parrent);
Michal Vasko2bf4af42023-01-04 12:08:38 +0100100
Michal Vasko193dacd2022-10-13 08:43:05 +0200101LY_ERR yin_parse_extension_instance(struct lysp_yin_ctx *ctx, const void *parent, enum ly_stmt parent_stmt,
102 LY_ARRAY_COUNT_TYPE parent_stmt_index, struct lysp_ext_instance **exts);
Michal Vaskod0625d72022-10-06 15:02:50 +0200103LY_ERR yin_parse_element_generic(struct lysp_yin_ctx *ctx, enum ly_stmt parent, struct lysp_stmt **element);
104LY_ERR yin_parse_mod(struct lysp_yin_ctx *ctx, struct lysp_module *mod);
105LY_ERR yin_parse_submod(struct lysp_yin_ctx *ctx, struct lysp_submodule *submod);
Michal Vaskoafac7822020-10-20 14:22:26 +0200106
David Sedláke6cd89e2019-08-07 12:46:02 +0200107/* wrapping element used for mocking has nothing to do with real module structure */
108#define ELEMENT_WRAPPER_START "<status xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
109#define ELEMENT_WRAPPER_END "</status>"
110
Radek Iša56ca9e42020-09-08 18:42:00 +0200111#define TEST_1_CHECK_LYSP_EXT_INSTANCE(NODE, INSUBSTMT)\
Radek Krejci8df109d2021-04-23 12:19:08 +0200112 CHECK_LYSP_EXT_INSTANCE((NODE), NULL, 1, INSUBSTMT, 0, "myext:c-define", LY_VALUE_XML)
David Sedlák872c7b42018-10-26 13:15:20 +0200113
Michal Vaskod0625d72022-10-06 15:02:50 +0200114struct lysp_yin_ctx *YCTX;
Michal Vaskoc636ea42022-09-16 10:20:31 +0200115struct lysf_ctx fctx;
David Sedlák8e7bda82019-07-16 17:57:50 +0200116
117static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200118setup_ctx(void **state)
David Sedlák8e7bda82019-07-16 17:57:50 +0200119{
Michal Vasko8a67eff2021-12-07 14:04:47 +0100120 struct lysp_module *pmod;
121
David Sedlák619db942019-07-03 14:47:30 +0200122 /* allocate parser context */
Radek Iša56ca9e42020-09-08 18:42:00 +0200123 YCTX = calloc(1, sizeof(*YCTX));
Michal Vaskoc8806c82022-12-06 10:31:24 +0100124 YCTX->main_ctx = (struct lysp_ctx *)YCTX;
Radek Iša56ca9e42020-09-08 18:42:00 +0200125 YCTX->format = LYS_IN_YIN;
Michal Vasko8a67eff2021-12-07 14:04:47 +0100126 ly_set_new(&YCTX->parsed_mods);
David Sedlák8f5bce02019-06-03 16:41:08 +0200127
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200128 /* allocate new parsed module */
Michal Vasko8a67eff2021-12-07 14:04:47 +0100129 pmod = calloc(1, sizeof *pmod);
130 ly_set_add(YCTX->parsed_mods, pmod, 1, NULL);
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200131
132 /* allocate new module */
Michal Vasko8a67eff2021-12-07 14:04:47 +0100133 pmod->mod = calloc(1, sizeof *pmod->mod);
134 pmod->mod->ctx = UTEST_LYCTX;
135 pmod->mod->parsed = pmod;
Michal Vasko5d24f6c2020-10-13 13:49:06 +0200136
Radek Iša56ca9e42020-09-08 18:42:00 +0200137 return 0;
David Sedlák3b4db242018-10-19 16:11:01 +0200138}
139
140static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200141setup(void **state)
David Sedlák68a1af12019-03-08 13:46:54 +0100142{
Radek Iša56ca9e42020-09-08 18:42:00 +0200143 UTEST_SETUP;
David Sedlák68a1af12019-03-08 13:46:54 +0100144
Radek Iša56ca9e42020-09-08 18:42:00 +0200145 setup_ctx(state);
David Sedlák79e50cb2019-06-05 16:33:09 +0200146
Michal Vaskoc636ea42022-09-16 10:20:31 +0200147 fctx.ctx = UTEST_LYCTX;
148 fctx.mod = PARSER_CUR_PMOD(YCTX)->mod;
149
Radek Iša56ca9e42020-09-08 18:42:00 +0200150 return 0;
David Sedlák79e50cb2019-06-05 16:33:09 +0200151}
152
David Sedlák8985a142019-07-31 16:43:06 +0200153static int
Radek Iša56ca9e42020-09-08 18:42:00 +0200154teardown_ctx(void **UNUSED(state))
David Sedlák8985a142019-07-31 16:43:06 +0200155{
Michal Vaskoc636ea42022-09-16 10:20:31 +0200156 lys_module_free(&fctx, PARSER_CUR_PMOD(YCTX)->mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +0200157 lysp_yin_ctx_free(YCTX);
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 YCTX = NULL;
David Sedlák8985a142019-07-31 16:43:06 +0200159
Radek Iša56ca9e42020-09-08 18:42:00 +0200160 return 0;
David Sedlák8985a142019-07-31 16:43:06 +0200161}
162
Radek Iša56ca9e42020-09-08 18:42:00 +0200163static int
164teardown(void **state)
165{
166 teardown_ctx(state);
167
Michal Vaskoc636ea42022-09-16 10:20:31 +0200168 lysf_ctx_erase(&fctx);
169
Radek Iša56ca9e42020-09-08 18:42:00 +0200170 UTEST_TEARDOWN;
171
172 return 0;
173}
174
175#define RESET_STATE \
176 ly_in_free(UTEST_IN, 0); \
177 UTEST_IN = NULL; \
178 teardown_ctx(state); \
179 setup_ctx(state)
180
David Sedlák68a1af12019-03-08 13:46:54 +0100181static void
David Sedlák1bccdfa2019-06-17 15:55:27 +0200182test_yin_match_keyword(void **state)
David Sedlák3b4db242018-10-19 16:11:01 +0200183{
Michal Vaskob36053d2020-03-26 15:49:30 +0100184 const char *prefix;
185 size_t prefix_len;
Radek Iša56ca9e42020-09-08 18:42:00 +0200186
David Sedlák8f7a1172019-06-20 14:42:18 +0200187 /* create mock yin namespace in xml context */
Radek Iša56ca9e42020-09-08 18:42:00 +0200188 ly_in_new_memory("<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" />", &UTEST_IN);
189 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
190 prefix = YCTX->xmlctx->prefix;
191 prefix_len = YCTX->xmlctx->prefix_len;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100192
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 assert_int_equal(yin_match_keyword(YCTX, "anydatax", strlen("anydatax"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_NONE);
194 assert_int_equal(yin_match_keyword(YCTX, "asdasd", strlen("asdasd"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_NONE);
195 assert_int_equal(yin_match_keyword(YCTX, "", 0, prefix, prefix_len, LY_STMT_NONE), LY_STMT_NONE);
196 assert_int_equal(yin_match_keyword(YCTX, "anydata", strlen("anydata"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ANYDATA);
197 assert_int_equal(yin_match_keyword(YCTX, "anyxml", strlen("anyxml"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ANYXML);
198 assert_int_equal(yin_match_keyword(YCTX, "argument", strlen("argument"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ARGUMENT);
199 assert_int_equal(yin_match_keyword(YCTX, "augment", strlen("augment"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_AUGMENT);
200 assert_int_equal(yin_match_keyword(YCTX, "base", strlen("base"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_BASE);
201 assert_int_equal(yin_match_keyword(YCTX, "belongs-to", strlen("belongs-to"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_BELONGS_TO);
202 assert_int_equal(yin_match_keyword(YCTX, "bit", strlen("bit"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_BIT);
203 assert_int_equal(yin_match_keyword(YCTX, "case", strlen("case"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_CASE);
204 assert_int_equal(yin_match_keyword(YCTX, "choice", strlen("choice"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_CHOICE);
205 assert_int_equal(yin_match_keyword(YCTX, "config", strlen("config"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_CONFIG);
206 assert_int_equal(yin_match_keyword(YCTX, "contact", strlen("contact"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_CONTACT);
207 assert_int_equal(yin_match_keyword(YCTX, "container", strlen("container"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_CONTAINER);
208 assert_int_equal(yin_match_keyword(YCTX, "default", strlen("default"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_DEFAULT);
209 assert_int_equal(yin_match_keyword(YCTX, "description", strlen("description"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_DESCRIPTION);
210 assert_int_equal(yin_match_keyword(YCTX, "deviate", strlen("deviate"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_DEVIATE);
211 assert_int_equal(yin_match_keyword(YCTX, "deviation", strlen("deviation"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_DEVIATION);
212 assert_int_equal(yin_match_keyword(YCTX, "enum", strlen("enum"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ENUM);
213 assert_int_equal(yin_match_keyword(YCTX, "error-app-tag", strlen("error-app-tag"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ERROR_APP_TAG);
214 assert_int_equal(yin_match_keyword(YCTX, "error-message", strlen("error-message"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ERROR_MESSAGE);
215 assert_int_equal(yin_match_keyword(YCTX, "extension", strlen("extension"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_EXTENSION);
216 assert_int_equal(yin_match_keyword(YCTX, "feature", strlen("feature"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_FEATURE);
217 assert_int_equal(yin_match_keyword(YCTX, "fraction-digits", strlen("fraction-digits"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_FRACTION_DIGITS);
218 assert_int_equal(yin_match_keyword(YCTX, "grouping", strlen("grouping"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_GROUPING);
219 assert_int_equal(yin_match_keyword(YCTX, "identity", strlen("identity"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_IDENTITY);
220 assert_int_equal(yin_match_keyword(YCTX, "if-feature", strlen("if-feature"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_IF_FEATURE);
221 assert_int_equal(yin_match_keyword(YCTX, "import", strlen("import"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_IMPORT);
222 assert_int_equal(yin_match_keyword(YCTX, "include", strlen("include"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_INCLUDE);
223 assert_int_equal(yin_match_keyword(YCTX, "input", strlen("input"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_INPUT);
224 assert_int_equal(yin_match_keyword(YCTX, "key", strlen("key"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_KEY);
225 assert_int_equal(yin_match_keyword(YCTX, "leaf", strlen("leaf"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_LEAF);
226 assert_int_equal(yin_match_keyword(YCTX, "leaf-list", strlen("leaf-list"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_LEAF_LIST);
227 assert_int_equal(yin_match_keyword(YCTX, "length", strlen("length"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_LENGTH);
228 assert_int_equal(yin_match_keyword(YCTX, "list", strlen("list"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_LIST);
229 assert_int_equal(yin_match_keyword(YCTX, "mandatory", strlen("mandatory"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MANDATORY);
230 assert_int_equal(yin_match_keyword(YCTX, "max-elements", strlen("max-elements"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MAX_ELEMENTS);
231 assert_int_equal(yin_match_keyword(YCTX, "min-elements", strlen("min-elements"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MIN_ELEMENTS);
232 assert_int_equal(yin_match_keyword(YCTX, "modifier", strlen("modifier"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MODIFIER);
233 assert_int_equal(yin_match_keyword(YCTX, "module", strlen("module"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MODULE);
234 assert_int_equal(yin_match_keyword(YCTX, "must", strlen("must"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_MUST);
235 assert_int_equal(yin_match_keyword(YCTX, "namespace", strlen("namespace"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_NAMESPACE);
236 assert_int_equal(yin_match_keyword(YCTX, "notification", strlen("notification"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_NOTIFICATION);
237 assert_int_equal(yin_match_keyword(YCTX, "ordered-by", strlen("ordered-by"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ORDERED_BY);
238 assert_int_equal(yin_match_keyword(YCTX, "organization", strlen("organization"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_ORGANIZATION);
239 assert_int_equal(yin_match_keyword(YCTX, "output", strlen("output"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_OUTPUT);
240 assert_int_equal(yin_match_keyword(YCTX, "path", strlen("path"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_PATH);
241 assert_int_equal(yin_match_keyword(YCTX, "pattern", strlen("pattern"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_PATTERN);
242 assert_int_equal(yin_match_keyword(YCTX, "position", strlen("position"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_POSITION);
243 assert_int_equal(yin_match_keyword(YCTX, "prefix", strlen("prefix"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_PREFIX);
244 assert_int_equal(yin_match_keyword(YCTX, "presence", strlen("presence"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_PRESENCE);
245 assert_int_equal(yin_match_keyword(YCTX, "range", strlen("range"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_RANGE);
246 assert_int_equal(yin_match_keyword(YCTX, "reference", strlen("reference"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_REFERENCE);
247 assert_int_equal(yin_match_keyword(YCTX, "refine", strlen("refine"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_REFINE);
248 assert_int_equal(yin_match_keyword(YCTX, "require-instance", strlen("require-instance"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_REQUIRE_INSTANCE);
249 assert_int_equal(yin_match_keyword(YCTX, "revision", strlen("revision"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_REVISION);
250 assert_int_equal(yin_match_keyword(YCTX, "revision-date", strlen("revision-date"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_REVISION_DATE);
251 assert_int_equal(yin_match_keyword(YCTX, "rpc", strlen("rpc"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_RPC);
252 assert_int_equal(yin_match_keyword(YCTX, "status", strlen("status"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_STATUS);
253 assert_int_equal(yin_match_keyword(YCTX, "submodule", strlen("submodule"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_SUBMODULE);
254 assert_int_equal(yin_match_keyword(YCTX, "type", strlen("type"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_TYPE);
255 assert_int_equal(yin_match_keyword(YCTX, "typedef", strlen("typedef"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_TYPEDEF);
256 assert_int_equal(yin_match_keyword(YCTX, "unique", strlen("unique"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_UNIQUE);
257 assert_int_equal(yin_match_keyword(YCTX, "units", strlen("units"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_UNITS);
258 assert_int_equal(yin_match_keyword(YCTX, "uses", strlen("uses"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_USES);
259 assert_int_equal(yin_match_keyword(YCTX, "value", strlen("value"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_VALUE);
260 assert_int_equal(yin_match_keyword(YCTX, "when", strlen("when"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_WHEN);
261 assert_int_equal(yin_match_keyword(YCTX, "yang-version", strlen("yang-version"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_YANG_VERSION);
262 assert_int_equal(yin_match_keyword(YCTX, "yin-element", strlen("yin-element"), prefix, prefix_len, LY_STMT_NONE), LY_STMT_YIN_ELEMENT);
David Sedlák872c7b42018-10-26 13:15:20 +0200263}
David Sedlák3b4db242018-10-19 16:11:01 +0200264
David Sedlák872c7b42018-10-26 13:15:20 +0200265static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200266test_yin_match_argument_name(void **UNUSED(state))
David Sedlák872c7b42018-10-26 13:15:20 +0200267{
David Sedlák060b00e2019-06-19 11:12:06 +0200268 assert_int_equal(yin_match_argument_name("", 5), YIN_ARG_UNKNOWN);
269 assert_int_equal(yin_match_argument_name("qwertyasd", 5), YIN_ARG_UNKNOWN);
270 assert_int_equal(yin_match_argument_name("conditionasd", 8), YIN_ARG_UNKNOWN);
271 assert_int_equal(yin_match_argument_name("condition", 9), YIN_ARG_CONDITION);
272 assert_int_equal(yin_match_argument_name("date", 4), YIN_ARG_DATE);
273 assert_int_equal(yin_match_argument_name("module", 6), YIN_ARG_MODULE);
274 assert_int_equal(yin_match_argument_name("name", 4), YIN_ARG_NAME);
275 assert_int_equal(yin_match_argument_name("tag", 3), YIN_ARG_TAG);
276 assert_int_equal(yin_match_argument_name("target-node", 11), YIN_ARG_TARGET_NODE);
277 assert_int_equal(yin_match_argument_name("text", 4), YIN_ARG_TEXT);
278 assert_int_equal(yin_match_argument_name("uri", 3), YIN_ARG_URI);
279 assert_int_equal(yin_match_argument_name("value", 5), YIN_ARG_VALUE);
David Sedlák3b4db242018-10-19 16:11:01 +0200280}
281
David Sedlák68a1af12019-03-08 13:46:54 +0100282static void
David Sedlák555c7202019-07-04 12:14:12 +0200283test_yin_parse_content(void **state)
284{
David Sedlák555c7202019-07-04 12:14:12 +0200285 LY_ERR ret = LY_SUCCESS;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100286 const char *data =
287 "<prefix value=\"a_mod\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
288 " <myext:custom xmlns:myext=\"urn:example:extensions\">totally amazing extension</myext:custom>\n"
289 " <extension name=\"ext\">\n"
290 " <argument name=\"argname\"></argument>\n"
291 " <description><text>desc</text></description>\n"
292 " <reference><text>ref</text></reference>\n"
293 " <status value=\"deprecated\"></status>\n"
294 " </extension>\n"
295 " <text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>\n"
296 " <if-feature name=\"foo\"></if-feature>\n"
297 " <when condition=\"condition...\">\n"
298 " <reference><text>when_ref</text></reference>\n"
299 " <description><text>when_desc</text></description>\n"
300 " </when>\n"
301 " <config value=\"true\"/>\n"
302 " <error-message>\n"
303 " <value>error-msg</value>\n"
304 " </error-message>\n"
305 " <error-app-tag value=\"err-app-tag\"/>\n"
306 " <units name=\"radians\"></units>\n"
307 " <default value=\"default-value\"/>\n"
308 " <position value=\"25\"></position>\n"
309 " <value value=\"-5\"/>\n"
310 " <require-instance value=\"true\"></require-instance>\n"
311 " <range value=\"5..10\" />\n"
312 " <length value=\"baf\"/>\n"
313 " <pattern value='pattern'>\n"
314 " <modifier value='invert-match'/>\n"
315 " </pattern>\n"
316 " <enum name=\"yay\">\n"
317 " </enum>\n"
318 "</prefix>";
David Sedlák555c7202019-07-04 12:14:12 +0200319 struct lysp_ext_instance *exts = NULL;
Michal Vasko12ef5362022-09-16 15:13:58 +0200320 const char *value;
David Sedlák555c7202019-07-04 12:14:12 +0200321
322 /* test unique subelem */
323 const char *prefix_value;
Radek Krejcid6b76452019-09-03 17:03:03 +0200324 struct yin_subelement subelems2[2] = {{LY_STMT_PREFIX, &prefix_value, YIN_SUBELEM_UNIQUE},
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100325 {LY_STMT_ARG_TEXT, &value, YIN_SUBELEM_UNIQUE}};
326
David Sedláke6cd89e2019-08-07 12:46:02 +0200327 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100328 "<prefix value=\"inv_mod\" />"
329 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
330 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
331 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +0200332 ly_in_new_memory(data, &UTEST_IN);
333 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
334 lyxml_ctx_next(YCTX->xmlctx);
Michal Vaskob36053d2020-03-26 15:49:30 +0100335
Michal Vasko193dacd2022-10-13 08:43:05 +0200336 ret = yin_parse_content(YCTX, subelems2, 2, NULL, LY_STMT_STATUS, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200337 assert_int_equal(ret, LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100338 CHECK_LOG_CTX("Redefinition of \"text\" sub-element in \"status\" element.", NULL, 1);
Radek Iša56ca9e42020-09-08 18:42:00 +0200339 lydict_remove(UTEST_LYCTX, prefix_value);
340 lydict_remove(UTEST_LYCTX, value);
341 RESET_STATE;
David Sedlák555c7202019-07-04 12:14:12 +0200342
343 /* test first subelem */
David Sedláke6cd89e2019-08-07 12:46:02 +0200344 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100345 "<prefix value=\"inv_mod\" />"
346 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
347 "<text xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">wsefsdf</text>"
348 ELEMENT_WRAPPER_END;
Radek Krejcid6b76452019-09-03 17:03:03 +0200349 struct yin_subelement subelems3[2] = {{LY_STMT_PREFIX, &prefix_value, YIN_SUBELEM_UNIQUE},
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100350 {LY_STMT_ARG_TEXT, &value, YIN_SUBELEM_FIRST}};
351
Radek Iša56ca9e42020-09-08 18:42:00 +0200352 ly_in_new_memory(data, &UTEST_IN);
353 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
354 lyxml_ctx_next(YCTX->xmlctx);
Michal Vaskob36053d2020-03-26 15:49:30 +0100355
Michal Vasko193dacd2022-10-13 08:43:05 +0200356 ret = yin_parse_content(YCTX, subelems3, 2, NULL, LY_STMT_STATUS, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200357 assert_int_equal(ret, LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100358 CHECK_LOG_CTX("Sub-element \"text\" of \"status\" element must be defined as it's first sub-element.", NULL, 1);
Radek Iša56ca9e42020-09-08 18:42:00 +0200359 lydict_remove(UTEST_LYCTX, prefix_value);
360 RESET_STATE;
David Sedlák555c7202019-07-04 12:14:12 +0200361
362 /* test mandatory subelem */
David Sedláke6cd89e2019-08-07 12:46:02 +0200363 data = ELEMENT_WRAPPER_START ELEMENT_WRAPPER_END;
Radek Krejcid6b76452019-09-03 17:03:03 +0200364 struct yin_subelement subelems4[1] = {{LY_STMT_PREFIX, &prefix_value, YIN_SUBELEM_MANDATORY | YIN_SUBELEM_UNIQUE}};
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100365
Radek Iša56ca9e42020-09-08 18:42:00 +0200366 ly_in_new_memory(data, &UTEST_IN);
367 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
368 lyxml_ctx_next(YCTX->xmlctx);
Michal Vaskob36053d2020-03-26 15:49:30 +0100369
Michal Vasko193dacd2022-10-13 08:43:05 +0200370 ret = yin_parse_content(YCTX, subelems4, 1, NULL, LY_STMT_STATUS, NULL, &exts);
David Sedlák555c7202019-07-04 12:14:12 +0200371 assert_int_equal(ret, LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100372 CHECK_LOG_CTX("Missing mandatory sub-element \"prefix\" of \"status\" element.", NULL, 1);
David Sedlák555c7202019-07-04 12:14:12 +0200373}
374
David Sedlák92147b02019-07-09 14:01:01 +0200375static void
David Sedlák4a650532019-07-10 11:55:18 +0200376test_validate_value(void **state)
377{
Michal Vaskob36053d2020-03-26 15:49:30 +0100378 const char *data = ELEMENT_WRAPPER_START ELEMENT_WRAPPER_END;
379
380 /* create some XML context */
Radek Iša56ca9e42020-09-08 18:42:00 +0200381 ly_in_new_memory(data, &UTEST_IN);
382 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
383 YCTX->xmlctx->status = LYXML_ELEM_CONTENT;
384 YCTX->xmlctx->dynamic = 0;
Michal Vaskob36053d2020-03-26 15:49:30 +0100385
Radek Iša56ca9e42020-09-08 18:42:00 +0200386 YCTX->xmlctx->value = "#invalid";
387 YCTX->xmlctx->value_len = 8;
388 assert_int_equal(yin_validate_value(YCTX, Y_IDENTIF_ARG), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100389 CHECK_LOG_CTX("Invalid identifier first character '#' (0x0023).", NULL, 1);
Michal Vaskob36053d2020-03-26 15:49:30 +0100390
Radek Iša56ca9e42020-09-08 18:42:00 +0200391 YCTX->xmlctx->value = "";
392 YCTX->xmlctx->value_len = 0;
393 assert_int_equal(yin_validate_value(YCTX, Y_STR_ARG), LY_SUCCESS);
Michal Vaskob36053d2020-03-26 15:49:30 +0100394
Radek Iša56ca9e42020-09-08 18:42:00 +0200395 YCTX->xmlctx->value = "pre:b";
396 YCTX->xmlctx->value_len = 5;
397 assert_int_equal(yin_validate_value(YCTX, Y_IDENTIF_ARG), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100398 CHECK_LOG_CTX("Invalid identifier character ':' (0x003a).", NULL, 1);
Radek Iša56ca9e42020-09-08 18:42:00 +0200399 assert_int_equal(yin_validate_value(YCTX, Y_PREF_IDENTIF_ARG), LY_SUCCESS);
Michal Vaskob36053d2020-03-26 15:49:30 +0100400
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 YCTX->xmlctx->value = "pre:pre:b";
402 YCTX->xmlctx->value_len = 9;
403 assert_int_equal(yin_validate_value(YCTX, Y_PREF_IDENTIF_ARG), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +0100404 CHECK_LOG_CTX("Invalid identifier character ':' (0x003a).", NULL, 1);
David Sedlák4a650532019-07-10 11:55:18 +0200405}
406
Michal Vasko12ef5362022-09-16 15:13:58 +0200407static void
408test_valid_module(void **state)
409{
410 struct lys_module *mod;
411 char *printed;
412 const char *links_yin =
413 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
414 "<module name=\"links\"\n"
415 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
416 " xmlns:mod2=\"urn:module2\">\n"
417 " <yang-version value=\"1.1\"/>\n"
418 " <namespace uri=\"urn:module2\"/>\n"
419 " <prefix value=\"mod2\"/>\n"
420 " <identity name=\"just-another-identity\"/>\n"
421 " <grouping name=\"rgroup\">\n"
422 " <leaf name=\"rg1\">\n"
423 " <type name=\"string\"/>\n"
424 " </leaf>\n"
425 " <leaf name=\"rg2\">\n"
426 " <type name=\"string\"/>\n"
427 " </leaf>\n"
428 " </grouping>\n"
429 " <leaf name=\"one-leaf\">\n"
430 " <type name=\"string\"/>\n"
431 " </leaf>\n"
432 " <list name=\"list-for-augment\">\n"
433 " <key value=\"keyleaf\"/>\n"
434 " <leaf name=\"keyleaf\">\n"
435 " <type name=\"string\"/>\n"
436 " </leaf>\n"
437 " <leaf name=\"just-leaf\">\n"
438 " <type name=\"int32\"/>\n"
439 " </leaf>\n"
440 " </list>\n"
441 " <leaf name=\"rleaf\">\n"
442 " <type name=\"string\"/>\n"
443 " </leaf>\n"
444 " <leaf-list name=\"llist\">\n"
445 " <type name=\"string\"/>\n"
446 " <min-elements value=\"0\"/>\n"
447 " <max-elements value=\"100\"/>\n"
448 " <ordered-by value=\"user\"/>\n"
449 " </leaf-list>\n"
450 "</module>\n";
451 const char *statements_yin =
452 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
453 "<module name=\"statements\"\n"
454 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
455 " xmlns:mod=\"urn:module\"\n"
456 " xmlns:mod2=\"urn:module2\">\n"
457 " <yang-version value=\"1.1\"/>\n"
458 " <namespace uri=\"urn:module\"/>\n"
459 " <prefix value=\"mod\"/>\n"
460 " <import module=\"links\">\n"
461 " <prefix value=\"mod2\"/>\n"
462 " </import>\n"
463 " <extension name=\"ext\"/>\n"
464 " <identity name=\"random-identity\">\n"
465 " <base name=\"mod2:just-another-identity\"/>\n"
466 " <base name=\"another-identity\"/>\n"
467 " </identity>\n"
468 " <identity name=\"another-identity\">\n"
469 " <base name=\"mod2:just-another-identity\"/>\n"
470 " </identity>\n"
471 " <typedef name=\"percent\">\n"
472 " <type name=\"uint8\">\n"
473 " <range value=\"0 .. 100\"/>\n"
474 " </type>\n"
475 " <units name=\"percent\"/>\n"
476 " </typedef>\n"
477 " <list name=\"list1\">\n"
478 " <key value=\"a\"/>\n"
479 " <leaf name=\"a\">\n"
480 " <type name=\"string\"/>\n"
481 " </leaf>\n"
482 " <leaf name=\"x\">\n"
483 " <type name=\"string\"/>\n"
484 " </leaf>\n"
485 " <leaf name=\"y\">\n"
486 " <type name=\"string\"/>\n"
487 " </leaf>\n"
488 " </list>\n"
489 " <container name=\"ice-cream-shop\">\n"
490 " <container name=\"employees\">\n"
491 " <when condition=\"/list1/x\"/>\n"
492 " <list name=\"employee\">\n"
493 " <key value=\"id\"/>\n"
494 " <unique tag=\"name\"/>\n"
495 " <config value=\"true\"/>\n"
496 " <min-elements value=\"0\">\n"
497 " <mod:ext/>\n"
498 " </min-elements>\n"
499 " <max-elements value=\"unbounded\"/>\n"
500 " <leaf name=\"id\">\n"
501 " <type name=\"uint64\"/>\n"
502 " <mandatory value=\"true\"/>\n"
503 " </leaf>\n"
504 " <leaf name=\"name\">\n"
505 " <type name=\"string\"/>\n"
506 " </leaf>\n"
507 " <leaf name=\"age\">\n"
508 " <type name=\"uint32\"/>\n"
509 " </leaf>\n"
510 " </list>\n"
511 " </container>\n"
512 " </container>\n"
513 " <container name=\"random\">\n"
514 " <grouping name=\"group\">\n"
515 " <leaf name=\"g1\">\n"
516 " <type name=\"percent\"/>\n"
517 " <mandatory value=\"false\"/>\n"
518 " </leaf>\n"
519 " <leaf name=\"g2\">\n"
520 " <type name=\"string\"/>\n"
521 " </leaf>\n"
522 " </grouping>\n"
523 " <choice name=\"switch\">\n"
524 " <case name=\"a\">\n"
525 " <leaf name=\"aleaf\">\n"
526 " <type name=\"string\"/>\n"
527 " <default value=\"aaa\"/>\n"
528 " </leaf>\n"
529 " </case>\n"
530 " <case name=\"c\">\n"
531 " <leaf name=\"cleaf\">\n"
532 " <type name=\"string\"/>\n"
533 " </leaf>\n"
534 " </case>\n"
535 " </choice>\n"
536 " <anyxml name=\"xml-data\"/>\n"
537 " <anydata name=\"any-data\"/>\n"
538 " <leaf-list name=\"leaflist\">\n"
539 " <type name=\"string\"/>\n"
540 " <min-elements value=\"0\"/>\n"
541 " <max-elements value=\"20\"/>\n"
542 " </leaf-list>\n"
543 " <uses name=\"group\"/>\n"
544 " <uses name=\"mod2:rgroup\"/>\n"
545 " <leaf name=\"lref\">\n"
546 " <type name=\"leafref\">\n"
547 " <path value=\"/mod2:one-leaf\"/>\n"
548 " </type>\n"
549 " </leaf>\n"
550 " <leaf name=\"iref\">\n"
551 " <type name=\"identityref\">\n"
552 " <base name=\"mod2:just-another-identity\"/>\n"
553 " </type>\n"
554 " </leaf>\n"
555 " </container>\n"
556 " <augment target-node=\"/random\">\n"
557 " <leaf name=\"aug-leaf\">\n"
558 " <type name=\"string\"/>\n"
559 " </leaf>\n"
560 " </augment>\n"
561 " <notification name=\"notif\"/>\n"
562 " <deviation target-node=\"/mod:ice-cream-shop/mod:employees/mod:employee/mod:age\">\n"
563 " <deviate value=\"not-supported\">\n"
564 " <mod:ext/>\n"
565 " </deviate>\n"
566 " </deviation>\n"
567 " <deviation target-node=\"/mod:list1\">\n"
568 " <deviate value=\"add\">\n"
569 " <mod:ext/>\n"
570 " <must condition=\"1\"/>\n"
571 " <must condition=\"2\"/>\n"
572 " <unique tag=\"x\"/>\n"
573 " <unique tag=\"y\"/>\n"
574 " <config value=\"true\"/>\n"
575 " <min-elements value=\"1\"/>\n"
576 " <max-elements value=\"2\"/>\n"
577 " </deviate>\n"
578 " </deviation>\n"
579 " <deviation target-node=\"/mod:ice-cream-shop/mod:employees/mod:employee\">\n"
580 " <deviate value=\"delete\">\n"
581 " <unique tag=\"name\"/>\n"
582 " </deviate>\n"
583 " </deviation>\n"
584 " <deviation target-node=\"/mod:random/mod:leaflist\">\n"
585 " <deviate value=\"replace\">\n"
586 " <type name=\"uint32\"/>\n"
587 " <min-elements value=\"10\"/>\n"
588 " <max-elements value=\"15\"/>\n"
589 " </deviate>\n"
590 " </deviation>\n"
591 "</module>\n";
592
593 UTEST_ADD_MODULE(links_yin, LYS_IN_YIN, NULL, NULL);
594 UTEST_ADD_MODULE(statements_yin, LYS_IN_YIN, NULL, &mod);
595 lys_print_mem(&printed, mod, LYS_OUT_YIN, 0);
596 assert_string_equal(printed, statements_yin);
597 free(printed);
598}
599
600static void
601test_print_module(void **state)
602{
603 struct lys_module *mod;
604
605 char *orig = malloc(8096);
606
607 strcpy(orig,
608 "module all {\n"
609 " yang-version 1.1;\n"
610 " namespace \"urn:all\";\n"
611 " prefix all_mod;\n\n"
612 " import ietf-yang-types {\n"
613 " prefix yt;\n"
614 " revision-date 2013-07-15;\n"
615 " description\n"
616 " \"YANG types\";\n"
617 " reference\n"
618 " \"RFC reference\";\n"
619 " }\n\n"
620 " feature feat1 {\n"
621 " if-feature \"feat2\";\n"
622 " status obsolete;\n"
623 " }\n\n"
624 " feature feat2;\n"
625 " feature feat3;\n\n"
626 " identity ident2 {\n"
627 " base ident1;\n"
628 " }\n\n"
629 " identity ident1;\n\n"
630 " typedef tdef1 {\n"
631 " type tdef2 {\n"
632 " length \"3..9 | 30..40\";\n"
633 " pattern \"[ac]*\";\n"
634 " }\n"
635 " units \"none\";\n"
636 " default \"aaa\";\n"
637 " }\n\n"
638 " typedef tdef2 {\n"
639 " type string {\n"
640 " length \"2..10 | 20..50\";\n"
641 " pattern \"[ab]*\";\n"
642 " }\n"
643 " }\n\n"
644 " grouping group1 {\n"
645 " leaf leaf1 {\n"
646 " type int8;\n"
647 " }\n"
648 " }\n\n"
649 " container cont1 {\n"
650 " leaf leaf2 {\n"
651 " if-feature \"feat1\";\n"
652 " type int16;\n"
653 " status obsolete;\n"
654 " }\n\n"
655 " uses group1 {\n"
656 " if-feature \"feat2\";\n"
657 " refine \"leaf1\" {\n"
658 " if-feature \"feat3\";\n"
659 " must \"24 - 4 = number('20')\";\n"
660 " default \"25\";\n"
661 " config true;\n"
662 " mandatory false;\n"
663 " description\n"
664 " \"dsc\";\n"
665 " reference\n"
666 " \"none\";\n"
667 " }\n"
668 " }\n\n"
669 " leaf leaf3 {\n"
670 " type int32;\n"
671 " }\n\n"
672 " leaf leaf4 {\n"
673 " type int64 {\n"
674 " range \"1000 .. 50000\" {\n"
675 " error-message\n"
676 " \"Special error message.\";\n"
677 " error-app-tag \"special-tag\";\n"
678 " }\n"
679 " }\n"
680 " }\n\n"
681 " leaf leaf5 {\n"
682 " type uint8;\n"
683 " }\n\n"
684 " leaf leaf6 {\n"
685 " type uint16;\n"
686 " }\n\n"
687 " leaf leaf7 {\n"
688 " type uint32;\n"
689 " }\n\n"
690 " leaf leaf8 {\n"
691 " type uint64;\n"
692 " }\n\n"
693 " choice choic1 {\n"
694 " default \"leaf9b\";\n"
695 " leaf leaf9a {\n"
696 " type decimal64 {\n"
697 " fraction-digits 9;\n"
698 " }\n"
699 " }\n\n"
700 " leaf leaf9b {\n"
701 " type boolean;\n"
702 " default \"false\";\n"
703 " }\n"
704 " }\n\n"
705 " leaf leaf10 {\n"
706 " type boolean;\n"
707 " }\n\n");
708 strcpy(orig + strlen(orig),
709 " leaf leaf11 {\n"
710 " type enumeration {\n"
711 " enum \"one\";\n"
712 " enum \"two\";\n"
713 " enum \"five\" {\n"
714 " value 5;\n"
715 " }\n"
716 " }\n"
717 " }\n\n"
718 " leaf leaf12 {\n"
719 " type bits {\n"
720 " bit flag0 {\n"
721 " position 0;\n"
722 " }\n"
723 " bit flag1;\n"
724 " bit flag2 {\n"
725 " position 2;\n"
726 " }\n"
727 " bit flag3 {\n"
728 " position 3;\n"
729 " }\n"
730 " }\n"
731 " default \"flag0 flag3\";\n"
732 " }\n\n"
733 " leaf leaf13 {\n"
734 " type binary;\n"
735 " }\n\n"
736 " leaf leaf14 {\n"
737 " type leafref {\n"
738 " path \"/cont1/leaf17\";\n"
739 " }\n"
740 " }\n\n"
741 " leaf leaf15 {\n"
742 " type empty;\n"
743 " }\n\n"
744 " leaf leaf16 {\n"
745 " type union {\n"
746 " type instance-identifier {\n"
747 " require-instance true;\n"
748 " }\n"
749 " type int8;\n"
750 " }\n"
751 " }\n\n"
752 " list list1 {\n"
753 " key \"leaf18\";\n"
754 " unique \"leaf19\";\n"
755 " min-elements 1;\n"
756 " max-elements 20;\n"
757 " leaf leaf18 {\n"
758 " type string;\n"
759 " }\n\n"
760 " leaf leaf19 {\n"
761 " type uint32;\n"
762 " }\n\n"
763 " anyxml axml1;\n"
764 " anydata adata1;\n\n"
765 " action act1 {\n"
766 " input {\n"
767 " leaf leaf24 {\n"
768 " type string;\n"
769 " }\n"
770 " }\n\n"
771 " output {\n"
772 " leaf leaf25 {\n"
773 " type string;\n"
774 " }\n"
775 " }\n"
776 " }\n\n"
777 " notification notif1 {\n"
778 " leaf leaf26 {\n"
779 " type string;\n"
780 " }\n"
781 " }\n"
782 " }\n\n"
783 " leaf-list llist1 {\n"
784 " type tdef1;\n"
785 " ordered-by user;\n"
786 " }\n\n"
787 " list list2 {\n"
788 " key \"leaf27 leaf28\";\n"
789 " leaf leaf27 {\n"
790 " type uint8;\n"
791 " }\n\n"
792 " leaf leaf28 {\n"
793 " type uint8;\n"
794 " }\n"
795 " }\n\n"
796 " leaf leaf29 {\n"
797 " type instance-identifier;\n"
798 " }\n\n"
799 " container must-deviations-container {\n"
800 " presence \"Allows deviations on the leaf\";\n"
801 " leaf leaf30 {\n"
802 " type string;\n"
803 " }\n"
804 " }\n\n"
805 " leaf leaf23 {\n"
806 " type empty;\n"
807 " }\n"
808 " }\n\n"
809 " augment \"/cont1\" {\n"
810 " leaf leaf17 {\n"
811 " type string;\n"
812 " }\n"
813 " }\n\n"
814 " rpc rpc1 {\n"
815 " input {\n"
816 " leaf leaf20 {\n"
817 " type tdef1;\n"
818 " }\n"
819 " }\n\n"
820 " output {\n"
821 " container cont2 {\n"
822 " leaf leaf21 {\n"
823 " type empty;\n"
824 " }\n"
825 " }\n"
826 " }\n"
827 " }\n\n"
828 " container test-when {\n"
829 " leaf when-check {\n"
830 " type boolean;\n"
831 " }\n\n"
832 " leaf gated-data {\n"
833 " when \"../when-check = 'true'\";\n"
834 " type uint16;\n"
835 " }\n"
836 " }\n\n"
837 " extension c-define {\n"
838 " description\n"
839 " \"Takes as an argument a name string.\n"
840 " Makes the code generator use the given name\n"
841 " in the #define.\";\n"
842 " argument \"name\";\n"
843 " }\n"
844 "}\n");
845
846 char *ori_res = malloc(8096);
847
848 strcpy(ori_res,
849 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
850 "<module name=\"all\"\n"
851 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
852 " xmlns:all_mod=\"urn:all\"\n"
853 " xmlns:yt=\"urn:ietf:params:xml:ns:yang:ietf-yang-types\">\n"
854 " <yang-version value=\"1.1\"/>\n"
855 " <namespace uri=\"urn:all\"/>\n"
856 " <prefix value=\"all_mod\"/>\n"
857 " <import module=\"ietf-yang-types\">\n"
858 " <prefix value=\"yt\"/>\n"
859 " <revision-date date=\"2013-07-15\"/>\n"
860 " <description>\n"
861 " <text>YANG types</text>\n"
862 " </description>\n"
863 " <reference>\n"
864 " <text>RFC reference</text>\n"
865 " </reference>\n"
866 " </import>\n"
867 " <extension name=\"c-define\">\n"
868 " <argument name=\"name\"/>\n"
869 " <description>\n"
870 " <text>Takes as an argument a name string.\n"
871 "Makes the code generator use the given name\n"
872 "in the #define.</text>\n"
873 " </description>\n"
874 " </extension>\n"
875 " <feature name=\"feat1\">\n"
876 " <if-feature name=\"feat2\"/>\n"
877 " <status value=\"obsolete\"/>\n"
878 " </feature>\n"
879 " <feature name=\"feat2\"/>\n"
880 " <feature name=\"feat3\"/>\n"
881 " <identity name=\"ident2\">\n"
882 " <base name=\"ident1\"/>\n"
883 " </identity>\n"
884 " <identity name=\"ident1\"/>\n"
885 " <typedef name=\"tdef1\">\n"
886 " <type name=\"tdef2\">\n"
887 " <length value=\"3..9 | 30..40\"/>\n"
888 " <pattern value=\"[ac]*\"/>\n"
889 " </type>\n"
890 " <units name=\"none\"/>\n"
891 " <default value=\"aaa\"/>\n"
892 " </typedef>\n"
893 " <typedef name=\"tdef2\">\n"
894 " <type name=\"string\">\n"
895 " <length value=\"2..10 | 20..50\"/>\n"
896 " <pattern value=\"[ab]*\"/>\n"
897 " </type>\n"
898 " </typedef>\n"
899 " <grouping name=\"group1\">\n"
900 " <leaf name=\"leaf1\">\n"
901 " <type name=\"int8\"/>\n"
902 " </leaf>\n"
903 " </grouping>\n"
904 " <container name=\"cont1\">\n"
905 " <leaf name=\"leaf2\">\n"
906 " <if-feature name=\"feat1\"/>\n"
907 " <type name=\"int16\"/>\n"
908 " <status value=\"obsolete\"/>\n"
909 " </leaf>\n"
910 " <uses name=\"group1\">\n"
911 " <if-feature name=\"feat2\"/>\n"
912 " <refine target-node=\"leaf1\">\n"
913 " <if-feature name=\"feat3\"/>\n"
914 " <must condition=\"24 - 4 = number('20')\"/>\n"
915 " <default value=\"25\"/>\n"
916 " <config value=\"true\"/>\n"
917 " <mandatory value=\"false\"/>\n"
918 " <description>\n"
919 " <text>dsc</text>\n"
920 " </description>\n"
921 " <reference>\n"
922 " <text>none</text>\n"
923 " </reference>\n"
924 " </refine>\n"
925 " </uses>\n"
926 " <leaf name=\"leaf3\">\n"
927 " <type name=\"int32\"/>\n"
928 " </leaf>\n"
929 " <leaf name=\"leaf4\">\n"
930 " <type name=\"int64\">\n"
931 " <range value=\"1000 .. 50000\">\n"
932 " <error-message>\n"
933 " <value>Special error message.</value>\n"
934 " </error-message>\n"
935 " <error-app-tag value=\"special-tag\"/>\n"
936 " </range>\n"
937 " </type>\n"
938 " </leaf>\n"
939 " <leaf name=\"leaf5\">\n"
940 " <type name=\"uint8\"/>\n"
941 " </leaf>\n"
942 " <leaf name=\"leaf6\">\n"
943 " <type name=\"uint16\"/>\n"
944 " </leaf>\n"
945 " <leaf name=\"leaf7\">\n"
946 " <type name=\"uint32\"/>\n"
947 " </leaf>\n"
948 " <leaf name=\"leaf8\">\n"
949 " <type name=\"uint64\"/>\n"
950 " </leaf>\n"
951 " <choice name=\"choic1\">\n"
952 " <default value=\"leaf9b\"/>\n"
953 " <leaf name=\"leaf9a\">\n"
954 " <type name=\"decimal64\">\n"
955 " <fraction-digits value=\"9\"/>\n"
956 " </type>\n"
957 " </leaf>\n"
958 " <leaf name=\"leaf9b\">\n"
959 " <type name=\"boolean\"/>\n"
960 " <default value=\"false\"/>\n"
961 " </leaf>\n"
962 " </choice>\n"
963 " <leaf name=\"leaf10\">\n"
964 " <type name=\"boolean\"/>\n"
965 " </leaf>\n");
966 strcpy(ori_res + strlen(ori_res),
967 " <leaf name=\"leaf11\">\n"
968 " <type name=\"enumeration\">\n"
969 " <enum name=\"one\"/>\n"
970 " <enum name=\"two\"/>\n"
971 " <enum name=\"five\">\n"
972 " <value value=\"5\"/>\n"
973 " </enum>\n"
974 " </type>\n"
975 " </leaf>\n"
976 " <leaf name=\"leaf12\">\n"
977 " <type name=\"bits\">\n"
978 " <bit name=\"flag0\">\n"
979 " <position value=\"0\"/>\n"
980 " </bit>\n"
981 " <bit name=\"flag1\"/>\n"
982 " <bit name=\"flag2\">\n"
983 " <position value=\"2\"/>\n"
984 " </bit>\n"
985 " <bit name=\"flag3\">\n"
986 " <position value=\"3\"/>\n"
987 " </bit>\n"
988 " </type>\n"
989 " <default value=\"flag0 flag3\"/>\n"
990 " </leaf>\n"
991 " <leaf name=\"leaf13\">\n"
992 " <type name=\"binary\"/>\n"
993 " </leaf>\n"
994 " <leaf name=\"leaf14\">\n"
995 " <type name=\"leafref\">\n"
996 " <path value=\"/cont1/leaf17\"/>\n"
997 " </type>\n"
998 " </leaf>\n"
999 " <leaf name=\"leaf15\">\n"
1000 " <type name=\"empty\"/>\n"
1001 " </leaf>\n"
1002 " <leaf name=\"leaf16\">\n"
1003 " <type name=\"union\">\n"
1004 " <type name=\"instance-identifier\">\n"
1005 " <require-instance value=\"true\"/>\n"
1006 " </type>\n"
1007 " <type name=\"int8\"/>\n"
1008 " </type>\n"
1009 " </leaf>\n"
1010 " <list name=\"list1\">\n"
1011 " <key value=\"leaf18\"/>\n"
1012 " <unique tag=\"leaf19\"/>\n"
1013 " <min-elements value=\"1\"/>\n"
1014 " <max-elements value=\"20\"/>\n"
1015 " <leaf name=\"leaf18\">\n"
1016 " <type name=\"string\"/>\n"
1017 " </leaf>\n"
1018 " <leaf name=\"leaf19\">\n"
1019 " <type name=\"uint32\"/>\n"
1020 " </leaf>\n"
1021 " <anyxml name=\"axml1\"/>\n"
1022 " <anydata name=\"adata1\"/>\n"
1023 " <action name=\"act1\">\n"
1024 " <input>\n"
1025 " <leaf name=\"leaf24\">\n"
1026 " <type name=\"string\"/>\n"
1027 " </leaf>\n"
1028 " </input>\n"
1029 " <output>\n"
1030 " <leaf name=\"leaf25\">\n"
1031 " <type name=\"string\"/>\n"
1032 " </leaf>\n"
1033 " </output>\n"
1034 " </action>\n"
1035 " <notification name=\"notif1\">\n"
1036 " <leaf name=\"leaf26\">\n"
1037 " <type name=\"string\"/>\n"
1038 " </leaf>\n"
1039 " </notification>\n"
1040 " </list>\n"
1041 " <leaf-list name=\"llist1\">\n"
1042 " <type name=\"tdef1\"/>\n"
1043 " <ordered-by value=\"user\"/>\n"
1044 " </leaf-list>\n"
1045 " <list name=\"list2\">\n"
1046 " <key value=\"leaf27 leaf28\"/>\n"
1047 " <leaf name=\"leaf27\">\n"
1048 " <type name=\"uint8\"/>\n"
1049 " </leaf>\n"
1050 " <leaf name=\"leaf28\">\n"
1051 " <type name=\"uint8\"/>\n"
1052 " </leaf>\n"
1053 " </list>\n"
1054 " <leaf name=\"leaf29\">\n"
1055 " <type name=\"instance-identifier\"/>\n"
1056 " </leaf>\n"
1057 " <container name=\"must-deviations-container\">\n"
1058 " <presence value=\"Allows deviations on the leaf\"/>\n"
1059 " <leaf name=\"leaf30\">\n"
1060 " <type name=\"string\"/>\n"
1061 " </leaf>\n"
1062 " </container>\n"
1063 " <leaf name=\"leaf23\">\n"
1064 " <type name=\"empty\"/>\n"
1065 " </leaf>\n"
1066 " </container>\n"
1067 " <container name=\"test-when\">\n"
1068 " <leaf name=\"when-check\">\n"
1069 " <type name=\"boolean\"/>\n"
1070 " </leaf>\n"
1071 " <leaf name=\"gated-data\">\n"
1072 " <when condition=\"../when-check = 'true'\"/>\n"
1073 " <type name=\"uint16\"/>\n"
1074 " </leaf>\n"
1075 " </container>\n"
1076 " <augment target-node=\"/cont1\">\n"
1077 " <leaf name=\"leaf17\">\n"
1078 " <type name=\"string\"/>\n"
1079 " </leaf>\n"
1080 " </augment>\n"
1081 " <rpc name=\"rpc1\">\n"
1082 " <input>\n"
1083 " <leaf name=\"leaf20\">\n"
1084 " <type name=\"tdef1\"/>\n"
1085 " </leaf>\n"
1086 " </input>\n"
1087 " <output>\n"
1088 " <container name=\"cont2\">\n"
1089 " <leaf name=\"leaf21\">\n"
1090 " <type name=\"empty\"/>\n"
1091 " </leaf>\n"
1092 " </container>\n"
1093 " </output>\n"
1094 " </rpc>\n"
1095 "</module>\n");
1096
1097 char *printed;
1098 struct ly_out *out;
1099
1100 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
1101
1102 UTEST_ADD_MODULE(orig, LYS_IN_YANG, NULL, &mod);
1103 assert_int_equal(LY_SUCCESS, lys_print_module(out, mod, LYS_OUT_YIN, 0, 0));
1104 assert_int_equal(strlen(ori_res), ly_out_printed(out));
1105 assert_string_equal(printed, ori_res);
1106
1107 ly_out_free(out, NULL, 1);
1108 free(orig);
1109 free(ori_res);
1110}
1111
1112static LY_ERR
1113test_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const char *UNUSED(submod_name),
1114 const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format,
1115 const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
1116{
1117 *module_data = user_data;
1118 *format = LYS_IN_YIN;
1119 *free_module_data = NULL;
1120 return LY_SUCCESS;
1121}
1122
1123static void
1124test_print_submodule(void **state)
1125{
1126 struct lys_module *mod;
1127
1128 const char *mod_yin =
1129 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1130 "<module name=\"a\"\n"
1131 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
1132 " xmlns:a_mod=\"urn:a\">\n"
1133 " <yang-version value=\"1.1\"/>\n"
1134 " <namespace uri=\"urn:a\"/>\n"
1135 " <prefix value=\"a_mod\"/>\n"
1136 " <include module=\"a-sub\"/>\n"
1137 "</module>\n";
1138
1139 char *submod_yin =
1140 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1141 "<submodule name=\"a-sub\"\n"
1142 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"\n"
1143 " xmlns:a_mod=\"urn:a\"\n"
1144 " xmlns:yt=\"urn:ietf:params:xml:ns:yang:ietf-yang-types\">\n"
1145 " <yang-version value=\"1.1\"/>\n"
1146 " <belongs-to module=\"a\">\n"
1147 " <prefix value=\"a_mod\"/>\n"
1148 " </belongs-to>\n"
1149 " <import module=\"ietf-yang-types\">\n"
1150 " <prefix value=\"yt\"/>\n"
1151 " <revision-date date=\"2013-07-15\"/>\n"
1152 " </import>\n\n"
1153 " <description>\n"
1154 " <text>YANG types</text>\n"
1155 " </description>\n"
1156 " <reference>\n"
1157 " <text>RFC reference</text>\n"
1158 " </reference>\n"
1159 "</submodule>\n";
1160
1161 char *printed;
1162 struct ly_out *out;
1163
1164 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
1165
1166 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod_yin);
1167
1168 UTEST_ADD_MODULE(mod_yin, LYS_IN_YIN, NULL, &mod);
1169 assert_int_equal(LY_SUCCESS, lys_print_submodule(out, mod->parsed->includes[0].submodule, LYS_OUT_YIN, 0, 0));
1170 assert_int_equal(strlen(submod_yin), ly_out_printed(out));
1171 assert_string_equal(printed, submod_yin);
1172
1173 ly_out_free(out, NULL, 1);
1174}
1175
David Sedlák32488102019-07-15 17:44:10 +02001176/* helper function to simplify unit test of each element using parse_content function */
1177LY_ERR
Radek Iša56ca9e42020-09-08 18:42:00 +02001178test_element_helper(void **state, const char *data, void *dest, const char **text, struct lysp_ext_instance **exts)
David Sedlák32488102019-07-15 17:44:10 +02001179{
David Sedlákc5b20842019-08-13 10:18:31 +02001180 const char *name, *prefix;
1181 size_t name_len, prefix_len;
David Sedlák32488102019-07-15 17:44:10 +02001182 LY_ERR ret = LY_SUCCESS;
1183 struct yin_subelement subelems[71] = {
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001184 {LY_STMT_ACTION, dest, 0},
1185 {LY_STMT_ANYDATA, dest, 0},
1186 {LY_STMT_ANYXML, dest, 0},
1187 {LY_STMT_ARGUMENT, dest, 0},
1188 {LY_STMT_AUGMENT, dest, 0},
1189 {LY_STMT_BASE, dest, 0},
1190 {LY_STMT_BELONGS_TO, dest, 0},
1191 {LY_STMT_BIT, dest, 0},
1192 {LY_STMT_CASE, dest, 0},
1193 {LY_STMT_CHOICE, dest, 0},
1194 {LY_STMT_CONFIG, dest, 0},
1195 {LY_STMT_CONTACT, dest, 0},
1196 {LY_STMT_CONTAINER, dest, 0},
1197 {LY_STMT_DEFAULT, dest, YIN_SUBELEM_UNIQUE},
1198 {LY_STMT_DESCRIPTION, dest, 0},
1199 {LY_STMT_DEVIATE, dest, 0},
1200 {LY_STMT_DEVIATION, dest, 0},
1201 {LY_STMT_ENUM, dest, 0},
1202 {LY_STMT_ERROR_APP_TAG, dest, YIN_SUBELEM_UNIQUE},
1203 {LY_STMT_ERROR_MESSAGE, dest, 0},
1204 {LY_STMT_EXTENSION, dest, 0},
1205 {LY_STMT_FEATURE, dest, 0},
1206 {LY_STMT_FRACTION_DIGITS, dest, 0},
1207 {LY_STMT_GROUPING, dest, 0},
1208 {LY_STMT_IDENTITY, dest, 0},
1209 {LY_STMT_IF_FEATURE, dest, 0},
1210 {LY_STMT_IMPORT, dest, 0},
1211 {LY_STMT_INCLUDE, dest, 0},
1212 {LY_STMT_INPUT, dest, 0},
1213 {LY_STMT_KEY, dest, YIN_SUBELEM_UNIQUE},
1214 {LY_STMT_LEAF, dest, 0},
1215 {LY_STMT_LEAF_LIST, dest, 0},
1216 {LY_STMT_LENGTH, dest, 0},
1217 {LY_STMT_LIST, dest, 0},
1218 {LY_STMT_MANDATORY, dest, 0},
1219 {LY_STMT_MAX_ELEMENTS, dest, 0},
1220 {LY_STMT_MIN_ELEMENTS, dest, 0},
1221 {LY_STMT_MODIFIER, dest, 0},
1222 {LY_STMT_MODULE, dest, 0},
1223 {LY_STMT_MUST, dest, 0},
1224 {LY_STMT_NAMESPACE, dest, YIN_SUBELEM_UNIQUE},
1225 {LY_STMT_NOTIFICATION, dest, 0},
1226 {LY_STMT_ORDERED_BY, dest, 0},
1227 {LY_STMT_ORGANIZATION, dest, 0},
1228 {LY_STMT_OUTPUT, dest, 0},
1229 {LY_STMT_PATH, dest, 0},
1230 {LY_STMT_PATTERN, dest, 0},
1231 {LY_STMT_POSITION, dest, 0},
1232 {LY_STMT_PREFIX, dest, YIN_SUBELEM_UNIQUE},
1233 {LY_STMT_PRESENCE, dest, YIN_SUBELEM_UNIQUE},
1234 {LY_STMT_RANGE, dest, 0},
1235 {LY_STMT_REFERENCE, dest, 0},
1236 {LY_STMT_REFINE, dest, 0},
1237 {LY_STMT_REQUIRE_INSTANCE, dest, 0},
1238 {LY_STMT_REVISION, dest, 0},
1239 {LY_STMT_REVISION_DATE, dest, 0},
1240 {LY_STMT_RPC, dest, 0},
1241 {LY_STMT_STATUS, dest, 0},
1242 {LY_STMT_SUBMODULE, dest, 0},
1243 {LY_STMT_TYPE, dest, 0},
1244 {LY_STMT_TYPEDEF, dest, 0},
1245 {LY_STMT_UNIQUE, dest, 0},
1246 {LY_STMT_UNITS, dest, YIN_SUBELEM_UNIQUE},
1247 {LY_STMT_USES, dest, 0},
1248 {LY_STMT_VALUE, dest, 0},
1249 {LY_STMT_WHEN, dest, 0},
1250 {LY_STMT_YANG_VERSION, dest, 0},
1251 {LY_STMT_YIN_ELEMENT, dest, 0},
1252 {LY_STMT_EXTENSION_INSTANCE, dest, 0},
1253 {LY_STMT_ARG_TEXT, dest, 0},
1254 {LY_STMT_ARG_VALUE, dest, 0}
1255 };
1256
Michal Vaskod0625d72022-10-06 15:02:50 +02001257 YCTX->main_ctx = (struct lysp_ctx *)YCTX;
Radek Iša56ca9e42020-09-08 18:42:00 +02001258 ly_in_new_memory(data, &UTEST_IN);
1259 lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx);
1260 prefix = YCTX->xmlctx->prefix;
1261 prefix_len = YCTX->xmlctx->prefix_len;
1262 name = YCTX->xmlctx->name;
1263 name_len = YCTX->xmlctx->name_len;
1264 lyxml_ctx_next(YCTX->xmlctx);
Michal Vaskob36053d2020-03-26 15:49:30 +01001265
Michal Vasko193dacd2022-10-13 08:43:05 +02001266 ret = yin_parse_content(YCTX, subelems, 71, NULL,
1267 yin_match_keyword(YCTX, name, name_len, prefix, prefix_len, LY_STMT_NONE), text, exts);
Michal Vaskob36053d2020-03-26 15:49:30 +01001268
Michal Vasko63f3d842020-07-08 10:10:14 +02001269 /* free parser and input */
Radek Iša56ca9e42020-09-08 18:42:00 +02001270 lyxml_ctx_free(YCTX->xmlctx);
1271 YCTX->xmlctx = NULL;
1272 ly_in_free(UTEST_IN, 0);
1273 UTEST_IN = NULL;
David Sedlák32488102019-07-15 17:44:10 +02001274 return ret;
1275}
1276
David Sedlákd1144562019-08-06 12:36:14 +02001277#define EXT_SUBELEM "<myext:c-define name=\"MY_MTU\" xmlns:myext=\"urn:example:extensions\"/>"
1278
David Sedlák32488102019-07-15 17:44:10 +02001279static void
David Sedlák43801c92019-08-05 15:58:54 +02001280test_enum_elem(void **state)
David Sedlák32488102019-07-15 17:44:10 +02001281{
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001282 struct lysp_type type = {0};
David Sedlák32488102019-07-15 17:44:10 +02001283 const char *data;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001284
David Sedlák32488102019-07-15 17:44:10 +02001285 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001286 "<enum name=\"enum-name\">\n"
1287 " <if-feature name=\"feature\" />\n"
1288 " <value value=\"55\" />\n"
1289 " <status value=\"deprecated\" />\n"
1290 " <description><text>desc...</text></description>\n"
1291 " <reference><text>ref...</text></reference>\n"
1292 " " EXT_SUBELEM "\n"
1293 "</enum>"
1294 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001295 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1296 uint16_t flags = LYS_STATUS_DEPRC | LYS_SET_VALUE;
1297
1298 CHECK_LYSP_TYPE_ENUM(type.enums, "desc...", 1, flags, 1, "enum-name", "ref...", 55);
Michal Vasko7f45cf22020-10-01 12:49:44 +02001299 assert_string_equal(type.enums->iffeatures[0].str, "feature");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001300 TEST_1_CHECK_LYSP_EXT_INSTANCE(type.enums->exts, LY_STMT_ENUM);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001301 lysp_type_free(&fctx, &type);
David Sedlákd1144562019-08-06 12:36:14 +02001302 memset(&type, 0, sizeof type);
1303
1304 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001305 "<enum name=\"enum-name\"></enum>"
1306 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001307 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
David Sedlákd1144562019-08-06 12:36:14 +02001308 assert_string_equal(type.enums->name, "enum-name");
Michal Vaskoc636ea42022-09-16 10:20:31 +02001309 lysp_type_free(&fctx, &type);
David Sedlák32488102019-07-15 17:44:10 +02001310 memset(&type, 0, sizeof type);
David Sedlák43801c92019-08-05 15:58:54 +02001311}
1312
1313static void
1314test_bit_elem(void **state)
1315{
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001316 struct lysp_type type = {0};
David Sedlák43801c92019-08-05 15:58:54 +02001317 const char *data;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001318
David Sedlák43801c92019-08-05 15:58:54 +02001319 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001320 "<bit name=\"bit-name\">\n"
1321 " <if-feature name=\"feature\" />\n"
1322 " <position value=\"55\" />\n"
1323 " <status value=\"deprecated\" />\n"
1324 " <description><text>desc...</text></description>\n"
1325 " <reference><text>ref...</text></reference>\n"
1326 EXT_SUBELEM
1327 "</bit>"
1328 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001329 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1330 uint16_t flags = LYS_STATUS_DEPRC | LYS_SET_VALUE;
1331
1332 CHECK_LYSP_TYPE_ENUM(type.bits, "desc...", 1, flags, 1, "bit-name", "ref...", 55);
Michal Vasko7f45cf22020-10-01 12:49:44 +02001333 assert_string_equal(type.bits->iffeatures[0].str, "feature");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001334 TEST_1_CHECK_LYSP_EXT_INSTANCE(type.bits->exts, LY_STMT_BIT);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001335 lysp_type_free(&fctx, &type);
David Sedlákd1144562019-08-06 12:36:14 +02001336 memset(&type, 0, sizeof type);
1337
1338 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001339 "<bit name=\"bit-name\"> </bit>"
1340 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001341 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1342 CHECK_LYSP_TYPE_ENUM(type.bits, NULL, 0, 0, 0, "bit-name", NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001343 lysp_type_free(&fctx, &type);
David Sedlák43801c92019-08-05 15:58:54 +02001344 memset(&type, 0, sizeof type);
David Sedlák32488102019-07-15 17:44:10 +02001345}
1346
1347static void
David Sedlák32488102019-07-15 17:44:10 +02001348test_status_elem(void **state)
1349{
David Sedlák32488102019-07-15 17:44:10 +02001350 const char *data;
1351 uint16_t flags = 0;
David Sedlák32488102019-07-15 17:44:10 +02001352
1353 /* test invalid value */
1354 data = ELEMENT_WRAPPER_START "<status value=\"invalid\"></status>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001355 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_EVALID);
1356 CHECK_LOG_CTX("Invalid value \"invalid\" of \"value\" attribute in \"status\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001357 "Valid values are \"current\", \"deprecated\" and \"obsolete\".", NULL, 1);
David Sedlák32488102019-07-15 17:44:10 +02001358}
1359
1360static void
David Sedlák32488102019-07-15 17:44:10 +02001361test_yin_element_elem(void **state)
1362{
David Sedlák32488102019-07-15 17:44:10 +02001363 const char *data;
1364 uint16_t flags = 0;
David Sedlák32488102019-07-15 17:44:10 +02001365
1366 data = ELEMENT_WRAPPER_START "<yin-element value=\"invalid\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001367 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_EVALID);
Radek Iša56ca9e42020-09-08 18:42:00 +02001368 CHECK_LOG_CTX("Invalid value \"invalid\" of \"value\" attribute in \"yin-element\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001369 "Valid values are \"true\" and \"false\".", NULL, 1);
David Sedlák32488102019-07-15 17:44:10 +02001370}
1371
1372static void
1373test_yangversion_elem(void **state)
1374{
David Sedlák32488102019-07-15 17:44:10 +02001375 const char *data;
1376 uint8_t version = 0;
David Sedlák32488102019-07-15 17:44:10 +02001377
1378 /* invalid value */
1379 data = ELEMENT_WRAPPER_START "<yang-version value=\"version\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001380 assert_int_equal(test_element_helper(state, data, &version, NULL, NULL), LY_EVALID);
1381 CHECK_LOG_CTX("Invalid value \"version\" of \"value\" attribute in \"yang-version\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001382 "Valid values are \"1\" and \"1.1\".", NULL, 1);
David Sedlák32488102019-07-15 17:44:10 +02001383}
1384
1385static void
David Sedlák8e7bda82019-07-16 17:57:50 +02001386test_argument_elem(void **state)
1387{
David Sedlák8e7bda82019-07-16 17:57:50 +02001388 const char *data;
1389 uint16_t flags = 0;
1390 const char *arg;
1391 struct yin_argument_meta arg_meta = {&flags, &arg};
David Sedlák8e7bda82019-07-16 17:57:50 +02001392
1393 /* min subelems */
1394 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001395 "<argument name=\"arg\">"
1396 "</argument>"
1397 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001398 assert_int_equal(test_element_helper(state, data, &arg_meta, NULL, NULL), LY_SUCCESS);
David Sedlák8e7bda82019-07-16 17:57:50 +02001399 assert_string_equal(arg, "arg");
1400 assert_true(flags == 0);
Michal Vaskoe180ed02021-02-05 16:31:20 +01001401 lydict_remove(UTEST_LYCTX, arg);
David Sedlák8e7bda82019-07-16 17:57:50 +02001402}
1403
1404static void
David Sedlák8e7bda82019-07-16 17:57:50 +02001405test_belongsto_elem(void **state)
1406{
David Sedlák8e7bda82019-07-16 17:57:50 +02001407 const char *data;
1408 struct lysp_submodule submod;
1409
Michal Vasko8a67eff2021-12-07 14:04:47 +01001410 lydict_insert(UTEST_LYCTX, "module-name", 0, &PARSER_CUR_PMOD(YCTX)->mod->name);
Radek Iša56ca9e42020-09-08 18:42:00 +02001411
David Sedlák8e7bda82019-07-16 17:57:50 +02001412 data = ELEMENT_WRAPPER_START "<belongs-to module=\"module-name\"></belongs-to>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001413 assert_int_equal(test_element_helper(state, data, &submod, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001414 CHECK_LOG_CTX("Missing mandatory sub-element \"prefix\" of \"belongs-to\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001415}
1416
1417static void
1418test_config_elem(void **state)
1419{
David Sedlák8e7bda82019-07-16 17:57:50 +02001420 const char *data;
1421 uint16_t flags = 0;
David Sedlák8e7bda82019-07-16 17:57:50 +02001422
1423 data = ELEMENT_WRAPPER_START "<config value=\"false\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001424 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001425 assert_true(flags & LYS_CONFIG_R);
David Sedlák8e7bda82019-07-16 17:57:50 +02001426 flags = 0;
1427
1428 data = ELEMENT_WRAPPER_START "<config value=\"invalid\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001429 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_EVALID);
1430 CHECK_LOG_CTX("Invalid value \"invalid\" of \"value\" attribute in \"config\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001431 "Valid values are \"true\" and \"false\".", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001432}
1433
1434static void
1435test_default_elem(void **state)
1436{
David Sedlák8e7bda82019-07-16 17:57:50 +02001437 const char *data;
Michal Vasko7f45cf22020-10-01 12:49:44 +02001438 struct lysp_qname val = {0};
David Sedlák8e7bda82019-07-16 17:57:50 +02001439
1440 data = ELEMENT_WRAPPER_START "<default/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001441 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001442 CHECK_LOG_CTX("Missing mandatory attribute value of default element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001443}
1444
1445static void
1446test_err_app_tag_elem(void **state)
1447{
David Sedlák8e7bda82019-07-16 17:57:50 +02001448 const char *data;
1449 const char *val = NULL;
David Sedlák8e7bda82019-07-16 17:57:50 +02001450
1451 data = ELEMENT_WRAPPER_START "<error-app-tag/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001452 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001453 CHECK_LOG_CTX("Missing mandatory attribute value of error-app-tag element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001454}
1455
1456static void
1457test_err_msg_elem(void **state)
1458{
David Sedlák8e7bda82019-07-16 17:57:50 +02001459 const char *data;
1460 const char *val = NULL;
David Sedlák8e7bda82019-07-16 17:57:50 +02001461
1462 data = ELEMENT_WRAPPER_START "<error-message></error-message>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001463 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001464 CHECK_LOG_CTX("Missing mandatory sub-element \"value\" of \"error-message\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001465
David Sedlákdf2a9732019-08-07 13:23:16 +02001466 data = ELEMENT_WRAPPER_START "<error-message invalid=\"text\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001467 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001468 CHECK_LOG_CTX("Unexpected attribute \"invalid\" of \"error-message\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001469}
1470
1471static void
1472test_fracdigits_elem(void **state)
1473{
David Sedlák8e7bda82019-07-16 17:57:50 +02001474 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001475 struct lysp_type type = {0};
David Sedlák8e7bda82019-07-16 17:57:50 +02001476
David Sedlák8e7bda82019-07-16 17:57:50 +02001477 /* invalid values */
1478 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"-1\"></fraction-digits>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001479 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001480 CHECK_LOG_CTX("Invalid value \"-1\" of \"value\" attribute in \"fraction-digits\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001481
1482 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"02\"></fraction-digits>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001483 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001484 CHECK_LOG_CTX("Invalid value \"02\" of \"value\" attribute in \"fraction-digits\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001485
1486 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"1p\"></fraction-digits>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001487 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001488 CHECK_LOG_CTX("Invalid value \"1p\" of \"value\" attribute in \"fraction-digits\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001489
1490 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"19\"></fraction-digits>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001491 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001492 CHECK_LOG_CTX("Invalid value \"19\" of \"value\" attribute in \"fraction-digits\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001493
1494 data = ELEMENT_WRAPPER_START "<fraction-digits value=\"999999999999999999\"></fraction-digits>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001495 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001496 CHECK_LOG_CTX("Invalid value \"999999999999999999\" of \"value\" attribute in \"fraction-digits\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001497}
1498
1499static void
1500test_iffeature_elem(void **state)
1501{
David Sedlák8e7bda82019-07-16 17:57:50 +02001502 const char *data;
1503 const char **iffeatures = NULL;
David Sedlák8e7bda82019-07-16 17:57:50 +02001504
1505 data = ELEMENT_WRAPPER_START "<if-feature/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001506 assert_int_equal(test_element_helper(state, data, &iffeatures, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001507 CHECK_LOG_CTX("Missing mandatory attribute name of if-feature element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001508 LY_ARRAY_FREE(iffeatures);
1509 iffeatures = NULL;
David Sedlák8e7bda82019-07-16 17:57:50 +02001510}
1511
1512static void
1513test_length_elem(void **state)
1514{
David Sedlák8e7bda82019-07-16 17:57:50 +02001515 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001516 struct lysp_type type = {0};
David Sedlák8e7bda82019-07-16 17:57:50 +02001517
1518 /* max subelems */
1519 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001520 "<length value=\"length-str\">\n"
1521 " <error-message><value>err-msg</value></error-message>\n"
1522 " <error-app-tag value=\"err-app-tag\"/>\n"
1523 " <description><text>desc</text></description>\n"
1524 " <reference><text>ref</text></reference>\n"
1525 EXT_SUBELEM
1526 "</length>"
David Sedlák8e7bda82019-07-16 17:57:50 +02001527 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001528 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1529 CHECK_LYSP_RESTR(type.length, "length-str", "desc",
1530 "err-app-tag", "err-msg", 1, "ref");
David Sedlákc3da3ef2019-07-19 12:56:08 +02001531 assert_true(type.flags & LYS_SET_LENGTH);
Radek Krejci39b7fc22021-02-26 23:29:18 +01001532 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(type.length->exts[0]), LY_STMT_LENGTH);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001533 lysp_type_free(&fctx, &type);
David Sedlák8e7bda82019-07-16 17:57:50 +02001534 memset(&type, 0, sizeof(type));
1535
1536 /* min subelems */
1537 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001538 "<length value=\"length-str\">"
1539 "</length>"
David Sedlák8e7bda82019-07-16 17:57:50 +02001540 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001541 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1542 CHECK_LYSP_RESTR(type.length, "length-str", NULL,
1543 NULL, NULL, 0, NULL);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001544 lysp_type_free(&fctx, &type);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001545 assert_true(type.flags & LYS_SET_LENGTH);
David Sedlák8e7bda82019-07-16 17:57:50 +02001546 memset(&type, 0, sizeof(type));
1547
1548 data = ELEMENT_WRAPPER_START "<length></length>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001549 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001550 CHECK_LOG_CTX("Missing mandatory attribute value of length element.", NULL, 1);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001551 lysp_type_free(&fctx, &type);
David Sedlák8e7bda82019-07-16 17:57:50 +02001552 memset(&type, 0, sizeof(type));
David Sedlák8e7bda82019-07-16 17:57:50 +02001553}
1554
1555static void
1556test_modifier_elem(void **state)
1557{
David Sedlák8e7bda82019-07-16 17:57:50 +02001558 const char *data;
Radek Krejci011e4aa2020-09-04 15:22:31 +02001559 const char *pat;
David Sedlák8e7bda82019-07-16 17:57:50 +02001560
Radek Iša56ca9e42020-09-08 18:42:00 +02001561 assert_int_equal(LY_SUCCESS, lydict_insert(UTEST_LYCTX, "\006pattern", 8, &pat));
David Sedlák8e7bda82019-07-16 17:57:50 +02001562 data = ELEMENT_WRAPPER_START "<modifier value=\"invert\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001563 assert_int_equal(test_element_helper(state, data, &pat, NULL, NULL), LY_EVALID);
1564 CHECK_LOG_CTX("Invalid value \"invert\" of \"value\" attribute in \"modifier\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001565 "Only valid value is \"invert-match\".", NULL, 1);
Michal Vaskoe180ed02021-02-05 16:31:20 +01001566 lydict_remove(UTEST_LYCTX, pat);
David Sedlák8e7bda82019-07-16 17:57:50 +02001567}
1568
1569static void
1570test_namespace_elem(void **state)
1571{
David Sedlák8e7bda82019-07-16 17:57:50 +02001572 const char *data;
1573 const char *ns;
David Sedlák8e7bda82019-07-16 17:57:50 +02001574
1575 data = ELEMENT_WRAPPER_START "<namespace/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001576 assert_int_equal(test_element_helper(state, data, &ns, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001577 CHECK_LOG_CTX("Missing mandatory attribute uri of namespace element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001578}
1579
1580static void
David Sedlák8e7bda82019-07-16 17:57:50 +02001581test_pattern_elem(void **state)
1582{
David Sedlák8e7bda82019-07-16 17:57:50 +02001583 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001584 struct lysp_type type = {0};
David Sedlák8e7bda82019-07-16 17:57:50 +02001585
1586 /* max subelems */
1587 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001588 "<pattern value=\"super_pattern\">\n"
1589 " <modifier value=\"invert-match\"/>\n"
1590 " <error-message><value>err-msg-value</value></error-message>\n"
1591 " <error-app-tag value=\"err-app-tag-value\"/>\n"
1592 " <description><text>&quot;pattern-desc&quot;</text></description>\n"
1593 " <reference><text>pattern-ref</text></reference>\n"
1594 EXT_SUBELEM
1595 "</pattern>"
1596 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001597 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001598 assert_true(type.flags & LYS_SET_PATTERN);
Radek Iša56ca9e42020-09-08 18:42:00 +02001599 CHECK_LYSP_RESTR(type.patterns, "\x015super_pattern", "\"pattern-desc\"",
1600 "err-app-tag-value", "err-msg-value", 1, "pattern-ref");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001601 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(type.patterns->exts[0]), LY_STMT_PATTERN);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001602 lysp_type_free(&fctx, &type);
David Sedlák8e7bda82019-07-16 17:57:50 +02001603 memset(&type, 0, sizeof(type));
1604
1605 /* min subelems */
1606 data = ELEMENT_WRAPPER_START "<pattern value=\"pattern\"> </pattern>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001607 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1608 CHECK_LYSP_RESTR(type.patterns, "\x006pattern", NULL, NULL, NULL, 0, NULL);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001609 lysp_type_free(&fctx, &type);
David Sedlák8e7bda82019-07-16 17:57:50 +02001610 memset(&type, 0, sizeof(type));
David Sedlák8e7bda82019-07-16 17:57:50 +02001611}
1612
1613static void
1614test_value_position_elem(void **state)
1615{
David Sedlák8e7bda82019-07-16 17:57:50 +02001616 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001617 struct lysp_type_enum en = {0};
David Sedlák8e7bda82019-07-16 17:57:50 +02001618
1619 /* valid values */
David Sedlák8e7bda82019-07-16 17:57:50 +02001620 data = ELEMENT_WRAPPER_START "<value value=\"-55\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001621 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_SUCCESS);
1622 CHECK_LYSP_TYPE_ENUM(&(en), NULL, 0, LYS_SET_VALUE, 0, NULL, NULL, -55);
David Sedlák8e7bda82019-07-16 17:57:50 +02001623 memset(&en, 0, sizeof(en));
1624
1625 data = ELEMENT_WRAPPER_START "<value value=\"0\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001626 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_SUCCESS);
1627 CHECK_LYSP_TYPE_ENUM(&(en), NULL, 0, LYS_SET_VALUE, 0, NULL, NULL, 0);
David Sedlák8e7bda82019-07-16 17:57:50 +02001628 memset(&en, 0, sizeof(en));
1629
1630 data = ELEMENT_WRAPPER_START "<value value=\"-0\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001631 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_SUCCESS);
1632 CHECK_LYSP_TYPE_ENUM(&(en), NULL, 0, LYS_SET_VALUE, 0, NULL, NULL, 0);
David Sedlák8e7bda82019-07-16 17:57:50 +02001633 memset(&en, 0, sizeof(en));
1634
1635 /* valid positions */
David Sedlák8e7bda82019-07-16 17:57:50 +02001636 data = ELEMENT_WRAPPER_START "<position value=\"0\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001637 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_SUCCESS);
1638 CHECK_LYSP_TYPE_ENUM(&(en), NULL, 0, LYS_SET_VALUE, 0, NULL, NULL, 0);
David Sedlák8e7bda82019-07-16 17:57:50 +02001639 memset(&en, 0, sizeof(en));
1640
1641 /* invalid values */
1642 data = ELEMENT_WRAPPER_START "<value value=\"99999999999999999999999\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001643 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001644 CHECK_LOG_CTX("Invalid value \"99999999999999999999999\" of \"value\" attribute in \"value\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001645
1646 data = ELEMENT_WRAPPER_START "<value value=\"1k\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001647 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001648 CHECK_LOG_CTX("Invalid value \"1k\" of \"value\" attribute in \"value\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001649
David Sedlák69f01612019-07-17 11:41:08 +02001650 data = ELEMENT_WRAPPER_START "<value value=\"\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001651 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001652 CHECK_LOG_CTX("Invalid value \"\" of \"value\" attribute in \"value\" element.", NULL, 1);
David Sedlák69f01612019-07-17 11:41:08 +02001653
David Sedlák8e7bda82019-07-16 17:57:50 +02001654 /*invalid positions */
1655 data = ELEMENT_WRAPPER_START "<position value=\"-5\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001656 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001657 CHECK_LOG_CTX("Invalid value \"-5\" of \"value\" attribute in \"position\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001658
1659 data = ELEMENT_WRAPPER_START "<position value=\"-0\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001660 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001661 CHECK_LOG_CTX("Invalid value \"-0\" of \"value\" attribute in \"position\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001662
1663 data = ELEMENT_WRAPPER_START "<position value=\"99999999999999999999\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001664 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001665 CHECK_LOG_CTX("Invalid value \"99999999999999999999\" of \"value\" attribute in \"position\" element.", NULL, 1);
David Sedlák8e7bda82019-07-16 17:57:50 +02001666
David Sedlák69f01612019-07-17 11:41:08 +02001667 data = ELEMENT_WRAPPER_START "<position value=\"\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001668 assert_int_equal(test_element_helper(state, data, &en, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001669 CHECK_LOG_CTX("Invalid value \"\" of \"value\" attribute in \"position\" element.", NULL, 1);
David Sedlák69f01612019-07-17 11:41:08 +02001670}
1671
1672static void
1673test_prefix_elem(void **state)
1674{
David Sedlák69f01612019-07-17 11:41:08 +02001675 const char *data;
1676 const char *value = NULL;
1677
1678 data = ELEMENT_WRAPPER_START "<prefix value=\"pref\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001679 assert_int_equal(test_element_helper(state, data, &value, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001680 assert_string_equal(value, "pref");
Michal Vaskoe180ed02021-02-05 16:31:20 +01001681 lydict_remove(UTEST_LYCTX, value);
David Sedlák69f01612019-07-17 11:41:08 +02001682}
1683
1684static void
1685test_range_elem(void **state)
1686{
David Sedlák69f01612019-07-17 11:41:08 +02001687 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001688 struct lysp_type type = {0};
David Sedlák69f01612019-07-17 11:41:08 +02001689
1690 /* max subelems */
1691 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001692 "<range value=\"range-str\">\n"
1693 " <error-message><value>err-msg</value></error-message>\n"
1694 " <error-app-tag value=\"err-app-tag\" />\n"
1695 " <description><text>desc</text></description>\n"
1696 " <reference><text>ref</text></reference>\n"
1697 EXT_SUBELEM
1698 "</range>"
1699 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001700 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1701 CHECK_LYSP_RESTR(type.range, "range-str", "desc",
1702 "err-app-tag", "err-msg", 1, "ref");
David Sedlákc3da3ef2019-07-19 12:56:08 +02001703 assert_true(type.flags & LYS_SET_RANGE);
Radek Krejci39b7fc22021-02-26 23:29:18 +01001704 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(type.range->exts[0]), LY_STMT_RANGE);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001705 lysp_type_free(&fctx, &type);
David Sedlák69f01612019-07-17 11:41:08 +02001706 memset(&type, 0, sizeof(type));
1707
1708 /* min subelems */
1709 data = ELEMENT_WRAPPER_START "<range value=\"range-str\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001710 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
1711 CHECK_LYSP_RESTR(type.range, "range-str", NULL,
1712 NULL, NULL, 0, NULL);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001713 lysp_type_free(&fctx, &type);
David Sedlák69f01612019-07-17 11:41:08 +02001714 memset(&type, 0, sizeof(type));
David Sedlák69f01612019-07-17 11:41:08 +02001715}
1716
1717static void
1718test_reqinstance_elem(void **state)
1719{
David Sedlák69f01612019-07-17 11:41:08 +02001720 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001721 struct lysp_type type = {0};
David Sedlák69f01612019-07-17 11:41:08 +02001722
David Sedlákd1144562019-08-06 12:36:14 +02001723 data = ELEMENT_WRAPPER_START "<require-instance value=\"true\">" EXT_SUBELEM "</require-instance>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001724 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001725 assert_int_equal(type.require_instance, 1);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001726 assert_true(type.flags & LYS_SET_REQINST);
Radek Krejci5984d222021-02-26 23:01:45 +01001727 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(type.exts[0]), LY_STMT_REQUIRE_INSTANCE);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001728 lysp_type_free(&fctx, &type);
David Sedlák69f01612019-07-17 11:41:08 +02001729 memset(&type, 0, sizeof(type));
1730
1731 data = ELEMENT_WRAPPER_START "<require-instance value=\"false\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001732 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001733 assert_int_equal(type.require_instance, 0);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001734 assert_true(type.flags & LYS_SET_REQINST);
David Sedlák69f01612019-07-17 11:41:08 +02001735 memset(&type, 0, sizeof(type));
1736
1737 data = ELEMENT_WRAPPER_START "<require-instance value=\"invalid\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001738 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_EVALID);
David Sedlák69f01612019-07-17 11:41:08 +02001739 memset(&type, 0, sizeof(type));
Radek Iša56ca9e42020-09-08 18:42:00 +02001740 CHECK_LOG_CTX("Invalid value \"invalid\" of \"value\" attribute in \"require-instance\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001741 "Valid values are \"true\" and \"false\".", NULL, 1);
David Sedlák69f01612019-07-17 11:41:08 +02001742}
1743
1744static void
1745test_revision_date_elem(void **state)
1746{
David Sedlák69f01612019-07-17 11:41:08 +02001747 const char *data;
1748 char rev[LY_REV_SIZE];
1749
1750 data = ELEMENT_WRAPPER_START "<revision-date date=\"2000-01-01\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001751 assert_int_equal(test_element_helper(state, data, rev, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001752 assert_string_equal(rev, "2000-01-01");
1753
1754 data = ELEMENT_WRAPPER_START "<revision-date date=\"2000-50-05\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001755 assert_int_equal(test_element_helper(state, data, rev, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001756 CHECK_LOG_CTX("Invalid value \"2000-50-05\" of \"revision-date\".", NULL, 1);
David Sedlák69f01612019-07-17 11:41:08 +02001757}
1758
1759static void
1760test_unique_elem(void **state)
1761{
David Sedlák69f01612019-07-17 11:41:08 +02001762 const char *data;
1763 const char **values = NULL;
1764
1765 data = ELEMENT_WRAPPER_START "<unique tag=\"tag\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001766 assert_int_equal(test_element_helper(state, data, &values, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001767 assert_string_equal(*values, "tag");
Michal Vaskoe180ed02021-02-05 16:31:20 +01001768 lydict_remove(UTEST_LYCTX, *values);
David Sedlák69f01612019-07-17 11:41:08 +02001769 LY_ARRAY_FREE(values);
David Sedlákd1144562019-08-06 12:36:14 +02001770 values = NULL;
David Sedlák69f01612019-07-17 11:41:08 +02001771}
1772
1773static void
1774test_units_elem(void **state)
1775{
David Sedlák69f01612019-07-17 11:41:08 +02001776 const char *data;
1777 const char *values = NULL;
1778
1779 data = ELEMENT_WRAPPER_START "<units name=\"name\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001780 assert_int_equal(test_element_helper(state, data, &values, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001781 assert_string_equal(values, "name");
Michal Vaskoe180ed02021-02-05 16:31:20 +01001782 lydict_remove(UTEST_LYCTX, values);
David Sedlákd1144562019-08-06 12:36:14 +02001783 values = NULL;
David Sedlák69f01612019-07-17 11:41:08 +02001784}
1785
1786static void
David Sedlák69f01612019-07-17 11:41:08 +02001787test_yin_text_value_elem(void **state)
1788{
David Sedlák69f01612019-07-17 11:41:08 +02001789 const char *data;
1790 const char *val;
1791
1792 data = ELEMENT_WRAPPER_START "<text>text</text>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001793 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001794 assert_string_equal(val, "text");
Michal Vaskoe180ed02021-02-05 16:31:20 +01001795 lydict_remove(UTEST_LYCTX, val);
David Sedlák69f01612019-07-17 11:41:08 +02001796
1797 data = "<error-message xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <value>text</value> </error-message>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001798 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001799 assert_string_equal(val, "text");
Michal Vaskoe180ed02021-02-05 16:31:20 +01001800 lydict_remove(UTEST_LYCTX, val);
David Sedlák69f01612019-07-17 11:41:08 +02001801
1802 data = ELEMENT_WRAPPER_START "<text></text>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001803 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_SUCCESS);
David Sedlák69f01612019-07-17 11:41:08 +02001804 assert_string_equal("", val);
Michal Vaskoe180ed02021-02-05 16:31:20 +01001805 lydict_remove(UTEST_LYCTX, val);
David Sedlák8e7bda82019-07-16 17:57:50 +02001806}
David Sedlák32488102019-07-15 17:44:10 +02001807
David Sedlák374d2b32019-07-17 15:06:55 +02001808static void
1809test_type_elem(void **state)
1810{
David Sedlák374d2b32019-07-17 15:06:55 +02001811 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001812 struct lysp_type type = {0};
David Sedlák374d2b32019-07-17 15:06:55 +02001813
1814 /* max subelems */
1815 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001816 "<type name=\"type-name\">\n"
1817 " <base name=\"base-name\"/>\n"
1818 " <bit name=\"bit\"/>\n"
1819 " <enum name=\"enum\"/>\n"
1820 " <fraction-digits value=\"2\"/>\n"
1821 " <length value=\"length\"/>\n"
1822 " <path value=\"/path\"/>\n"
1823 " <pattern value=\"pattern\"/>\n"
1824 " <range value=\"range\" />\n"
1825 " <require-instance value=\"true\"/>\n"
1826 " <type name=\"sub-type-name\"/>\n"
1827 EXT_SUBELEM
1828 "</type>"
1829 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001830 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
David Sedlák374d2b32019-07-17 15:06:55 +02001831 assert_string_equal(type.name, "type-name");
1832 assert_string_equal(*type.bases, "base-name");
1833 assert_string_equal(type.bits->name, "bit");
1834 assert_string_equal(type.enums->name, "enum");
1835 assert_int_equal(type.fraction_digits, 2);
Radek Iša56ca9e42020-09-08 18:42:00 +02001836 CHECK_LYSP_RESTR(type.length, "length", NULL,
1837 NULL, NULL, 0, NULL);
Michal Vaskocb8c6d42020-10-16 11:58:30 +02001838 assert_string_equal(type.path->expr, "/path");
Radek Iša56ca9e42020-09-08 18:42:00 +02001839 CHECK_LYSP_RESTR(type.patterns, "\006pattern", NULL,
1840 NULL, NULL, 0, NULL);
1841 CHECK_LYSP_RESTR(type.range, "range", NULL,
1842 NULL, NULL, 0, NULL);
David Sedlák374d2b32019-07-17 15:06:55 +02001843 assert_int_equal(type.require_instance, 1);
1844 assert_string_equal(type.types->name, "sub-type-name");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001845 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(type.exts[0]), LY_STMT_TYPE);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001846 assert_true(type.flags & LYS_SET_BASE);
1847 assert_true(type.flags & LYS_SET_BIT);
1848 assert_true(type.flags & LYS_SET_ENUM);
1849 assert_true(type.flags & LYS_SET_FRDIGITS);
1850 assert_true(type.flags & LYS_SET_LENGTH);
1851 assert_true(type.flags & LYS_SET_PATH);
1852 assert_true(type.flags & LYS_SET_PATTERN);
1853 assert_true(type.flags & LYS_SET_RANGE);
1854 assert_true(type.flags & LYS_SET_REQINST);
1855 assert_true(type.flags & LYS_SET_TYPE);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001856 lysp_type_free(&fctx, &type);
David Sedlák374d2b32019-07-17 15:06:55 +02001857 memset(&type, 0, sizeof(type));
1858
1859 /* min subelems */
1860 data = ELEMENT_WRAPPER_START "<type name=\"type-name\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001861 assert_int_equal(test_element_helper(state, data, &type, NULL, NULL), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001862 lysp_type_free(&fctx, &type);
David Sedlák374d2b32019-07-17 15:06:55 +02001863 memset(&type, 0, sizeof(type));
David Sedlák374d2b32019-07-17 15:06:55 +02001864}
1865
David Sedlák1af868e2019-07-17 17:03:14 +02001866static void
1867test_max_elems_elem(void **state)
1868{
David Sedlák1af868e2019-07-17 17:03:14 +02001869 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001870 struct lysp_node_list list = {0};
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001871 struct lysp_refine refine = {0};
David Sedlák1af868e2019-07-17 17:03:14 +02001872
David Sedlák1af868e2019-07-17 17:03:14 +02001873 data = "<refine xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"10\"/> </refine>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001874 assert_int_equal(test_element_helper(state, data, &refine, NULL, NULL), LY_SUCCESS);
David Sedlák1af868e2019-07-17 17:03:14 +02001875 assert_int_equal(refine.max, 10);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001876 assert_true(refine.flags & LYS_SET_MAX);
David Sedlák1af868e2019-07-17 17:03:14 +02001877
1878 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"0\"/> </list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001879 assert_int_equal(test_element_helper(state, data, &list, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001880 CHECK_LOG_CTX("Invalid value \"0\" of \"value\" attribute in \"max-elements\" element.", NULL, 1);
David Sedlák1af868e2019-07-17 17:03:14 +02001881
1882 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"-10\"/> </list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001883 assert_int_equal(test_element_helper(state, data, &list, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001884 CHECK_LOG_CTX("Invalid value \"-10\" of \"value\" attribute in \"max-elements\" element.", NULL, 1);
David Sedlák1af868e2019-07-17 17:03:14 +02001885
1886 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"k\"/> </list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001887 assert_int_equal(test_element_helper(state, data, &list, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001888 CHECK_LOG_CTX("Invalid value \"k\" of \"value\" attribute in \"max-elements\" element.", NULL, 1);
David Sedlák1af868e2019-07-17 17:03:14 +02001889
1890 data = "<list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <max-elements value=\"u12\"/> </list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001891 assert_int_equal(test_element_helper(state, data, &list, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001892 CHECK_LOG_CTX("Invalid value \"u12\" of \"value\" attribute in \"max-elements\" element.", NULL, 1);
David Sedlák1af868e2019-07-17 17:03:14 +02001893}
1894
David Sedlák09e18c92019-07-18 11:17:11 +02001895static void
1896test_min_elems_elem(void **state)
1897{
David Sedlák09e18c92019-07-18 11:17:11 +02001898 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02001899 struct lysp_node_leaflist llist = {0};
David Sedlák09e18c92019-07-18 11:17:11 +02001900
1901 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"-5\"/> </leaf-list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001902 assert_int_equal(test_element_helper(state, data, &llist, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001903 CHECK_LOG_CTX("Value \"-5\" of \"value\" attribute in \"min-elements\" element is out of bounds.", NULL, 1);
David Sedlák09e18c92019-07-18 11:17:11 +02001904
1905 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"99999999999999999\"/> </leaf-list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001906 assert_int_equal(test_element_helper(state, data, &llist, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001907 CHECK_LOG_CTX("Value \"99999999999999999\" of \"value\" attribute in \"min-elements\" element is out of bounds.", NULL, 1);
David Sedlák09e18c92019-07-18 11:17:11 +02001908
1909 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"5k\"/> </leaf-list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001910 assert_int_equal(test_element_helper(state, data, &llist, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001911 CHECK_LOG_CTX("Invalid value \"5k\" of \"value\" attribute in \"min-elements\" element.", NULL, 1);
David Sedlák09e18c92019-07-18 11:17:11 +02001912
1913 data = "<leaf-list xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\"> <min-elements value=\"05\"/> </leaf-list>";
Radek Iša56ca9e42020-09-08 18:42:00 +02001914 assert_int_equal(test_element_helper(state, data, &llist, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01001915 CHECK_LOG_CTX("Invalid value \"05\" of \"value\" attribute in \"min-elements\" element.", NULL, 1);
David Sedlák09e18c92019-07-18 11:17:11 +02001916}
1917
David Sedláka2dad212019-07-18 12:45:19 +02001918static void
1919test_ordby_elem(void **state)
1920{
David Sedláka2dad212019-07-18 12:45:19 +02001921 const char *data;
1922 uint16_t flags = 0;
David Sedláka2dad212019-07-18 12:45:19 +02001923
1924 data = ELEMENT_WRAPPER_START "<ordered-by value=\"user\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001925 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02001926 assert_true(flags & LYS_ORDBY_USER);
David Sedláka2dad212019-07-18 12:45:19 +02001927
1928 data = ELEMENT_WRAPPER_START "<ordered-by value=\"inv\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001929 assert_int_equal(test_element_helper(state, data, &flags, NULL, NULL), LY_EVALID);
1930 CHECK_LOG_CTX("Invalid value \"inv\" of \"value\" attribute in \"ordered-by\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01001931 "Valid values are \"system\" and \"user\".", NULL, 1);
David Sedláka2dad212019-07-18 12:45:19 +02001932}
1933
David Sedlák8a83bbb2019-07-18 14:46:00 +02001934static void
1935test_any_elem(void **state)
1936{
David Sedlák8a83bbb2019-07-18 14:46:00 +02001937 const char *data;
1938 struct lysp_node *siblings = NULL;
David Sedlákbf8a2b72019-08-14 16:48:10 +02001939 struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
David Sedlák8a83bbb2019-07-18 14:46:00 +02001940 struct lysp_node_anydata *parsed = NULL;
Radek Iša56ca9e42020-09-08 18:42:00 +02001941 uint16_t flags;
David Sedlák8a83bbb2019-07-18 14:46:00 +02001942
1943 /* anyxml max subelems */
1944 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001945 "<anyxml name=\"any-name\">\n"
1946 " <config value=\"true\" />\n"
1947 " <description><text>desc</text></description>\n"
1948 " <if-feature name=\"feature\" />\n"
1949 " <mandatory value=\"true\" />\n"
1950 " <must condition=\"must-cond\" />\n"
1951 " <reference><text>ref</text></reference>\n"
1952 " <status value=\"deprecated\"/>\n"
1953 " <when condition=\"when-cond\"/>\n"
1954 EXT_SUBELEM
1955 "</anyxml>"
1956 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001957 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák8a83bbb2019-07-18 14:46:00 +02001958 parsed = (struct lysp_node_anydata *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02001959 flags = LYS_CONFIG_W | LYS_MAND_TRUE | LYS_STATUS_DEPRC;
1960 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
1961 "any-name", 0, LYS_ANYXML, 0, "ref", 1);
1962 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02001963 assert_string_equal(parsed->iffeatures[0].str, "feature");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001964 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_ANYXML);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001965 lysp_node_free(&fctx, siblings);
David Sedlák8a83bbb2019-07-18 14:46:00 +02001966 siblings = NULL;
1967
1968 /* anydata max subelems */
1969 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001970 "<anydata name=\"any-name\">\n"
1971 " <config value=\"true\" />\n"
1972 " <description><text>desc</text></description>\n"
1973 " <if-feature name=\"feature\" />\n"
1974 " <mandatory value=\"true\" />\n"
1975 " <must condition=\"must-cond\" />\n"
1976 " <reference><text>ref</text></reference>\n"
1977 " <status value=\"deprecated\"/>\n"
1978 " <when condition=\"when-cond\"/>\n"
1979 EXT_SUBELEM
1980 "</anydata>"
1981 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001982 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák8a83bbb2019-07-18 14:46:00 +02001983 parsed = (struct lysp_node_anydata *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02001984 flags = LYS_CONFIG_W | LYS_MAND_TRUE | LYS_STATUS_DEPRC;
1985 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
1986 "any-name", 0, LYS_ANYDATA, 0, "ref", 1);
1987 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02001988 assert_string_equal(parsed->iffeatures[0].str, "feature");
Radek Krejci39b7fc22021-02-26 23:29:18 +01001989 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_ANYDATA);
Michal Vaskoc636ea42022-09-16 10:20:31 +02001990 lysp_node_free(&fctx, siblings);
David Sedlák8a83bbb2019-07-18 14:46:00 +02001991 siblings = NULL;
1992
1993 /* min subelems */
1994 node_meta.parent = (void *)0x10;
1995 data = ELEMENT_WRAPPER_START "<anydata name=\"any-name\"> </anydata>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02001996 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák8a83bbb2019-07-18 14:46:00 +02001997 parsed = (struct lysp_node_anydata *)siblings;
1998 assert_ptr_equal(parsed->parent, node_meta.parent);
Radek Iša56ca9e42020-09-08 18:42:00 +02001999 CHECK_LYSP_NODE(parsed, NULL, 0, 0, 0,
2000 "any-name", 0, LYS_ANYDATA, 1, NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002001 lysp_node_free(&fctx, siblings);
David Sedlák8a83bbb2019-07-18 14:46:00 +02002002}
2003
David Sedlák203ca3a2019-07-18 15:26:25 +02002004static void
2005test_leaf_elem(void **state)
2006{
David Sedlák203ca3a2019-07-18 15:26:25 +02002007 const char *data;
2008 struct lysp_node *siblings = NULL;
David Sedlákbf8a2b72019-08-14 16:48:10 +02002009 struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
David Sedlák203ca3a2019-07-18 15:26:25 +02002010 struct lysp_node_leaf *parsed = NULL;
Radek Iša56ca9e42020-09-08 18:42:00 +02002011 uint16_t flags;
David Sedlák203ca3a2019-07-18 15:26:25 +02002012
2013 /* max elements */
2014 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002015 "<leaf name=\"leaf\">\n"
2016 " <config value=\"true\" />\n"
2017 " <default value=\"def-val\"/>\n"
2018 " <description><text>desc</text></description>\n"
2019 " <if-feature name=\"feature\" />\n"
2020 " <mandatory value=\"true\" />\n"
2021 " <must condition=\"must-cond\" />\n"
2022 " <reference><text>ref</text></reference>\n"
2023 " <status value=\"deprecated\"/>\n"
2024 " <type name=\"type\"/>\n"
2025 " <units name=\"uni\"/>\n"
2026 " <when condition=\"when-cond\"/>\n"
2027 EXT_SUBELEM
2028 "</leaf>"
David Sedlák203ca3a2019-07-18 15:26:25 +02002029 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002030 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák203ca3a2019-07-18 15:26:25 +02002031 parsed = (struct lysp_node_leaf *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002032 flags = LYS_CONFIG_W | LYS_MAND_TRUE | LYS_STATUS_DEPRC;
2033 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2034 "leaf", 0, LYS_LEAF, 0, "ref", 1);
2035 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002036 assert_string_equal(parsed->iffeatures[0].str, "feature");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002037 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_LEAF);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002038 assert_string_equal(parsed->musts->arg.str, "must-cond");
David Sedlák203ca3a2019-07-18 15:26:25 +02002039 assert_string_equal(parsed->type.name, "type");
2040 assert_string_equal(parsed->units, "uni");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002041 assert_string_equal(parsed->dflt.str, "def-val");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002042 lysp_node_free(&fctx, siblings);
David Sedlák203ca3a2019-07-18 15:26:25 +02002043 siblings = NULL;
2044
2045 /* min elements */
2046 data = ELEMENT_WRAPPER_START "<leaf name=\"leaf\"> <type name=\"type\"/> </leaf>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002047 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák203ca3a2019-07-18 15:26:25 +02002048 parsed = (struct lysp_node_leaf *)siblings;
2049 assert_string_equal(parsed->name, "leaf");
2050 assert_string_equal(parsed->type.name, "type");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002051 lysp_node_free(&fctx, siblings);
David Sedlák203ca3a2019-07-18 15:26:25 +02002052 siblings = NULL;
David Sedlák203ca3a2019-07-18 15:26:25 +02002053}
2054
David Sedlákc3da3ef2019-07-19 12:56:08 +02002055static void
2056test_leaf_list_elem(void **state)
2057{
David Sedlákc3da3ef2019-07-19 12:56:08 +02002058 const char *data;
2059 struct lysp_node *siblings = NULL;
David Sedlákbf8a2b72019-08-14 16:48:10 +02002060 struct tree_node_meta node_meta = {.parent = NULL, .nodes = &siblings};
David Sedlákc3da3ef2019-07-19 12:56:08 +02002061 struct lysp_node_leaflist *parsed = NULL;
Radek Iša56ca9e42020-09-08 18:42:00 +02002062 uint16_t flags;
David Sedlákc3da3ef2019-07-19 12:56:08 +02002063
2064 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002065 "<leaf-list name=\"llist\">\n"
2066 " <config value=\"true\" />\n"
2067 " <default value=\"def-val0\"/>\n"
2068 " <default value=\"def-val1\"/>\n"
2069 " <description><text>desc</text></description>\n"
2070 " <if-feature name=\"feature\"/>\n"
2071 " <max-elements value=\"5\"/>\n"
2072 " <must condition=\"must-cond\"/>\n"
2073 " <ordered-by value=\"user\" />\n"
2074 " <reference><text>ref</text></reference>\n"
2075 " <status value=\"current\"/>\n"
2076 " <type name=\"type\"/>\n"
2077 " <units name=\"uni\"/>\n"
2078 " <when condition=\"when-cond\"/>\n"
2079 EXT_SUBELEM
2080 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002081 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002082 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002083 parsed = (struct lysp_node_leaflist *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002084 flags = LYS_CONFIG_W | LYS_ORDBY_USER | LYS_STATUS_CURR | LYS_SET_MAX;
2085 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2086 "llist", 0, LYS_LEAFLIST, 0, "ref", 1);
2087 CHECK_LYSP_RESTR(parsed->musts, "must-cond", NULL, NULL, NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002088 assert_string_equal(parsed->dflts[0].str, "def-val0");
2089 assert_string_equal(parsed->dflts[1].str, "def-val1");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002090 assert_string_equal(parsed->iffeatures[0].str, "feature");
David Sedlákc3da3ef2019-07-19 12:56:08 +02002091 assert_int_equal(parsed->max, 5);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002092 assert_string_equal(parsed->type.name, "type");
2093 assert_string_equal(parsed->units, "uni");
Radek Iša56ca9e42020-09-08 18:42:00 +02002094 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002095 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_LEAF_LIST);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002096 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002097 siblings = NULL;
2098
2099 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002100 "<leaf-list name=\"llist\">\n"
2101 " <config value=\"true\" />\n"
2102 " <description><text>desc</text></description>\n"
2103 " <if-feature name=\"feature\"/>\n"
2104 " <min-elements value=\"5\"/>\n"
2105 " <must condition=\"must-cond\"/>\n"
2106 " <ordered-by value=\"user\" />\n"
2107 " <reference><text>ref</text></reference>\n"
2108 " <status value=\"current\"/>\n"
2109 " <type name=\"type\"/>\n"
2110 " <units name=\"uni\"/>\n"
2111 " <when condition=\"when-cond\"/>\n"
2112 EXT_SUBELEM
2113 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002114 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002115 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002116 parsed = (struct lysp_node_leaflist *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002117 flags = LYS_CONFIG_W | LYS_ORDBY_USER | LYS_STATUS_CURR | LYS_SET_MIN;
2118 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2119 "llist", 0, LYS_LEAFLIST, 0, "ref", 1);
2120 CHECK_LYSP_RESTR(parsed->musts, "must-cond", NULL, NULL, NULL, 0, NULL);
2121 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002122 assert_string_equal(parsed->iffeatures[0].str, "feature");
David Sedlákc3da3ef2019-07-19 12:56:08 +02002123 assert_int_equal(parsed->min, 5);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002124 assert_string_equal(parsed->type.name, "type");
2125 assert_string_equal(parsed->units, "uni");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002126 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_LEAF_LIST);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002127 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002128 siblings = NULL;
2129
2130 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002131 "<leaf-list name=\"llist\">\n"
2132 " <config value=\"true\" />\n"
2133 " <description><text>desc</text></description>\n"
2134 " <if-feature name=\"feature\"/>\n"
2135 " <max-elements value=\"15\"/>\n"
2136 " <min-elements value=\"5\"/>\n"
2137 " <must condition=\"must-cond\"/>\n"
2138 " <ordered-by value=\"user\" />\n"
2139 " <reference><text>ref</text></reference>\n"
2140 " <status value=\"current\"/>\n"
2141 " <type name=\"type\"/>\n"
2142 " <units name=\"uni\"/>\n"
2143 " <when condition=\"when-cond\"/>\n"
2144 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002145 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002146 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002147 parsed = (struct lysp_node_leaflist *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002148 flags = LYS_CONFIG_W | LYS_ORDBY_USER | LYS_STATUS_CURR | LYS_SET_MIN | LYS_SET_MAX;
2149 CHECK_LYSP_NODE(parsed, "desc", 0, flags, 1,
2150 "llist", 0, LYS_LEAFLIST, 0, "ref", 1);
2151 CHECK_LYSP_RESTR(parsed->musts, "must-cond", NULL, NULL, NULL, 0, NULL);
2152 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002153 assert_string_equal(parsed->iffeatures[0].str, "feature");
David Sedlákc3da3ef2019-07-19 12:56:08 +02002154 assert_int_equal(parsed->min, 5);
2155 assert_int_equal(parsed->max, 15);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002156 assert_string_equal(parsed->type.name, "type");
2157 assert_string_equal(parsed->units, "uni");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002158 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002159 siblings = NULL;
2160
2161 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002162 "<leaf-list name=\"llist\">\n"
2163 " <type name=\"type\"/>\n"
2164 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002165 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002166 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002167 parsed = (struct lysp_node_leaflist *)siblings;
2168 assert_string_equal(parsed->name, "llist");
2169 assert_string_equal(parsed->type.name, "type");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002170 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002171 siblings = NULL;
2172
2173 /* invalid combinations */
2174 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002175 "<leaf-list name=\"llist\">\n"
2176 " <max-elements value=\"5\"/>\n"
2177 " <min-elements value=\"15\"/>\n"
2178 " <type name=\"type\"/>"
2179 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002180 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002181 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01002182 CHECK_LOG_CTX("Invalid combination of min-elements and max-elements: min value 15 is bigger than the max value 5.",
2183 NULL, 4);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002184 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002185 siblings = NULL;
2186
2187 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002188 "<leaf-list name=\"llist\">\n"
2189 " <default value=\"def-val1\"/>\n"
2190 " <min-elements value=\"15\"/>\n"
2191 " <type name=\"type\"/>\n"
2192 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002193 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002194 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01002195 CHECK_LOG_CTX("Invalid combination of sub-elemnts \"min-elements\" and \"default\" in \"leaf-list\" element.", NULL, 5);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002196 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002197 siblings = NULL;
2198
2199 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002200 "<leaf-list name=\"llist\">"
2201 "</leaf-list>"
David Sedlákc3da3ef2019-07-19 12:56:08 +02002202 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002203 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01002204 CHECK_LOG_CTX("Missing mandatory sub-element \"type\" of \"leaf-list\" element.", NULL, 1);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002205 lysp_node_free(&fctx, siblings);
David Sedlákc3da3ef2019-07-19 12:56:08 +02002206 siblings = NULL;
David Sedlákc3da3ef2019-07-19 12:56:08 +02002207}
2208
David Sedlákcb39f642019-07-19 13:19:55 +02002209static void
2210test_presence_elem(void **state)
2211{
David Sedlákcb39f642019-07-19 13:19:55 +02002212 const char *data;
2213 const char *val;
2214
2215 data = ELEMENT_WRAPPER_START "<presence value=\"presence-val\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002216 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_SUCCESS);
David Sedlákcb39f642019-07-19 13:19:55 +02002217 assert_string_equal(val, "presence-val");
Michal Vaskoe180ed02021-02-05 16:31:20 +01002218 lydict_remove(UTEST_LYCTX, val);
David Sedlákcb39f642019-07-19 13:19:55 +02002219
2220 data = ELEMENT_WRAPPER_START "<presence/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002221 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01002222 CHECK_LOG_CTX("Missing mandatory attribute value of presence element.", NULL, 1);
David Sedlákcb39f642019-07-19 13:19:55 +02002223}
2224
David Sedlák12470a82019-07-19 13:44:36 +02002225static void
2226test_key_elem(void **state)
2227{
David Sedlák12470a82019-07-19 13:44:36 +02002228 const char *data;
2229 const char *val;
2230
2231 data = ELEMENT_WRAPPER_START "<key value=\"key-value\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002232 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_SUCCESS);
David Sedlák12470a82019-07-19 13:44:36 +02002233 assert_string_equal(val, "key-value");
Michal Vaskoe180ed02021-02-05 16:31:20 +01002234 lydict_remove(UTEST_LYCTX, val);
David Sedlák12470a82019-07-19 13:44:36 +02002235
2236 data = ELEMENT_WRAPPER_START "<key/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002237 assert_int_equal(test_element_helper(state, data, &val, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01002238 CHECK_LOG_CTX("Missing mandatory attribute value of key element.", NULL, 1);
David Sedlák12470a82019-07-19 13:44:36 +02002239}
2240
David Sedlák04e17b22019-07-19 15:29:48 +02002241static void
David Sedlák0d6de5a2019-07-22 13:25:44 +02002242test_uses_elem(void **state)
2243{
David Sedlák0d6de5a2019-07-22 13:25:44 +02002244 const char *data;
2245 struct lysp_node *siblings = NULL;
2246 struct tree_node_meta node_meta = {NULL, &siblings};
2247 struct lysp_node_uses *parsed = NULL;
2248
2249 /* max subelems */
2250 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002251 "<uses name=\"uses-name\">\n"
2252 " <when condition=\"cond\" />\n"
2253 " <if-feature name=\"feature\" />\n"
2254 " <status value=\"obsolete\" />\n"
2255 " <description><text>desc</text></description>\n"
2256 " <reference><text>ref</text></reference>\n"
2257 " <refine target-node=\"target\"/>\n"
2258 " <augment target-node=\"target\" />\n"
2259 EXT_SUBELEM
2260 "</uses>"
2261 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002262 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák0d6de5a2019-07-22 13:25:44 +02002263 parsed = (struct lysp_node_uses *)&siblings[0];
Radek Iša56ca9e42020-09-08 18:42:00 +02002264 CHECK_LYSP_NODE(parsed, "desc", 1, LYS_STATUS_OBSLT, 1,
2265 "uses-name", 0, LYS_USES, 0, "ref", 1);
2266 CHECK_LYSP_WHEN(parsed->when, "cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002267 assert_string_equal(parsed->iffeatures[0].str, "feature");
David Sedlák0d6de5a2019-07-22 13:25:44 +02002268 assert_string_equal(parsed->refines->nodeid, "target");
David Sedlák992fb7c2019-07-24 16:51:01 +02002269 assert_string_equal(parsed->augments->nodeid, "target");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002270 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_USES);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002271 lysp_node_free(&fctx, siblings);
David Sedlák0d6de5a2019-07-22 13:25:44 +02002272 siblings = NULL;
2273
2274 /* min subelems */
2275 data = ELEMENT_WRAPPER_START "<uses name=\"uses-name\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002276 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák0d6de5a2019-07-22 13:25:44 +02002277 assert_string_equal(siblings[0].name, "uses-name");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002278 lysp_node_free(&fctx, siblings);
David Sedlák0d6de5a2019-07-22 13:25:44 +02002279 siblings = NULL;
David Sedlák0d6de5a2019-07-22 13:25:44 +02002280}
2281
David Sedlákaa854b02019-07-22 14:17:10 +02002282static void
David Sedlákaf536aa2019-07-23 13:42:23 +02002283test_list_elem(void **state)
2284{
David Sedlákaf536aa2019-07-23 13:42:23 +02002285 const char *data;
2286 struct lysp_node *siblings = NULL;
2287 struct tree_node_meta node_meta = {NULL, &siblings};
2288 struct lysp_node_list *parsed = NULL;
2289
2290 /* max subelems */
2291 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002292 "<list name=\"list-name\">\n"
2293 " <when condition=\"when\"/>\n"
2294 " <if-feature name=\"iff\"/>\n"
2295 " <must condition=\"must-cond\"/>\n"
2296 " <key value=\"key\"/>\n"
2297 " <unique tag=\"utag\"/>\n"
2298 " <config value=\"true\"/>\n"
2299 " <min-elements value=\"10\"/>\n"
2300 " <ordered-by value=\"user\"/>\n"
2301 " <status value=\"deprecated\"/>\n"
2302 " <description><text>desc</text></description>\n"
2303 " <reference><text>ref</text></reference>\n"
2304 " <anydata name=\"anyd\"/>\n"
2305 " <anyxml name=\"anyx\"/>\n"
2306 " <container name=\"cont\"/>\n"
2307 " <choice name=\"choice\"/>\n"
2308 " <action name=\"action\"/>\n"
2309 " <grouping name=\"grp\"/>\n"
2310 " <notification name=\"notf\"/>\n"
2311 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2312 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2313 " <list name=\"sub-list\"/>\n"
2314 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2315 " <uses name=\"uses-name\"/>\n"
2316 EXT_SUBELEM
2317 "</list>"
2318 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002319 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákaf536aa2019-07-23 13:42:23 +02002320 parsed = (struct lysp_node_list *)&siblings[0];
David Sedlákaf536aa2019-07-23 13:42:23 +02002321 assert_string_equal(parsed->child->name, "anyd");
2322 assert_int_equal(parsed->child->nodetype, LYS_ANYDATA);
2323 assert_string_equal(parsed->child->next->name, "anyx");
2324 assert_int_equal(parsed->child->next->nodetype, LYS_ANYXML);
David Sedlákf111bcb2019-07-23 17:15:51 +02002325 assert_string_equal(parsed->child->next->next->name, "cont");
2326 assert_int_equal(parsed->child->next->next->nodetype, LYS_CONTAINER);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002327 assert_string_equal(parsed->child->next->next->next->name, "choice");
2328 assert_int_equal(parsed->child->next->next->next->nodetype, LYS_CHOICE);
David Sedlák85d0eca2019-07-24 15:15:21 +02002329 assert_string_equal(parsed->child->next->next->next->next->name, "leaf");
2330 assert_int_equal(parsed->child->next->next->next->next->nodetype, LYS_LEAF);
2331 assert_string_equal(parsed->child->next->next->next->next->next->name, "llist");
2332 assert_int_equal(parsed->child->next->next->next->next->next->nodetype, LYS_LEAFLIST);
2333 assert_string_equal(parsed->child->next->next->next->next->next->next->name, "sub-list");
2334 assert_int_equal(parsed->child->next->next->next->next->next->next->nodetype, LYS_LIST);
2335 assert_string_equal(parsed->child->next->next->next->next->next->next->next->name, "uses-name");
2336 assert_int_equal(parsed->child->next->next->next->next->next->next->next->nodetype, LYS_USES);
2337 assert_null(parsed->child->next->next->next->next->next->next->next->next);
Radek Iša56ca9e42020-09-08 18:42:00 +02002338 uint16_t flags = LYS_ORDBY_USER | LYS_STATUS_DEPRC | LYS_CONFIG_W | LYS_SET_MIN;
2339
2340 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2341 "list-name", 0, LYS_LIST, 0, "ref", 1);
2342 CHECK_LYSP_RESTR(parsed->musts, "must-cond", NULL, NULL, NULL, 0, NULL);
2343 CHECK_LYSP_WHEN(parsed->when, "when", NULL, 0, NULL);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002344 assert_string_equal(parsed->groupings->name, "grp");
David Sedlák85d0eca2019-07-24 15:15:21 +02002345 assert_string_equal(parsed->actions->name, "action");
David Sedláke3ce9ef2019-07-23 16:34:30 +02002346 assert_int_equal(parsed->groupings->nodetype, LYS_GROUPING);
David Sedlák031b9e72019-07-23 15:19:37 +02002347 assert_string_equal(parsed->notifs->name, "notf");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002348 assert_string_equal(parsed->iffeatures[0].str, "iff");
David Sedlákaf536aa2019-07-23 13:42:23 +02002349 assert_string_equal(parsed->key, "key");
2350 assert_int_equal(parsed->min, 10);
David Sedlákaf536aa2019-07-23 13:42:23 +02002351 assert_string_equal(parsed->typedefs->name, "tpdf");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002352 assert_string_equal(parsed->uniques->str, "utag");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002353 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_LIST);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002354 lysp_node_free(&fctx, siblings);
Radek Iša56ca9e42020-09-08 18:42:00 +02002355 ly_set_erase(&YCTX->tpdfs_nodes, NULL);
David Sedlákaf536aa2019-07-23 13:42:23 +02002356 siblings = NULL;
2357
2358 /* min subelems */
2359 data = ELEMENT_WRAPPER_START "<list name=\"list-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002360 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákaf536aa2019-07-23 13:42:23 +02002361 parsed = (struct lysp_node_list *)&siblings[0];
Radek Iša56ca9e42020-09-08 18:42:00 +02002362 CHECK_LYSP_NODE(parsed, NULL, 0, 0, 0,
2363 "list-name", 0, LYS_LIST, 0, NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002364 lysp_node_free(&fctx, siblings);
David Sedlákaf536aa2019-07-23 13:42:23 +02002365 siblings = NULL;
David Sedlákaf536aa2019-07-23 13:42:23 +02002366}
2367
David Sedlák031b9e72019-07-23 15:19:37 +02002368static void
2369test_notification_elem(void **state)
2370{
David Sedlák031b9e72019-07-23 15:19:37 +02002371 const char *data;
Radek Krejci2a9fc652021-01-22 17:44:34 +01002372 struct lysp_node_notif *notifs = NULL;
David Sedlák6881b512019-08-13 12:52:00 +02002373 struct tree_node_meta notif_meta = {NULL, (struct lysp_node **)&notifs};
David Sedlák031b9e72019-07-23 15:19:37 +02002374
2375 /* max subelems */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002376 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák031b9e72019-07-23 15:19:37 +02002377 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002378 "<notification name=\"notif-name\">\n"
2379 " <anydata name=\"anyd\"/>\n"
2380 " <anyxml name=\"anyx\"/>\n"
2381 " <description><text>desc</text></description>\n"
2382 " <if-feature name=\"iff\"/>\n"
2383 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2384 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2385 " <list name=\"sub-list\"/>\n"
2386 " <must condition=\"cond\"/>\n"
2387 " <reference><text>ref</text></reference>\n"
2388 " <status value=\"deprecated\"/>\n"
2389 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2390 " <uses name=\"uses-name\"/>\n"
2391 " <container name=\"cont\"/>\n"
2392 " <choice name=\"choice\"/>\n"
2393 " <grouping name=\"grp\"/>\n"
2394 EXT_SUBELEM
2395 "</notification>"
2396 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002397 assert_int_equal(test_element_helper(state, data, &notif_meta, NULL, NULL), LY_SUCCESS);
David Sedlák031b9e72019-07-23 15:19:37 +02002398 assert_string_equal(notifs->name, "notif-name");
Radek Krejci01180ac2021-01-27 08:48:22 +01002399 assert_string_equal(notifs->child->name, "anyd");
2400 assert_int_equal(notifs->child->nodetype, LYS_ANYDATA);
2401 assert_string_equal(notifs->child->next->name, "anyx");
2402 assert_int_equal(notifs->child->next->nodetype, LYS_ANYXML);
2403 assert_string_equal(notifs->child->next->next->name, "leaf");
2404 assert_int_equal(notifs->child->next->next->nodetype, LYS_LEAF);
2405 assert_string_equal(notifs->child->next->next->next->name, "llist");
2406 assert_int_equal(notifs->child->next->next->next->nodetype, LYS_LEAFLIST);
2407 assert_string_equal(notifs->child->next->next->next->next->name, "sub-list");
2408 assert_int_equal(notifs->child->next->next->next->next->nodetype, LYS_LIST);
David Sedlák031b9e72019-07-23 15:19:37 +02002409 assert_true(notifs->flags & LYS_STATUS_DEPRC);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002410 assert_string_equal(notifs->groupings->name, "grp");
2411 assert_int_equal(notifs->groupings->nodetype, LYS_GROUPING);
Radek Krejci01180ac2021-01-27 08:48:22 +01002412 assert_string_equal(notifs->child->next->next->next->next->next->name, "uses-name");
2413 assert_int_equal(notifs->child->next->next->next->next->next->nodetype, LYS_USES);
2414 assert_string_equal(notifs->child->next->next->next->next->next->next->name, "cont");
2415 assert_int_equal(notifs->child->next->next->next->next->next->next->nodetype, LYS_CONTAINER);
2416 assert_int_equal(notifs->child->next->next->next->next->next->next->next->nodetype, LYS_CHOICE);
2417 assert_string_equal(notifs->child->next->next->next->next->next->next->next->name, "choice");
2418 assert_null(notifs->child->next->next->next->next->next->next->next->next);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002419 assert_string_equal(notifs->iffeatures[0].str, "iff");
2420 assert_string_equal(notifs->musts->arg.str, "cond");
David Sedlák031b9e72019-07-23 15:19:37 +02002421 assert_int_equal(notifs->nodetype, LYS_NOTIF);
2422 assert_null(notifs->parent);
2423 assert_string_equal(notifs->ref, "ref");
2424 assert_string_equal(notifs->typedefs->name, "tpdf");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002425 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(notifs->exts[0]), LY_STMT_NOTIFICATION);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002426 lysp_node_free(&fctx, (struct lysp_node *)notifs);
David Sedlák031b9e72019-07-23 15:19:37 +02002427 notifs = NULL;
2428
2429 /* min subelems */
2430 data = ELEMENT_WRAPPER_START "<notification name=\"notif-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002431 assert_int_equal(test_element_helper(state, data, &notif_meta, NULL, NULL), LY_SUCCESS);
David Sedlák031b9e72019-07-23 15:19:37 +02002432 assert_string_equal(notifs->name, "notif-name");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002433 lysp_node_free(&fctx, (struct lysp_node *)notifs);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002434 notifs = NULL;
David Sedláke3ce9ef2019-07-23 16:34:30 +02002435}
2436
2437static void
2438test_grouping_elem(void **state)
2439{
David Sedláke3ce9ef2019-07-23 16:34:30 +02002440 const char *data;
Radek Krejci2a9fc652021-01-22 17:44:34 +01002441 struct lysp_node_grp *grps = NULL;
David Sedlák6881b512019-08-13 12:52:00 +02002442 struct tree_node_meta grp_meta = {NULL, (struct lysp_node **)&grps};
David Sedláke3ce9ef2019-07-23 16:34:30 +02002443
2444 /* max subelems */
2445 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002446 "<grouping name=\"grp-name\">\n"
2447 " <anydata name=\"anyd\"/>\n"
2448 " <anyxml name=\"anyx\"/>\n"
2449 " <description><text>desc</text></description>\n"
2450 " <grouping name=\"sub-grp\"/>\n"
2451 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2452 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2453 " <list name=\"list\"/>\n"
2454 " <notification name=\"notf\"/>\n"
2455 " <reference><text>ref</text></reference>\n"
2456 " <status value=\"current\"/>\n"
2457 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2458 " <uses name=\"uses-name\"/>\n"
2459 " <action name=\"act\"/>\n"
2460 " <container name=\"cont\"/>\n"
2461 " <choice name=\"choice\"/>\n"
2462 EXT_SUBELEM
2463 "</grouping>"
2464 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002465 assert_int_equal(test_element_helper(state, data, &grp_meta, NULL, NULL), LY_SUCCESS);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002466 assert_string_equal(grps->name, "grp-name");
Radek Krejci01180ac2021-01-27 08:48:22 +01002467 assert_string_equal(grps->child->name, "anyd");
2468 assert_string_equal(grps->child->next->name, "anyx");
2469 assert_string_equal(grps->child->next->next->name, "leaf");
2470 assert_string_equal(grps->child->next->next->next->name, "llist");
2471 assert_string_equal(grps->child->next->next->next->next->name, "list");
David Sedláke3ce9ef2019-07-23 16:34:30 +02002472 assert_string_equal(grps->dsc, "desc");
David Sedláke3ce9ef2019-07-23 16:34:30 +02002473 assert_true(grps->flags & LYS_STATUS_CURR);
2474 assert_string_equal(grps->groupings->name, "sub-grp");
2475 assert_int_equal(grps->nodetype, LYS_GROUPING);
2476 assert_string_equal(grps->notifs->name, "notf");
2477 assert_null(grps->parent);
2478 assert_string_equal(grps->ref, "ref");
2479 assert_string_equal(grps->typedefs->name, "tpdf");
David Sedlák85d0eca2019-07-24 15:15:21 +02002480 assert_string_equal(grps->actions->name, "act");
Radek Krejci01180ac2021-01-27 08:48:22 +01002481 assert_string_equal(grps->child->next->next->next->next->next->name, "uses-name");
2482 assert_int_equal(grps->child->next->next->next->next->next->nodetype, LYS_USES);
2483 assert_string_equal(grps->child->next->next->next->next->next->next->name, "cont");
2484 assert_int_equal(grps->child->next->next->next->next->next->next->nodetype, LYS_CONTAINER);
2485 assert_string_equal(grps->child->next->next->next->next->next->next->next->name, "choice");
2486 assert_int_equal(grps->child->next->next->next->next->next->next->next->nodetype, LYS_CHOICE);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002487 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(grps->exts[0]), LY_STMT_GROUPING);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002488 lysp_node_free(&fctx, &grps->node);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002489 grps = NULL;
2490
2491 /* min subelems */
2492 data = ELEMENT_WRAPPER_START "<grouping name=\"grp-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002493 assert_int_equal(test_element_helper(state, data, &grp_meta, NULL, NULL), LY_SUCCESS);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002494 assert_string_equal(grps->name, "grp-name");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002495 lysp_node_free(&fctx, &grps->node);
David Sedláke3ce9ef2019-07-23 16:34:30 +02002496 grps = NULL;
David Sedlák031b9e72019-07-23 15:19:37 +02002497}
2498
David Sedlákf111bcb2019-07-23 17:15:51 +02002499static void
2500test_container_elem(void **state)
2501{
David Sedlákf111bcb2019-07-23 17:15:51 +02002502 const char *data;
2503 struct lysp_node *siblings = NULL;
2504 struct tree_node_meta node_meta = {NULL, &siblings};
2505 struct lysp_node_container *parsed = NULL;
2506
2507 /* max subelems */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002508 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedláke2dc9e92019-07-24 09:59:21 +02002509 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002510 "<container name=\"cont-name\">\n"
2511 " <anydata name=\"anyd\"/>\n"
2512 " <anyxml name=\"anyx\"/>\n"
2513 " <config value=\"true\"/>\n"
2514 " <container name=\"subcont\"/>\n"
2515 " <description><text>desc</text></description>\n"
2516 " <grouping name=\"sub-grp\"/>\n"
2517 " <if-feature name=\"iff\"/>\n"
2518 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2519 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2520 " <list name=\"list\"/>\n"
2521 " <must condition=\"cond\"/>\n"
2522 " <notification name=\"notf\"/>\n"
2523 " <presence value=\"presence\"/>\n"
2524 " <reference><text>ref</text></reference>\n"
2525 " <status value=\"current\"/>\n"
2526 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2527 " <uses name=\"uses-name\"/>\n"
2528 " <when condition=\"when-cond\"/>\n"
2529 " <action name=\"act\"/>\n"
2530 " <choice name=\"choice\"/>\n"
2531 EXT_SUBELEM
2532 "</container>"
2533 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002534 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedláke2dc9e92019-07-24 09:59:21 +02002535 parsed = (struct lysp_node_container *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002536 uint16_t flags = LYS_CONFIG_W | LYS_STATUS_CURR;
2537
2538 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2539 "cont-name", 0, LYS_CONTAINER, 0, "ref", 1);
2540 CHECK_LYSP_RESTR(parsed->musts, "cond", NULL, NULL, NULL, 0, NULL);
2541 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
2542
Michal Vasko7f45cf22020-10-01 12:49:44 +02002543 assert_string_equal(parsed->iffeatures[0].str, "iff");
David Sedláke2dc9e92019-07-24 09:59:21 +02002544 assert_string_equal(parsed->presence, "presence");
2545 assert_string_equal(parsed->typedefs->name, "tpdf");
2546 assert_string_equal(parsed->groupings->name, "sub-grp");
2547 assert_string_equal(parsed->child->name, "anyd");
2548 assert_int_equal(parsed->child->nodetype, LYS_ANYDATA);
2549 assert_string_equal(parsed->child->next->name, "anyx");
2550 assert_int_equal(parsed->child->next->nodetype, LYS_ANYXML);
2551 assert_string_equal(parsed->child->next->next->name, "subcont");
2552 assert_int_equal(parsed->child->next->next->nodetype, LYS_CONTAINER);
2553 assert_string_equal(parsed->child->next->next->next->name, "leaf");
2554 assert_int_equal(parsed->child->next->next->next->nodetype, LYS_LEAF);
2555 assert_string_equal(parsed->child->next->next->next->next->name, "llist");
2556 assert_int_equal(parsed->child->next->next->next->next->nodetype, LYS_LEAFLIST);
2557 assert_string_equal(parsed->child->next->next->next->next->next->name, "list");
2558 assert_int_equal(parsed->child->next->next->next->next->next->nodetype, LYS_LIST);
2559 assert_string_equal(parsed->child->next->next->next->next->next->next->name, "uses-name");
2560 assert_int_equal(parsed->child->next->next->next->next->next->next->nodetype, LYS_USES);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002561 assert_string_equal(parsed->child->next->next->next->next->next->next->next->name, "choice");
2562 assert_int_equal(parsed->child->next->next->next->next->next->next->next->nodetype, LYS_CHOICE);
2563 assert_null(parsed->child->next->next->next->next->next->next->next->next);
David Sedláke2dc9e92019-07-24 09:59:21 +02002564 assert_string_equal(parsed->notifs->name, "notf");
David Sedlák85d0eca2019-07-24 15:15:21 +02002565 assert_string_equal(parsed->actions->name, "act");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002566 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_CONTAINER);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002567 lysp_node_free(&fctx, siblings);
Radek Iša56ca9e42020-09-08 18:42:00 +02002568 ly_set_erase(&YCTX->tpdfs_nodes, NULL);
David Sedláke2dc9e92019-07-24 09:59:21 +02002569 siblings = NULL;
David Sedlákf111bcb2019-07-23 17:15:51 +02002570
2571 /* min subelems */
2572 data = ELEMENT_WRAPPER_START "<container name=\"cont-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002573 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákf111bcb2019-07-23 17:15:51 +02002574 parsed = (struct lysp_node_container *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002575 CHECK_LYSP_NODE(parsed, NULL, 0, 0, 0,
2576 "cont-name", 0, LYS_CONTAINER, 0, NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002577 lysp_node_free(&fctx, siblings);
David Sedlákf111bcb2019-07-23 17:15:51 +02002578 siblings = NULL;
David Sedlákf111bcb2019-07-23 17:15:51 +02002579}
2580
David Sedlák5379d392019-07-24 10:42:03 +02002581static void
2582test_case_elem(void **state)
2583{
David Sedlák5379d392019-07-24 10:42:03 +02002584 const char *data;
2585 struct lysp_node *siblings = NULL;
2586 struct tree_node_meta node_meta = {NULL, &siblings};
2587 struct lysp_node_case *parsed = NULL;
2588
2589 /* max subelems */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002590 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák5379d392019-07-24 10:42:03 +02002591 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002592 "<case name=\"case-name\">\n"
2593 " <anydata name=\"anyd\"/>\n"
2594 " <anyxml name=\"anyx\"/>\n"
2595 " <container name=\"subcont\"/>\n"
2596 " <description><text>desc</text></description>\n"
2597 " <if-feature name=\"iff\"/>\n"
2598 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2599 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2600 " <list name=\"list\"/>\n"
2601 " <reference><text>ref</text></reference>\n"
2602 " <status value=\"current\"/>\n"
2603 " <uses name=\"uses-name\"/>\n"
2604 " <when condition=\"when-cond\"/>\n"
2605 " <choice name=\"choice\"/>\n"
2606 EXT_SUBELEM
2607 "</case>"
2608 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002609 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák5379d392019-07-24 10:42:03 +02002610 parsed = (struct lysp_node_case *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002611 uint16_t flags = LYS_STATUS_CURR;
2612
2613 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2614 "case-name", 0, LYS_CASE, 0, "ref", 1);
2615 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002616 assert_string_equal(parsed->iffeatures[0].str, "iff");
David Sedlák5379d392019-07-24 10:42:03 +02002617 assert_string_equal(parsed->child->name, "anyd");
2618 assert_int_equal(parsed->child->nodetype, LYS_ANYDATA);
2619 assert_string_equal(parsed->child->next->name, "anyx");
2620 assert_int_equal(parsed->child->next->nodetype, LYS_ANYXML);
2621 assert_string_equal(parsed->child->next->next->name, "subcont");
2622 assert_int_equal(parsed->child->next->next->nodetype, LYS_CONTAINER);
2623 assert_string_equal(parsed->child->next->next->next->name, "leaf");
2624 assert_int_equal(parsed->child->next->next->next->nodetype, LYS_LEAF);
2625 assert_string_equal(parsed->child->next->next->next->next->name, "llist");
2626 assert_int_equal(parsed->child->next->next->next->next->nodetype, LYS_LEAFLIST);
2627 assert_string_equal(parsed->child->next->next->next->next->next->name, "list");
2628 assert_int_equal(parsed->child->next->next->next->next->next->nodetype, LYS_LIST);
2629 assert_string_equal(parsed->child->next->next->next->next->next->next->name, "uses-name");
2630 assert_int_equal(parsed->child->next->next->next->next->next->next->nodetype, LYS_USES);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002631 assert_string_equal(parsed->child->next->next->next->next->next->next->next->name, "choice");
2632 assert_int_equal(parsed->child->next->next->next->next->next->next->next->nodetype, LYS_CHOICE);
2633 assert_null(parsed->child->next->next->next->next->next->next->next->next);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002634 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_CASE);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002635 lysp_node_free(&fctx, siblings);
David Sedlák5379d392019-07-24 10:42:03 +02002636 siblings = NULL;
2637
2638 /* min subelems */
2639 data = ELEMENT_WRAPPER_START "<case name=\"case-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002640 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlák5379d392019-07-24 10:42:03 +02002641 parsed = (struct lysp_node_case *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002642 CHECK_LYSP_NODE(parsed, NULL, 0, 0, 0,
2643 "case-name", 0, LYS_CASE, 0, NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002644 lysp_node_free(&fctx, siblings);
David Sedlák5379d392019-07-24 10:42:03 +02002645 siblings = NULL;
David Sedlák5379d392019-07-24 10:42:03 +02002646}
2647
David Sedlákb7abcfa2019-07-24 12:33:35 +02002648static void
2649test_choice_elem(void **state)
2650{
David Sedlákb7abcfa2019-07-24 12:33:35 +02002651 const char *data;
2652 struct lysp_node *siblings = NULL;
2653 struct tree_node_meta node_meta = {NULL, &siblings};
2654 struct lysp_node_choice *parsed = NULL;
2655
2656 /* max subelems */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002657 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlákb7abcfa2019-07-24 12:33:35 +02002658 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002659 "<choice name=\"choice-name\">\n"
2660 " <anydata name=\"anyd\"/>\n"
2661 " <anyxml name=\"anyx\"/>\n"
2662 " <case name=\"sub-case\"/>\n"
2663 " <choice name=\"choice\"/>\n"
2664 " <config value=\"true\"/>\n"
2665 " <container name=\"subcont\"/>\n"
2666 " <default value=\"def\"/>\n"
2667 " <description><text>desc</text></description>\n"
2668 " <if-feature name=\"iff\"/>\n"
2669 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2670 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2671 " <list name=\"list\"/>\n"
2672 " <mandatory value=\"true\" />\n"
2673 " <reference><text>ref</text></reference>\n"
2674 " <status value=\"current\"/>\n"
2675 " <when condition=\"when-cond\"/>\n"
2676 EXT_SUBELEM
2677 "</choice>"
2678 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002679 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002680 parsed = (struct lysp_node_choice *)siblings;
Radek Iša56ca9e42020-09-08 18:42:00 +02002681 uint16_t flags = LYS_CONFIG_W | LYS_MAND_TRUE | LYS_STATUS_CURR;
2682
2683 CHECK_LYSP_NODE(parsed, "desc", 1, flags, 1,
2684 "choice-name", 0, LYS_CHOICE, 0, "ref", 1);
2685 CHECK_LYSP_WHEN(parsed->when, "when-cond", NULL, 0, NULL);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002686 assert_string_equal(parsed->iffeatures[0].str, "iff");
David Sedlákb7abcfa2019-07-24 12:33:35 +02002687 assert_string_equal(parsed->child->name, "anyd");
2688 assert_int_equal(parsed->child->nodetype, LYS_ANYDATA);
2689 assert_string_equal(parsed->child->next->name, "anyx");
2690 assert_int_equal(parsed->child->next->nodetype, LYS_ANYXML);
2691 assert_string_equal(parsed->child->next->next->name, "sub-case");
2692 assert_int_equal(parsed->child->next->next->nodetype, LYS_CASE);
2693 assert_string_equal(parsed->child->next->next->next->name, "choice");
2694 assert_int_equal(parsed->child->next->next->next->nodetype, LYS_CHOICE);
2695 assert_string_equal(parsed->child->next->next->next->next->name, "subcont");
2696 assert_int_equal(parsed->child->next->next->next->next->nodetype, LYS_CONTAINER);
2697 assert_string_equal(parsed->child->next->next->next->next->next->name, "leaf");
2698 assert_int_equal(parsed->child->next->next->next->next->next->nodetype, LYS_LEAF);
2699 assert_string_equal(parsed->child->next->next->next->next->next->next->name, "llist");
2700 assert_int_equal(parsed->child->next->next->next->next->next->next->nodetype, LYS_LEAFLIST);
2701 assert_string_equal(parsed->child->next->next->next->next->next->next->next->name, "list");
2702 assert_int_equal(parsed->child->next->next->next->next->next->next->next->nodetype, LYS_LIST);
2703 assert_null(parsed->child->next->next->next->next->next->next->next->next);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002704 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(parsed->exts[0]), LY_STMT_CHOICE);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002705 lysp_node_free(&fctx, siblings);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002706 siblings = NULL;
2707
2708 /* min subelems */
2709 data = ELEMENT_WRAPPER_START "<choice name=\"choice-name\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002710 assert_int_equal(test_element_helper(state, data, &node_meta, NULL, NULL), LY_SUCCESS);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002711 parsed = (struct lysp_node_choice *)siblings;
2712 assert_string_equal(parsed->name, "choice-name");
Radek Iša56ca9e42020-09-08 18:42:00 +02002713 CHECK_LYSP_NODE(parsed, NULL, 0, 0, 0,
2714 "choice-name", 0, LYS_CHOICE, 0, NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002715 lysp_node_free(&fctx, siblings);
David Sedlákb7abcfa2019-07-24 12:33:35 +02002716 siblings = NULL;
David Sedlákb7abcfa2019-07-24 12:33:35 +02002717}
2718
David Sedlák05404f62019-07-24 14:11:53 +02002719static void
2720test_inout_elem(void **state)
2721{
David Sedlák05404f62019-07-24 14:11:53 +02002722 const char *data;
Michal Vasko2a6c53f2021-09-22 12:20:05 +02002723 struct lysp_node_action_inout inout = {0};
David Sedlák05404f62019-07-24 14:11:53 +02002724 struct inout_meta inout_meta = {NULL, &inout};
2725
2726 /* max subelements */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002727 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák05404f62019-07-24 14:11:53 +02002728 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002729 "<input>\n"
2730 " <anydata name=\"anyd\"/>\n"
2731 " <anyxml name=\"anyx\"/>\n"
2732 " <choice name=\"choice\"/>\n"
2733 " <container name=\"subcont\"/>\n"
2734 " <grouping name=\"sub-grp\"/>\n"
2735 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2736 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2737 " <list name=\"list\"/>\n"
2738 " <must condition=\"cond\"/>\n"
2739 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2740 " <uses name=\"uses-name\"/>\n"
2741 EXT_SUBELEM
2742 "</input>"
2743 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002744 assert_int_equal(test_element_helper(state, data, &inout_meta, NULL, NULL), LY_SUCCESS);
2745 CHECK_LYSP_ACTION_INOUT(&(inout), 1, 1, 1, 1, LYS_INPUT, 0, 1);
2746 CHECK_LYSP_RESTR(inout.musts, "cond", NULL, NULL, NULL, 0, NULL);
David Sedlák05404f62019-07-24 14:11:53 +02002747 assert_string_equal(inout.typedefs->name, "tpdf");
2748 assert_string_equal(inout.groupings->name, "sub-grp");
Radek Krejci01180ac2021-01-27 08:48:22 +01002749 assert_string_equal(inout.child->name, "anyd");
2750 assert_int_equal(inout.child->nodetype, LYS_ANYDATA);
2751 assert_string_equal(inout.child->next->name, "anyx");
2752 assert_int_equal(inout.child->next->nodetype, LYS_ANYXML);
2753 assert_string_equal(inout.child->next->next->name, "choice");
2754 assert_int_equal(inout.child->next->next->nodetype, LYS_CHOICE);
2755 assert_string_equal(inout.child->next->next->next->name, "subcont");
2756 assert_int_equal(inout.child->next->next->next->nodetype, LYS_CONTAINER);
2757 assert_string_equal(inout.child->next->next->next->next->name, "leaf");
2758 assert_int_equal(inout.child->next->next->next->next->nodetype, LYS_LEAF);
2759 assert_string_equal(inout.child->next->next->next->next->next->name, "llist");
2760 assert_int_equal(inout.child->next->next->next->next->next->nodetype, LYS_LEAFLIST);
2761 assert_string_equal(inout.child->next->next->next->next->next->next->name, "list");
2762 assert_int_equal(inout.child->next->next->next->next->next->next->nodetype, LYS_LIST);
2763 assert_string_equal(inout.child->next->next->next->next->next->next->next->name, "uses-name");
2764 assert_int_equal(inout.child->next->next->next->next->next->next->next->nodetype, LYS_USES);
2765 assert_null(inout.child->next->next->next->next->next->next->next->next);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002766 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(inout.exts[0]), LY_STMT_INPUT);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002767 lysp_node_free(&fctx, (struct lysp_node *)&inout);
David Sedlák05404f62019-07-24 14:11:53 +02002768 memset(&inout, 0, sizeof inout);
2769
2770 /* max subelements */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002771 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák05404f62019-07-24 14:11:53 +02002772 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002773 "<output>\n"
2774 " <anydata name=\"anyd\"/>\n"
2775 " <anyxml name=\"anyx\"/>\n"
2776 " <choice name=\"choice\"/>\n"
2777 " <container name=\"subcont\"/>\n"
2778 " <grouping name=\"sub-grp\"/>\n"
2779 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2780 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2781 " <list name=\"list\"/>\n"
2782 " <must condition=\"cond\"/>\n"
2783 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2784 " <uses name=\"uses-name\"/>\n"
2785 EXT_SUBELEM
2786 "</output>"
2787 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002788 assert_int_equal(test_element_helper(state, data, &inout_meta, NULL, NULL), LY_SUCCESS);
2789 CHECK_LYSP_ACTION_INOUT(&(inout), 1, 1, 1, 1, LYS_OUTPUT, 0, 1);
Michal Vasko7f45cf22020-10-01 12:49:44 +02002790 assert_string_equal(inout.musts->arg.str, "cond");
David Sedlák05404f62019-07-24 14:11:53 +02002791 assert_string_equal(inout.typedefs->name, "tpdf");
2792 assert_string_equal(inout.groupings->name, "sub-grp");
Radek Krejci01180ac2021-01-27 08:48:22 +01002793 assert_string_equal(inout.child->name, "anyd");
2794 assert_int_equal(inout.child->nodetype, LYS_ANYDATA);
2795 assert_string_equal(inout.child->next->name, "anyx");
2796 assert_int_equal(inout.child->next->nodetype, LYS_ANYXML);
2797 assert_string_equal(inout.child->next->next->name, "choice");
2798 assert_int_equal(inout.child->next->next->nodetype, LYS_CHOICE);
2799 assert_string_equal(inout.child->next->next->next->name, "subcont");
2800 assert_int_equal(inout.child->next->next->next->nodetype, LYS_CONTAINER);
2801 assert_string_equal(inout.child->next->next->next->next->name, "leaf");
2802 assert_int_equal(inout.child->next->next->next->next->nodetype, LYS_LEAF);
2803 assert_string_equal(inout.child->next->next->next->next->next->name, "llist");
2804 assert_int_equal(inout.child->next->next->next->next->next->nodetype, LYS_LEAFLIST);
2805 assert_string_equal(inout.child->next->next->next->next->next->next->name, "list");
2806 assert_int_equal(inout.child->next->next->next->next->next->next->nodetype, LYS_LIST);
2807 assert_string_equal(inout.child->next->next->next->next->next->next->next->name, "uses-name");
2808 assert_int_equal(inout.child->next->next->next->next->next->next->next->nodetype, LYS_USES);
2809 assert_null(inout.child->next->next->next->next->next->next->next->next);
Radek Krejci39b7fc22021-02-26 23:29:18 +01002810 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(inout.exts[0]), LY_STMT_OUTPUT);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002811 lysp_node_free(&fctx, (struct lysp_node *)&inout);
David Sedlák05404f62019-07-24 14:11:53 +02002812 memset(&inout, 0, sizeof inout);
2813
2814 /* min subelems */
Michal Vaskob83af8a2020-01-06 09:49:22 +01002815 data = ELEMENT_WRAPPER_START "<input><leaf name=\"l\"><type name=\"empty\"/></leaf></input>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002816 assert_int_equal(test_element_helper(state, data, &inout_meta, NULL, NULL), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002817 lysp_node_free(&fctx, (struct lysp_node *)&inout);
David Sedlák05404f62019-07-24 14:11:53 +02002818 memset(&inout, 0, sizeof inout);
2819
Michal Vaskob83af8a2020-01-06 09:49:22 +01002820 data = ELEMENT_WRAPPER_START "<output><leaf name=\"l\"><type name=\"empty\"/></leaf></output>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002821 assert_int_equal(test_element_helper(state, data, &inout_meta, NULL, NULL), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002822 lysp_node_free(&fctx, (struct lysp_node *)&inout);
David Sedlák05404f62019-07-24 14:11:53 +02002823 memset(&inout, 0, sizeof inout);
2824
2825 /* invalid combinations */
2826 data = ELEMENT_WRAPPER_START "<input name=\"test\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002827 assert_int_equal(test_element_helper(state, data, &inout_meta, NULL, NULL), LY_EVALID);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002828 lysp_node_free(&fctx, (struct lysp_node *)&inout);
Michal Vasko7a266772024-01-23 11:02:38 +01002829 CHECK_LOG_CTX("Unexpected attribute \"name\" of \"input\" element.", NULL, 1);
David Sedlák05404f62019-07-24 14:11:53 +02002830 memset(&inout, 0, sizeof inout);
David Sedlák05404f62019-07-24 14:11:53 +02002831}
2832
David Sedlák85d0eca2019-07-24 15:15:21 +02002833static void
2834test_action_elem(void **state)
2835{
David Sedlák85d0eca2019-07-24 15:15:21 +02002836 const char *data;
Radek Krejci2a9fc652021-01-22 17:44:34 +01002837 struct lysp_node_action *actions = NULL;
David Sedlák6881b512019-08-13 12:52:00 +02002838 struct tree_node_meta act_meta = {NULL, (struct lysp_node **)&actions};
Radek Iša56ca9e42020-09-08 18:42:00 +02002839 uint16_t flags;
David Sedlák85d0eca2019-07-24 15:15:21 +02002840
2841 /* max subelems */
Michal Vasko8a67eff2021-12-07 14:04:47 +01002842 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák85d0eca2019-07-24 15:15:21 +02002843 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002844 "<action name=\"act\">\n"
2845 " <description><text>desc</text></description>\n"
2846 " <grouping name=\"grouping\"/>\n"
2847 " <if-feature name=\"iff\"/>\n"
2848 " <input><uses name=\"uses-name\"/></input>\n"
2849 " <output><must condition=\"cond\"/><leaf name=\"l\"><type name=\"type\"/></leaf></output>\n"
2850 " <reference><text>ref</text></reference>\n"
2851 " <status value=\"deprecated\"/>\n"
2852 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2853 EXT_SUBELEM
2854 "</action>"
2855 ELEMENT_WRAPPER_END;
Michal Vasko1bf09392020-03-27 12:38:10 +01002856 /* there must be parent for action */
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002857 act_meta.parent = (void *)1;
Radek Iša56ca9e42020-09-08 18:42:00 +02002858 assert_int_equal(test_element_helper(state, data, &act_meta, NULL, NULL), LY_SUCCESS);
Michal Vasko1bf09392020-03-27 12:38:10 +01002859 act_meta.parent = NULL;
Radek Iša56ca9e42020-09-08 18:42:00 +02002860 flags = LYS_STATUS_DEPRC;
2861 CHECK_LYSP_ACTION(actions, "desc", 1, flags, 1, 1,\
2862 1, 0, 0, 0,\
2863 1, 0,\
2864 "act", LYS_ACTION, \
2865 1, 0, 0, 1,\
2866 1, 0,\
2867 1, "ref", 1);
2868
Michal Vasko7f45cf22020-10-01 12:49:44 +02002869 assert_string_equal(actions->iffeatures[0].str, "iff");
David Sedlák85d0eca2019-07-24 15:15:21 +02002870 assert_string_equal(actions->typedefs->name, "tpdf");
2871 assert_string_equal(actions->groupings->name, "grouping");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002872 assert_string_equal(actions->output.musts->arg.str, "cond");
Radek Krejci01180ac2021-01-27 08:48:22 +01002873 assert_string_equal(actions->input.child->name, "uses-name");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002874 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(actions->exts[0]), LY_STMT_ACTION);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002875 lysp_node_free(&fctx, (struct lysp_node *)actions);
David Sedlák85d0eca2019-07-24 15:15:21 +02002876 actions = NULL;
2877
Michal Vasko8a67eff2021-12-07 14:04:47 +01002878 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlákeaa45792019-07-24 15:25:01 +02002879 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002880 "<rpc name=\"act\">\n"
2881 " <description><text>desc</text></description>\n"
2882 " <grouping name=\"grouping\"/>\n"
2883 " <if-feature name=\"iff\"/>\n"
2884 " <input><uses name=\"uses-name\"/></input>\n"
2885 " <output><must condition=\"cond\"/><leaf name=\"l\"><type name=\"type\"/></leaf></output>\n"
2886 " <reference><text>ref</text></reference>\n"
2887 " <status value=\"deprecated\"/>\n"
2888 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
2889 EXT_SUBELEM
2890 "</rpc>"
2891 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002892 assert_int_equal(test_element_helper(state, data, &act_meta, NULL, NULL), LY_SUCCESS);
2893 flags = LYS_STATUS_DEPRC;
2894 CHECK_LYSP_ACTION(actions, "desc", 1, flags, 1, 1,\
2895 1, 0, 0, 0,\
2896 1, 0,\
2897 "act", LYS_RPC, \
2898 1, 0, 0, 1,\
2899 1, 0,\
2900 0, "ref", 1);
2901
Michal Vasko7f45cf22020-10-01 12:49:44 +02002902 assert_string_equal(actions->iffeatures[0].str, "iff");
David Sedlákeaa45792019-07-24 15:25:01 +02002903 assert_string_equal(actions->typedefs->name, "tpdf");
2904 assert_string_equal(actions->groupings->name, "grouping");
Radek Krejci01180ac2021-01-27 08:48:22 +01002905 assert_string_equal(actions->input.child->name, "uses-name");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002906 assert_string_equal(actions->output.musts->arg.str, "cond");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002907 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(actions->exts[0]), LY_STMT_RPC);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002908 lysp_node_free(&fctx, (struct lysp_node *)actions);
David Sedlákeaa45792019-07-24 15:25:01 +02002909 actions = NULL;
2910
David Sedlák85d0eca2019-07-24 15:15:21 +02002911 /* min subelems */
2912 data = ELEMENT_WRAPPER_START "<action name=\"act\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002913 assert_int_equal(test_element_helper(state, data, &act_meta, NULL, NULL), LY_SUCCESS);
David Sedlák85d0eca2019-07-24 15:15:21 +02002914 assert_string_equal(actions->name, "act");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002915 lysp_node_free(&fctx, (struct lysp_node *)actions);
David Sedlák85d0eca2019-07-24 15:15:21 +02002916 actions = NULL;
David Sedlák85d0eca2019-07-24 15:15:21 +02002917}
2918
David Sedlák992fb7c2019-07-24 16:51:01 +02002919static void
2920test_augment_elem(void **state)
2921{
David Sedlák992fb7c2019-07-24 16:51:01 +02002922 const char *data;
Radek Krejci2a9fc652021-01-22 17:44:34 +01002923 struct lysp_node_augment *augments = NULL;
David Sedlák6881b512019-08-13 12:52:00 +02002924 struct tree_node_meta aug_meta = {NULL, (struct lysp_node **)&augments};
David Sedlák992fb7c2019-07-24 16:51:01 +02002925
Michal Vasko8a67eff2021-12-07 14:04:47 +01002926 PARSER_CUR_PMOD(YCTX)->version = LYS_VERSION_1_1;
David Sedlák992fb7c2019-07-24 16:51:01 +02002927 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01002928 "<augment target-node=\"target\">\n"
2929 " <action name=\"action\"/>\n"
2930 " <anydata name=\"anyd\"/>\n"
2931 " <anyxml name=\"anyx\"/>\n"
2932 " <case name=\"case\"/>\n"
2933 " <choice name=\"choice\"/>\n"
2934 " <container name=\"subcont\"/>\n"
2935 " <description><text>desc</text></description>\n"
2936 " <if-feature name=\"iff\"/>\n"
2937 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
2938 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
2939 " <list name=\"list\"/>\n"
2940 " <notification name=\"notif\"/>\n"
2941 " <reference><text>ref</text></reference>\n"
2942 " <status value=\"current\"/>\n"
2943 " <uses name=\"uses\"/>\n"
2944 " <when condition=\"when-cond\"/>\n"
2945 EXT_SUBELEM
2946 "</augment>"
2947 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002948 assert_int_equal(test_element_helper(state, data, &aug_meta, NULL, NULL), LY_SUCCESS);
David Sedlák992fb7c2019-07-24 16:51:01 +02002949 assert_string_equal(augments->nodeid, "target");
2950 assert_null(augments->parent);
2951 assert_int_equal(augments->nodetype, LYS_AUGMENT);
2952 assert_true(augments->flags & LYS_STATUS_CURR);
2953 assert_string_equal(augments->dsc, "desc");
2954 assert_string_equal(augments->ref, "ref");
2955 assert_string_equal(augments->when->cond, "when-cond");
Michal Vasko7f45cf22020-10-01 12:49:44 +02002956 assert_string_equal(augments->iffeatures[0].str, "iff");
David Sedlák992fb7c2019-07-24 16:51:01 +02002957 assert_string_equal(augments->child->name, "anyd");
2958 assert_int_equal(augments->child->nodetype, LYS_ANYDATA);
2959 assert_string_equal(augments->child->next->name, "anyx");
2960 assert_int_equal(augments->child->next->nodetype, LYS_ANYXML);
2961 assert_string_equal(augments->child->next->next->name, "case");
2962 assert_int_equal(augments->child->next->next->nodetype, LYS_CASE);
2963 assert_string_equal(augments->child->next->next->next->name, "choice");
2964 assert_int_equal(augments->child->next->next->next->nodetype, LYS_CHOICE);
2965 assert_string_equal(augments->child->next->next->next->next->name, "subcont");
2966 assert_int_equal(augments->child->next->next->next->next->nodetype, LYS_CONTAINER);
2967 assert_string_equal(augments->child->next->next->next->next->next->name, "leaf");
2968 assert_int_equal(augments->child->next->next->next->next->next->nodetype, LYS_LEAF);
2969 assert_string_equal(augments->child->next->next->next->next->next->next->name, "llist");
2970 assert_int_equal(augments->child->next->next->next->next->next->next->nodetype, LYS_LEAFLIST);
2971 assert_string_equal(augments->child->next->next->next->next->next->next->next->name, "list");
2972 assert_int_equal(augments->child->next->next->next->next->next->next->next->nodetype, LYS_LIST);
2973 assert_string_equal(augments->child->next->next->next->next->next->next->next->next->name, "uses");
2974 assert_int_equal(augments->child->next->next->next->next->next->next->next->next->nodetype, LYS_USES);
2975 assert_null(augments->child->next->next->next->next->next->next->next->next->next);
2976 assert_string_equal(augments->actions->name, "action");
2977 assert_string_equal(augments->notifs->name, "notif");
Radek Krejci39b7fc22021-02-26 23:29:18 +01002978 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(augments->exts[0]), LY_STMT_AUGMENT);
Michal Vaskoc636ea42022-09-16 10:20:31 +02002979 lysp_node_free(&fctx, (struct lysp_node *)augments);
David Sedlák992fb7c2019-07-24 16:51:01 +02002980 augments = NULL;
2981
2982 data = ELEMENT_WRAPPER_START "<augment target-node=\"target\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002983 assert_int_equal(test_element_helper(state, data, &aug_meta, NULL, NULL), LY_SUCCESS);
David Sedlák992fb7c2019-07-24 16:51:01 +02002984 assert_string_equal(augments->nodeid, "target");
Michal Vaskoc636ea42022-09-16 10:20:31 +02002985 lysp_node_free(&fctx, (struct lysp_node *)augments);
David Sedlák992fb7c2019-07-24 16:51:01 +02002986 augments = NULL;
David Sedlák992fb7c2019-07-24 16:51:01 +02002987}
2988
David Sedlák4ffcec82019-07-25 15:10:21 +02002989static void
2990test_deviate_elem(void **state)
2991{
David Sedlák4ffcec82019-07-25 15:10:21 +02002992 const char *data;
2993 struct lysp_deviate *deviates = NULL;
David Sedlák4ffcec82019-07-25 15:10:21 +02002994
2995 /* invalid arguments */
2996 data = ELEMENT_WRAPPER_START "<deviate value=\"\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02002997 assert_int_equal(test_element_helper(state, data, &deviates, NULL, NULL), LY_EVALID);
2998 CHECK_LOG_CTX("Invalid value \"\" of \"value\" attribute in \"deviate\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01002999 "Valid values are \"not-supported\", \"add\", \"replace\" and \"delete\".", NULL, 1);
David Sedlák4ffcec82019-07-25 15:10:21 +02003000 deviates = NULL;
3001
3002 data = ELEMENT_WRAPPER_START "<deviate value=\"invalid\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02003003 assert_int_equal(test_element_helper(state, data, &deviates, NULL, NULL), LY_EVALID);
3004 CHECK_LOG_CTX("Invalid value \"invalid\" of \"value\" attribute in \"deviate\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01003005 "Valid values are \"not-supported\", \"add\", \"replace\" and \"delete\".", NULL, 1);
David Sedlák4ffcec82019-07-25 15:10:21 +02003006 deviates = NULL;
3007
3008 data = ELEMENT_WRAPPER_START "<deviate value=\"ad\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02003009 assert_int_equal(test_element_helper(state, data, &deviates, NULL, NULL), LY_EVALID);
3010 CHECK_LOG_CTX("Invalid value \"ad\" of \"value\" attribute in \"deviate\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01003011 "Valid values are \"not-supported\", \"add\", \"replace\" and \"delete\".", NULL, 1);
David Sedlák4ffcec82019-07-25 15:10:21 +02003012 deviates = NULL;
3013
3014 data = ELEMENT_WRAPPER_START "<deviate value=\"adds\" />" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02003015 assert_int_equal(test_element_helper(state, data, &deviates, NULL, NULL), LY_EVALID);
3016 CHECK_LOG_CTX("Invalid value \"adds\" of \"value\" attribute in \"deviate\" element. "
Michal Vasko7a266772024-01-23 11:02:38 +01003017 "Valid values are \"not-supported\", \"add\", \"replace\" and \"delete\".", NULL, 1);
David Sedlák4ffcec82019-07-25 15:10:21 +02003018 deviates = NULL;
3019
3020 data = ELEMENT_WRAPPER_START
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003021 "<deviate value=\"not-supported\">\n"
3022 " <must condition=\"c\"/>\n"
3023 "</deviate>"
3024 ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02003025 assert_int_equal(test_element_helper(state, data, &deviates, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003026 CHECK_LOG_CTX("Deviate of this type doesn't allow \"must\" as it's sub-element.", NULL, 2);
David Sedlák4ffcec82019-07-25 15:10:21 +02003027}
3028
David Sedlák8b754462019-07-25 16:22:13 +02003029static void
3030test_deviation_elem(void **state)
3031{
David Sedlák8b754462019-07-25 16:22:13 +02003032 const char *data;
3033 struct lysp_deviation *deviations = NULL;
3034
David Sedlák8b754462019-07-25 16:22:13 +02003035 /* invalid */
3036 data = ELEMENT_WRAPPER_START "<deviation target-node=\"target\"/>" ELEMENT_WRAPPER_END;
Radek Iša56ca9e42020-09-08 18:42:00 +02003037 assert_int_equal(test_element_helper(state, data, &deviations, NULL, NULL), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003038 CHECK_LOG_CTX("Missing mandatory sub-element \"deviate\" of \"deviation\" element.", NULL, 1);
Michal Vasko12ef5362022-09-16 15:13:58 +02003039}
David Sedlák8b754462019-07-25 16:22:13 +02003040
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003041static struct lysp_module *
Michal Vaskod0625d72022-10-06 15:02:50 +02003042mod_renew(struct lysp_yin_ctx *ctx)
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003043{
Michal Vasko8a67eff2021-12-07 14:04:47 +01003044 struct ly_ctx *ly_ctx = PARSER_CUR_PMOD(ctx)->mod->ctx;
3045 struct lysp_module *pmod;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003046
Michal Vaskoc636ea42022-09-16 10:20:31 +02003047 lys_module_free(&fctx, PARSER_CUR_PMOD(ctx)->mod, 0);
Michal Vasko8a67eff2021-12-07 14:04:47 +01003048 pmod = calloc(1, sizeof *pmod);
3049 ctx->parsed_mods->objs[0] = pmod;
3050 pmod->mod = calloc(1, sizeof *pmod->mod);
3051 pmod->mod->parsed = pmod;
3052 pmod->mod->ctx = ly_ctx;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003053
Michal Vaskoc636ea42022-09-16 10:20:31 +02003054 fctx.mod = pmod->mod;
3055
Michal Vasko8a67eff2021-12-07 14:04:47 +01003056 return pmod;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003057}
3058
David Sedlák4f03b932019-07-26 13:01:47 +02003059static void
3060test_module_elem(void **state)
3061{
Michal Vaskob36053d2020-03-26 15:49:30 +01003062 const char *data;
Radek Iša56ca9e42020-09-08 18:42:00 +02003063 struct lysp_module *lysp_mod = mod_renew(YCTX);
David Sedlák4f03b932019-07-26 13:01:47 +02003064
3065 /* max subelems */
David Sedlák4f03b932019-07-26 13:01:47 +02003066 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"mod\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003067 " <yang-version value=\"1.1\"/>\n"
3068 " <namespace uri=\"ns\"/>\n"
3069 " <prefix value=\"pref\"/>\n"
3070 " <include module=\"b-mod\"/>\n"
3071 " <import module=\"a-mod\"><prefix value=\"imp-pref\"/></import>\n"
3072 " <organization><text>org</text></organization>\n"
3073 " <contact><text>contact</text></contact>\n"
3074 " <description><text>desc</text></description>\n"
3075 " <reference><text>ref</text></reference>\n"
3076 " <revision date=\"2019-02-02\"/>\n"
3077 " <anydata name=\"anyd\"/>\n"
3078 " <anyxml name=\"anyx\"/>\n"
3079 " <choice name=\"choice\"/>\n"
3080 " <container name=\"cont\"/>\n"
3081 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
3082 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
3083 " <list name=\"sub-list\"/>\n"
3084 " <uses name=\"uses-name\"/>\n"
3085 " <augment target-node=\"target\"/>\n"
3086 " <deviation target-node=\"target\">\n"
3087 " <deviate value=\"not-supported\"/>\n"
3088 " </deviation>\n"
3089 " <extension name=\"ext\"/>\n"
3090 " <feature name=\"feature\"/>\n"
3091 " <grouping name=\"grp\"/>\n"
3092 " <identity name=\"ident-name\"/>\n"
3093 " <notification name=\"notf\"/>\n"
3094 " <rpc name=\"rpc-name\"/>\n"
3095 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
3096 EXT_SUBELEM "\n"
3097 "</module>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +02003098 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3099 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
Michal Vaskob36053d2020-03-26 15:49:30 +01003100
Radek Iša56ca9e42020-09-08 18:42:00 +02003101 assert_int_equal(yin_parse_mod(YCTX, lysp_mod), LY_SUCCESS);
David Sedlák4f03b932019-07-26 13:01:47 +02003102 assert_string_equal(lysp_mod->mod->name, "mod");
Michal Vasko892355e2023-03-14 13:37:48 +01003103 assert_string_equal(lysp_mod->revs[0].date, "2019-02-02");
David Sedlák4f03b932019-07-26 13:01:47 +02003104 assert_string_equal(lysp_mod->mod->ns, "ns");
3105 assert_string_equal(lysp_mod->mod->prefix, "pref");
3106 assert_null(lysp_mod->mod->filepath);
3107 assert_string_equal(lysp_mod->mod->org, "org");
3108 assert_string_equal(lysp_mod->mod->contact, "contact");
3109 assert_string_equal(lysp_mod->mod->dsc, "desc");
3110 assert_string_equal(lysp_mod->mod->ref, "ref");
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003111 assert_int_equal(lysp_mod->version, LYS_VERSION_1_1);
Radek Iša56ca9e42020-09-08 18:42:00 +02003112 CHECK_LYSP_IMPORT(lysp_mod->imports, NULL, 0, "a-mod",
3113 "imp-pref", NULL, "");
David Sedlák4f03b932019-07-26 13:01:47 +02003114 assert_string_equal(lysp_mod->includes->name, "b-mod");
3115 assert_string_equal(lysp_mod->extensions->name, "ext");
3116 assert_string_equal(lysp_mod->features->name, "feature");
3117 assert_string_equal(lysp_mod->identities->name, "ident-name");
3118 assert_string_equal(lysp_mod->typedefs->name, "tpdf");
3119 assert_string_equal(lysp_mod->groupings->name, "grp");
3120 assert_string_equal(lysp_mod->data->name, "anyd");
3121 assert_int_equal(lysp_mod->data->nodetype, LYS_ANYDATA);
3122 assert_string_equal(lysp_mod->data->next->name, "anyx");
3123 assert_int_equal(lysp_mod->data->next->nodetype, LYS_ANYXML);
3124 assert_string_equal(lysp_mod->data->next->next->name, "choice");
3125 assert_int_equal(lysp_mod->data->next->next->nodetype, LYS_CHOICE);
3126 assert_string_equal(lysp_mod->data->next->next->next->name, "cont");
3127 assert_int_equal(lysp_mod->data->next->next->next->nodetype, LYS_CONTAINER);
3128 assert_string_equal(lysp_mod->data->next->next->next->next->name, "leaf");
3129 assert_int_equal(lysp_mod->data->next->next->next->next->nodetype, LYS_LEAF);
3130 assert_string_equal(lysp_mod->data->next->next->next->next->next->name, "llist");
3131 assert_int_equal(lysp_mod->data->next->next->next->next->next->nodetype, LYS_LEAFLIST);
3132 assert_string_equal(lysp_mod->data->next->next->next->next->next->next->name, "sub-list");
3133 assert_int_equal(lysp_mod->data->next->next->next->next->next->next->nodetype, LYS_LIST);
3134 assert_string_equal(lysp_mod->data->next->next->next->next->next->next->next->name, "uses-name");
3135 assert_int_equal(lysp_mod->data->next->next->next->next->next->next->next->nodetype, LYS_USES);
3136 assert_null(lysp_mod->data->next->next->next->next->next->next->next->next);
3137 assert_string_equal(lysp_mod->augments->nodeid, "target");
3138 assert_string_equal(lysp_mod->rpcs->name, "rpc-name");
3139 assert_string_equal(lysp_mod->notifs->name, "notf");
3140 assert_string_equal(lysp_mod->deviations->nodeid, "target");
Radek Krejci39b7fc22021-02-26 23:29:18 +01003141 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(lysp_mod->exts[0]), LY_STMT_MODULE);
David Sedlák4f03b932019-07-26 13:01:47 +02003142
3143 /* min subelems */
Radek Iša56ca9e42020-09-08 18:42:00 +02003144 ly_in_free(UTEST_IN, 0);
3145 lyxml_ctx_free(YCTX->xmlctx);
3146 lysp_mod = mod_renew(YCTX);
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003147 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"mod\">\n"
3148 " <namespace uri=\"ns\"/>\n"
3149 " <prefix value=\"pref\"/>\n"
3150 " <yang-version value=\"1.1\"/>\n"
3151 "</module>";
Radek Iša56ca9e42020-09-08 18:42:00 +02003152 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3153 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
3154 assert_int_equal(yin_parse_mod(YCTX, lysp_mod), LY_SUCCESS);
David Sedlák298ff6d2019-07-26 14:29:03 +02003155 assert_string_equal(lysp_mod->mod->name, "mod");
David Sedlák298ff6d2019-07-26 14:29:03 +02003156
David Sedláke6cd89e2019-08-07 12:46:02 +02003157 /* incorrect subelem order */
Radek Iša56ca9e42020-09-08 18:42:00 +02003158 ly_in_free(UTEST_IN, 0);
3159 lyxml_ctx_free(YCTX->xmlctx);
3160 lysp_mod = mod_renew(YCTX);
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003161 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"mod\">\n"
3162 " <feature name=\"feature\"/>\n"
3163 " <namespace uri=\"ns\"/>\n"
3164 " <prefix value=\"pref\"/>\n"
3165 " <yang-version value=\"1.1\"/>\n"
3166 "</module>";
Radek Iša56ca9e42020-09-08 18:42:00 +02003167 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3168 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
3169 assert_int_equal(yin_parse_mod(YCTX, lysp_mod), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003170 CHECK_LOG_CTX("Invalid order of module\'s sub-elements \"namespace\" can\'t appear after \"feature\".", NULL, 3);
David Sedlák298ff6d2019-07-26 14:29:03 +02003171}
3172
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003173static struct lysp_submodule *
Michal Vaskod0625d72022-10-06 15:02:50 +02003174submod_renew(struct lysp_yin_ctx *ctx, const char *belongs_to)
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003175{
Michal Vasko8a67eff2021-12-07 14:04:47 +01003176 struct ly_ctx *ly_ctx = PARSER_CUR_PMOD(ctx)->mod->ctx;
3177 struct lysp_submodule *submod;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003178
Michal Vaskoc636ea42022-09-16 10:20:31 +02003179 lys_module_free(&fctx, PARSER_CUR_PMOD(ctx)->mod, 0);
Michal Vasko8a67eff2021-12-07 14:04:47 +01003180 submod = calloc(1, sizeof *submod);
3181 ctx->parsed_mods->objs[0] = submod;
3182 submod->mod = calloc(1, sizeof *submod->mod);
3183 lydict_insert(ly_ctx, belongs_to, 0, &submod->mod->name);
3184 submod->mod->parsed = (struct lysp_module *)submod;
3185 submod->mod->ctx = ly_ctx;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003186
Michal Vaskoc636ea42022-09-16 10:20:31 +02003187 fctx.mod = submod->mod;
3188
Michal Vasko8a67eff2021-12-07 14:04:47 +01003189 return submod;
Michal Vasko5d24f6c2020-10-13 13:49:06 +02003190}
3191
David Sedlák298ff6d2019-07-26 14:29:03 +02003192static void
3193test_submodule_elem(void **state)
3194{
Michal Vaskob36053d2020-03-26 15:49:30 +01003195 const char *data;
Radek Iša56ca9e42020-09-08 18:42:00 +02003196 struct lysp_submodule *lysp_submod = submod_renew(YCTX, "module-name");
David Sedlák298ff6d2019-07-26 14:29:03 +02003197
3198 /* max subelements */
David Sedlák298ff6d2019-07-26 14:29:03 +02003199 data = "<submodule xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"mod\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003200 " <yang-version value=\"1.1\"/>\n"
3201 " <belongs-to module=\"module-name\">\n"
3202 " <prefix value=\"pref\"/>\n"
3203 " </belongs-to>\n"
3204 " <include module=\"b-mod\"/>\n"
3205 " <import module=\"a-mod\"><prefix value=\"imp-pref\"/></import>\n"
3206 " <organization><text>org</text></organization>\n"
3207 " <contact><text>contact</text></contact>\n"
3208 " <description><text>desc</text></description>\n"
3209 " <reference><text>ref</text></reference>\n"
3210 " <revision date=\"2019-02-02\"/>\n"
3211 " <anydata name=\"anyd\"/>\n"
3212 " <anyxml name=\"anyx\"/>\n"
3213 " <choice name=\"choice\"/>\n"
3214 " <container name=\"cont\"/>\n"
3215 " <leaf name=\"leaf\"> <type name=\"type\"/> </leaf>\n"
3216 " <leaf-list name=\"llist\"> <type name=\"type\"/> </leaf-list>\n"
3217 " <list name=\"sub-list\"/>\n"
3218 " <uses name=\"uses-name\"/>\n"
3219 " <augment target-node=\"target\"/>\n"
3220 " <deviation target-node=\"target\">\n"
3221 " <deviate value=\"not-supported\"/>\n"
3222 " </deviation>\n"
3223 " <extension name=\"ext\"/>\n"
3224 " <feature name=\"feature\"/>\n"
3225 " <grouping name=\"grp\"/>\n"
3226 " <identity name=\"ident-name\"/>\n"
3227 " <notification name=\"notf\"/>\n"
3228 " <rpc name=\"rpc-name\"/>\n"
3229 " <typedef name=\"tpdf\"> <type name=\"type\"/> </typedef>\n"
3230 EXT_SUBELEM "\n"
3231 "</submodule>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +02003232 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3233 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
David Sedlák298ff6d2019-07-26 14:29:03 +02003234
Radek Iša56ca9e42020-09-08 18:42:00 +02003235 assert_int_equal(yin_parse_submod(YCTX, lysp_submod), LY_SUCCESS);
Michal Vasko62af3692023-02-09 14:00:09 +01003236 CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (mod) are not necessary.",
Michal Vasko7a266772024-01-23 11:02:38 +01003237 NULL, 0);
David Sedlák298ff6d2019-07-26 14:29:03 +02003238 assert_string_equal(lysp_submod->name, "mod");
Michal Vasko892355e2023-03-14 13:37:48 +01003239 assert_string_equal(lysp_submod->revs[0].date, "2019-02-02");
David Sedlák298ff6d2019-07-26 14:29:03 +02003240 assert_string_equal(lysp_submod->prefix, "pref");
3241 assert_null(lysp_submod->filepath);
3242 assert_string_equal(lysp_submod->org, "org");
3243 assert_string_equal(lysp_submod->contact, "contact");
3244 assert_string_equal(lysp_submod->dsc, "desc");
3245 assert_string_equal(lysp_submod->ref, "ref");
3246 assert_int_equal(lysp_submod->version, LYS_VERSION_1_1);
Radek Iša56ca9e42020-09-08 18:42:00 +02003247 CHECK_LYSP_IMPORT(lysp_submod->imports, NULL, 0, "a-mod",
3248 "imp-pref", NULL, "");
David Sedlák298ff6d2019-07-26 14:29:03 +02003249 assert_string_equal(lysp_submod->includes->name, "b-mod");
3250 assert_string_equal(lysp_submod->extensions->name, "ext");
3251 assert_string_equal(lysp_submod->features->name, "feature");
3252 assert_string_equal(lysp_submod->identities->name, "ident-name");
3253 assert_string_equal(lysp_submod->typedefs->name, "tpdf");
3254 assert_string_equal(lysp_submod->groupings->name, "grp");
3255 assert_string_equal(lysp_submod->data->name, "anyd");
3256 assert_int_equal(lysp_submod->data->nodetype, LYS_ANYDATA);
3257 assert_string_equal(lysp_submod->data->next->name, "anyx");
3258 assert_int_equal(lysp_submod->data->next->nodetype, LYS_ANYXML);
3259 assert_string_equal(lysp_submod->data->next->next->name, "choice");
3260 assert_int_equal(lysp_submod->data->next->next->nodetype, LYS_CHOICE);
3261 assert_string_equal(lysp_submod->data->next->next->next->name, "cont");
3262 assert_int_equal(lysp_submod->data->next->next->next->nodetype, LYS_CONTAINER);
3263 assert_string_equal(lysp_submod->data->next->next->next->next->name, "leaf");
3264 assert_int_equal(lysp_submod->data->next->next->next->next->nodetype, LYS_LEAF);
3265 assert_string_equal(lysp_submod->data->next->next->next->next->next->name, "llist");
3266 assert_int_equal(lysp_submod->data->next->next->next->next->next->nodetype, LYS_LEAFLIST);
3267 assert_string_equal(lysp_submod->data->next->next->next->next->next->next->name, "sub-list");
3268 assert_int_equal(lysp_submod->data->next->next->next->next->next->next->nodetype, LYS_LIST);
3269 assert_string_equal(lysp_submod->data->next->next->next->next->next->next->next->name, "uses-name");
3270 assert_int_equal(lysp_submod->data->next->next->next->next->next->next->next->nodetype, LYS_USES);
3271 assert_null(lysp_submod->data->next->next->next->next->next->next->next->next);
3272 assert_string_equal(lysp_submod->augments->nodeid, "target");
3273 assert_string_equal(lysp_submod->rpcs->name, "rpc-name");
3274 assert_string_equal(lysp_submod->notifs->name, "notf");
3275 assert_string_equal(lysp_submod->deviations->nodeid, "target");
Radek Krejci39b7fc22021-02-26 23:29:18 +01003276 TEST_1_CHECK_LYSP_EXT_INSTANCE(&(lysp_submod->exts[0]), LY_STMT_SUBMODULE);
David Sedlák298ff6d2019-07-26 14:29:03 +02003277
David Sedlák298ff6d2019-07-26 14:29:03 +02003278 /* min subelemnts */
Radek Iša56ca9e42020-09-08 18:42:00 +02003279 ly_in_free(UTEST_IN, 0);
3280 lyxml_ctx_free(YCTX->xmlctx);
3281 lysp_submod = submod_renew(YCTX, "module-name");
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003282 data = "<submodule xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"submod\">\n"
3283 " <yang-version value=\"1\"/>\n"
3284 " <belongs-to module=\"module-name\"><prefix value=\"pref\"/></belongs-to>\n"
3285 "</submodule>";
Radek Iša56ca9e42020-09-08 18:42:00 +02003286 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3287 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
3288 assert_int_equal(yin_parse_submod(YCTX, lysp_submod), LY_SUCCESS);
David Sedlák298ff6d2019-07-26 14:29:03 +02003289 assert_string_equal(lysp_submod->prefix, "pref");
David Sedlák298ff6d2019-07-26 14:29:03 +02003290 assert_int_equal(lysp_submod->version, LYS_VERSION_1_0);
David Sedlák298ff6d2019-07-26 14:29:03 +02003291
David Sedláke6cd89e2019-08-07 12:46:02 +02003292 /* incorrect subelem order */
Radek Iša56ca9e42020-09-08 18:42:00 +02003293 ly_in_free(UTEST_IN, 0);
3294 lyxml_ctx_free(YCTX->xmlctx);
3295 lysp_submod = submod_renew(YCTX, "module-name");
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003296 data = "<submodule xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" name=\"submod\">\n"
3297 " <yang-version value=\"1\"/>\n"
3298 " <reference><text>ref</text></reference>\n"
3299 " <belongs-to module=\"module-name\"><prefix value=\"pref\"/></belongs-to>\n"
3300 "</submodule>";
Radek Iša56ca9e42020-09-08 18:42:00 +02003301 assert_int_equal(ly_in_new_memory(data, &UTEST_IN), LY_SUCCESS);
3302 assert_int_equal(lyxml_ctx_new(UTEST_LYCTX, UTEST_IN, &YCTX->xmlctx), LY_SUCCESS);
3303 assert_int_equal(yin_parse_submod(YCTX, lysp_submod), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003304 CHECK_LOG_CTX("Invalid order of submodule's sub-elements \"belongs-to\" can't appear after \"reference\".", NULL, 4);
David Sedlák4f03b932019-07-26 13:01:47 +02003305}
3306
David Sedlák8985a142019-07-31 16:43:06 +02003307static void
3308test_yin_parse_module(void **state)
3309{
David Sedlák8985a142019-07-31 16:43:06 +02003310 const char *data;
3311 struct lys_module *mod;
Michal Vaskod0625d72022-10-06 15:02:50 +02003312 struct lysp_yin_ctx *yin_ctx = NULL;
Michal Vasko63f3d842020-07-08 10:10:14 +02003313 struct ly_in *in = NULL;
David Sedlák8985a142019-07-31 16:43:06 +02003314
3315 mod = calloc(1, sizeof *mod);
Radek Iša56ca9e42020-09-08 18:42:00 +02003316 mod->ctx = UTEST_LYCTX;
David Sedlákd2844882019-09-13 16:01:22 +02003317 data = "<module xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\" xmlns:md=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\" name=\"a\"> \n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003318 " <yang-version value=\"1.1\"/>\n"
3319 " <namespace uri=\"urn:tests:extensions:metadata:a\"/>\n"
3320 " <prefix value=\"a\"/>\n"
3321 " <import module=\"ietf-yang-metadata\">\n"
3322 " <prefix value=\"md\"/>\n"
3323 " </import>\n"
3324 " <feature name=\"f\"/>\n"
3325 " <md:annotation name=\"x\">\n"
3326 " <description>\n"
3327 " <text>test</text>\n"
3328 " </description>\n"
3329 " <reference>\n"
3330 " <text>test</text>\n"
3331 " </reference>\n"
3332 " <if-feature name=\"f\"/>\n"
3333 " <status value=\"current\"/>\n"
3334 " <type name=\"uint8\"/>\n"
3335 " <units name=\"meters\"/>\n"
3336 " </md:annotation>\n"
3337 "</module>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +02003338 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
aPiecekc3e26142021-06-22 14:25:49 +02003339 assert_int_equal(yin_parse_module(&yin_ctx, in, mod), LY_SUCCESS);
David Sedlákd2844882019-09-13 16:01:22 +02003340 assert_null(mod->parsed->exts->child->next->child);
3341 assert_string_equal(mod->parsed->exts->child->next->arg, "test");
Michal Vaskoc636ea42022-09-16 10:20:31 +02003342 lys_module_free(&fctx, mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +02003343 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003344 ly_in_free(in, 0);
David Sedlákd2844882019-09-13 16:01:22 +02003345 mod = NULL;
3346 yin_ctx = NULL;
3347
3348 mod = calloc(1, sizeof *mod);
Radek Iša56ca9e42020-09-08 18:42:00 +02003349 mod->ctx = UTEST_LYCTX;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003350 data = "<module name=\"example-foo\""
3351 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\""
3352 " xmlns:foo=\"urn:example:foo\""
3353 " xmlns:myext=\"urn:example:extensions\">\n"
David Sedlák8985a142019-07-31 16:43:06 +02003354
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003355 " <yang-version value=\"1\"/>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003356
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003357 " <namespace uri=\"urn:example:foo\"/>\n"
3358 " <prefix value=\"foo\"/>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003359
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003360 " <import module=\"example-extensions\">\n"
3361 " <prefix value=\"myext\"/>\n"
3362 " </import>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003363
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003364 " <list name=\"interface\">\n"
3365 " <key value=\"name\"/>\n"
3366 " <leaf name=\"name\">\n"
3367 " <type name=\"string\"/>\n"
3368 " </leaf>\n"
3369 " <leaf name=\"mtu\">\n"
3370 " <type name=\"uint32\"/>\n"
3371 " <description>\n"
3372 " <text>The MTU of the interface.</text>\n"
3373 " </description>\n"
3374 " <myext:c-define name=\"MY_MTU\"/>\n"
3375 " </leaf>\n"
3376 " </list>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003377 "</module>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +02003378 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
aPiecekc3e26142021-06-22 14:25:49 +02003379 assert_int_equal(yin_parse_module(&yin_ctx, in, mod), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003380 lys_module_free(&fctx, mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +02003381 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003382 ly_in_free(in, 0);
David Sedlák8985a142019-07-31 16:43:06 +02003383 mod = NULL;
3384 yin_ctx = NULL;
3385
3386 mod = calloc(1, sizeof *mod);
Radek Iša56ca9e42020-09-08 18:42:00 +02003387 mod->ctx = UTEST_LYCTX;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003388 data = "<module name=\"example-foo\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
3389 " <yang-version value=\"1\"/>\n"
3390 " <namespace uri=\"urn:example:foo\"/>\n"
3391 " <prefix value=\"foo\"/>\n"
David Sedlák6d781b62019-08-02 15:22:52 +02003392 "</module>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +02003393 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
aPiecekc3e26142021-06-22 14:25:49 +02003394 assert_int_equal(yin_parse_module(&yin_ctx, in, mod), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003395 lys_module_free(&fctx, mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +02003396 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003397 ly_in_free(in, 0);
David Sedlák6d781b62019-08-02 15:22:52 +02003398 mod = NULL;
3399 yin_ctx = NULL;
3400
David Sedlák6d781b62019-08-02 15:22:52 +02003401 mod = calloc(1, sizeof *mod);
Radek Iša56ca9e42020-09-08 18:42:00 +02003402 mod->ctx = UTEST_LYCTX;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003403 data = "<submodule name=\"example-foo\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
David Sedlák8985a142019-07-31 16:43:06 +02003404 "</submodule>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +02003405 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
aPiecekc3e26142021-06-22 14:25:49 +02003406 assert_int_equal(yin_parse_module(&yin_ctx, in, mod), LY_EINVAL);
Michal Vasko7a266772024-01-23 11:02:38 +01003407 CHECK_LOG_CTX("Input data contains submodule which cannot be parsed directly without its main module.", NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003408 lys_module_free(&fctx, mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +02003409 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003410 ly_in_free(in, 0);
David Sedlák8985a142019-07-31 16:43:06 +02003411
David Sedlák6d781b62019-08-02 15:22:52 +02003412 mod = calloc(1, sizeof *mod);
Radek Iša56ca9e42020-09-08 18:42:00 +02003413 mod->ctx = UTEST_LYCTX;
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003414 data = "<module name=\"example-foo\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
3415 " <yang-version value=\"1\"/>\n"
3416 " <namespace uri=\"urn:example:foo\"/>\n"
3417 " <prefix value=\"foo\"/>\n"
3418 "</module>\n"
David Sedlák6d781b62019-08-02 15:22:52 +02003419 "<module>";
Michal Vasko63f3d842020-07-08 10:10:14 +02003420 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
aPiecekc3e26142021-06-22 14:25:49 +02003421 assert_int_equal(yin_parse_module(&yin_ctx, in, mod), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003422 CHECK_LOG_CTX("Trailing garbage \"<module>\" after module, expected end-of-input.", NULL, 6);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003423 lys_module_free(&fctx, mod, 0);
Michal Vaskod0625d72022-10-06 15:02:50 +02003424 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003425 ly_in_free(in, 0);
David Sedlák6d781b62019-08-02 15:22:52 +02003426 mod = NULL;
3427 yin_ctx = NULL;
David Sedlák8985a142019-07-31 16:43:06 +02003428}
3429
3430static void
3431test_yin_parse_submodule(void **state)
3432{
David Sedlák8985a142019-07-31 16:43:06 +02003433 const char *data;
Michal Vaskod0625d72022-10-06 15:02:50 +02003434 struct lysp_yin_ctx *yin_ctx = NULL;
David Sedlák8985a142019-07-31 16:43:06 +02003435 struct lysp_submodule *submod = NULL;
Michal Vasko63f3d842020-07-08 10:10:14 +02003436 struct ly_in *in;
David Sedlák8985a142019-07-31 16:43:06 +02003437
Michal Vasko8a67eff2021-12-07 14:04:47 +01003438 lydict_insert(UTEST_LYCTX, "a", 0, &PARSER_CUR_PMOD(YCTX)->mod->name);
Michal Vaskoc3781c32020-10-06 14:04:08 +02003439
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003440 data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003441 "<submodule name=\"asub\""
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003442 " xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\""
3443 " xmlns:a=\"urn:a\">\n"
3444 " <yang-version value=\"1\"/>\n"
3445 " <belongs-to module=\"a\">\n"
3446 " <prefix value=\"a_pref\"/>\n"
3447 " </belongs-to>\n"
3448 " <include module=\"atop\"/>\n"
3449 " <feature name=\"fox\"/>\n"
3450 " <notification name=\"bar-notif\">\n"
3451 " <if-feature name=\"bar\"/>\n"
3452 " </notification>\n"
3453 " <notification name=\"fox-notif\">\n"
3454 " <if-feature name=\"fox\"/>\n"
3455 " </notification>\n"
3456 " <augment target-node=\"/a_pref:top\">\n"
3457 " <if-feature name=\"bar\"/>\n"
3458 " <container name=\"bar-sub\"/>\n"
3459 " </augment>\n"
3460 " <augment target-node=\"/top\">\n"
3461 " <container name=\"bar-sub2\"/>\n"
3462 " </augment>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003463 "</submodule>";
Michal Vasko63f3d842020-07-08 10:10:14 +02003464 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
Michal Vaskod0625d72022-10-06 15:02:50 +02003465 assert_int_equal(yin_parse_submodule(&yin_ctx, UTEST_LYCTX, (struct lysp_ctx *)YCTX, in, &submod), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003466 lysp_module_free(&fctx, (struct lysp_module *)submod);
Michal Vaskod0625d72022-10-06 15:02:50 +02003467 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003468 ly_in_free(in, 0);
David Sedlák8985a142019-07-31 16:43:06 +02003469 yin_ctx = NULL;
3470 submod = NULL;
3471
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003472 data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
3473 "<submodule name=\"asub\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
3474 " <yang-version value=\"1\"/>\n"
3475 " <belongs-to module=\"a\">\n"
3476 " <prefix value=\"a_pref\"/>\n"
3477 " </belongs-to>\n"
David Sedlák6d781b62019-08-02 15:22:52 +02003478 "</submodule>";
Michal Vasko63f3d842020-07-08 10:10:14 +02003479 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
Michal Vaskod0625d72022-10-06 15:02:50 +02003480 assert_int_equal(yin_parse_submodule(&yin_ctx, UTEST_LYCTX, (struct lysp_ctx *)YCTX, in, &submod), LY_SUCCESS);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003481 lysp_module_free(&fctx, (struct lysp_module *)submod);
Michal Vaskod0625d72022-10-06 15:02:50 +02003482 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003483 ly_in_free(in, 0);
David Sedlák6d781b62019-08-02 15:22:52 +02003484 yin_ctx = NULL;
3485 submod = NULL;
3486
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003487 data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
David Sedlák8985a142019-07-31 16:43:06 +02003488 "<module name=\"inval\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">"
3489 "</module>";
Michal Vasko63f3d842020-07-08 10:10:14 +02003490 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
Michal Vaskod0625d72022-10-06 15:02:50 +02003491 assert_int_equal(yin_parse_submodule(&yin_ctx, UTEST_LYCTX, (struct lysp_ctx *)YCTX, in, &submod), LY_EINVAL);
Michal Vasko7a266772024-01-23 11:02:38 +01003492 CHECK_LOG_CTX("Input data contains module when a submodule is expected.", NULL, 0);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003493 lysp_module_free(&fctx, (struct lysp_module *)submod);
Michal Vaskod0625d72022-10-06 15:02:50 +02003494 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003495 ly_in_free(in, 0);
David Sedlák8985a142019-07-31 16:43:06 +02003496 yin_ctx = NULL;
3497 submod = NULL;
3498
Radek Krejcib4ac5a92020-11-23 17:54:33 +01003499 data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
3500 "<submodule name=\"asub\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
3501 " <yang-version value=\"1\"/>\n"
3502 " <belongs-to module=\"a\">\n"
3503 " <prefix value=\"a_pref\"/>\n"
3504 " </belongs-to>\n"
3505 "</submodule>\n"
3506 "<submodule name=\"asub\" xmlns=\"urn:ietf:params:xml:ns:yang:yin:1\">\n"
3507 " <yang-version value=\"1\"/>\n"
3508 " <belongs-to module=\"a\">\n"
3509 " <prefix value=\"a_pref\"/>\n"
3510 " </belongs-to>\n"
David Sedlák6d781b62019-08-02 15:22:52 +02003511 "</submodule>";
Michal Vasko63f3d842020-07-08 10:10:14 +02003512 assert_int_equal(ly_in_new_memory(data, &in), LY_SUCCESS);
Michal Vaskod0625d72022-10-06 15:02:50 +02003513 assert_int_equal(yin_parse_submodule(&yin_ctx, UTEST_LYCTX, (struct lysp_ctx *)YCTX, in, &submod), LY_EVALID);
Michal Vasko7a266772024-01-23 11:02:38 +01003514 CHECK_LOG_CTX("Trailing garbage \"<submodule name...\" after submodule, expected end-of-input.", NULL, 8);
Michal Vaskoc636ea42022-09-16 10:20:31 +02003515 lysp_module_free(&fctx, (struct lysp_module *)submod);
Michal Vaskod0625d72022-10-06 15:02:50 +02003516 lysp_yin_ctx_free(yin_ctx);
Michal Vasko63f3d842020-07-08 10:10:14 +02003517 ly_in_free(in, 0);
David Sedlák6d781b62019-08-02 15:22:52 +02003518 yin_ctx = NULL;
3519 submod = NULL;
David Sedlák8985a142019-07-31 16:43:06 +02003520}
3521
David Sedlák3b4db242018-10-19 16:11:01 +02003522int
3523main(void)
3524{
3525
3526 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02003527 UTEST(test_yin_match_keyword, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003528 UTEST(test_yin_parse_content, setup, teardown),
3529 UTEST(test_validate_value, setup, teardown),
Michal Vasko12ef5362022-09-16 15:13:58 +02003530 UTEST(test_valid_module),
3531 UTEST(test_print_module),
3532 UTEST(test_print_submodule),
David Sedlák32488102019-07-15 17:44:10 +02003533
Radek Iša56ca9e42020-09-08 18:42:00 +02003534 UTEST(test_yin_match_argument_name),
3535 cmocka_unit_test_setup_teardown(test_enum_elem, setup, teardown),
3536 cmocka_unit_test_setup_teardown(test_bit_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003537 cmocka_unit_test_setup_teardown(test_status_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003538 cmocka_unit_test_setup_teardown(test_yin_element_elem, setup, teardown),
3539 cmocka_unit_test_setup_teardown(test_yangversion_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003540 cmocka_unit_test_setup_teardown(test_argument_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003541 cmocka_unit_test_setup_teardown(test_belongsto_elem, setup, teardown),
3542 cmocka_unit_test_setup_teardown(test_config_elem, setup, teardown),
3543 cmocka_unit_test_setup_teardown(test_default_elem, setup, teardown),
3544 cmocka_unit_test_setup_teardown(test_err_app_tag_elem, setup, teardown),
3545 cmocka_unit_test_setup_teardown(test_err_msg_elem, setup, teardown),
3546 cmocka_unit_test_setup_teardown(test_fracdigits_elem, setup, teardown),
3547 cmocka_unit_test_setup_teardown(test_iffeature_elem, setup, teardown),
3548 cmocka_unit_test_setup_teardown(test_length_elem, setup, teardown),
3549 cmocka_unit_test_setup_teardown(test_modifier_elem, setup, teardown),
3550 cmocka_unit_test_setup_teardown(test_namespace_elem, setup, teardown),
3551 cmocka_unit_test_setup_teardown(test_pattern_elem, setup, teardown),
3552 cmocka_unit_test_setup_teardown(test_value_position_elem, setup, teardown),
3553 cmocka_unit_test_setup_teardown(test_prefix_elem, setup, teardown),
3554 cmocka_unit_test_setup_teardown(test_range_elem, setup, teardown),
3555 cmocka_unit_test_setup_teardown(test_reqinstance_elem, setup, teardown),
3556 cmocka_unit_test_setup_teardown(test_revision_date_elem, setup, teardown),
3557 cmocka_unit_test_setup_teardown(test_unique_elem, setup, teardown),
3558 cmocka_unit_test_setup_teardown(test_units_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003559 cmocka_unit_test_setup_teardown(test_yin_text_value_elem, setup, teardown),
3560 cmocka_unit_test_setup_teardown(test_type_elem, setup, teardown),
3561 cmocka_unit_test_setup_teardown(test_max_elems_elem, setup, teardown),
3562 cmocka_unit_test_setup_teardown(test_min_elems_elem, setup, teardown),
3563 cmocka_unit_test_setup_teardown(test_ordby_elem, setup, teardown),
3564 cmocka_unit_test_setup_teardown(test_any_elem, setup, teardown),
3565 cmocka_unit_test_setup_teardown(test_leaf_elem, setup, teardown),
3566 cmocka_unit_test_setup_teardown(test_leaf_list_elem, setup, teardown),
3567 cmocka_unit_test_setup_teardown(test_presence_elem, setup, teardown),
3568 cmocka_unit_test_setup_teardown(test_key_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003569 cmocka_unit_test_setup_teardown(test_uses_elem, setup, teardown),
Radek Iša56ca9e42020-09-08 18:42:00 +02003570 cmocka_unit_test_setup_teardown(test_list_elem, setup, teardown),
3571 cmocka_unit_test_setup_teardown(test_notification_elem, setup, teardown),
3572 cmocka_unit_test_setup_teardown(test_grouping_elem, setup, teardown),
3573 cmocka_unit_test_setup_teardown(test_container_elem, setup, teardown),
3574 cmocka_unit_test_setup_teardown(test_case_elem, setup, teardown),
3575 cmocka_unit_test_setup_teardown(test_choice_elem, setup, teardown),
3576 cmocka_unit_test_setup_teardown(test_inout_elem, setup, teardown),
3577 cmocka_unit_test_setup_teardown(test_action_elem, setup, teardown),
3578 cmocka_unit_test_setup_teardown(test_augment_elem, setup, teardown),
3579 cmocka_unit_test_setup_teardown(test_deviate_elem, setup, teardown),
3580 cmocka_unit_test_setup_teardown(test_deviation_elem, setup, teardown),
3581 cmocka_unit_test_setup_teardown(test_module_elem, setup, teardown),
3582 cmocka_unit_test_setup_teardown(test_submodule_elem, setup, teardown),
David Sedlák8985a142019-07-31 16:43:06 +02003583
Radek Iša56ca9e42020-09-08 18:42:00 +02003584 cmocka_unit_test_setup_teardown(test_yin_parse_module, setup, teardown),
3585 cmocka_unit_test_setup_teardown(test_yin_parse_submodule, setup, teardown),
David Sedlák3b4db242018-10-19 16:11:01 +02003586 };
3587
Radek Iša56ca9e42020-09-08 18:42:00 +02003588 return cmocka_run_group_tests(tests, NULL, NULL);
David Sedlák3b4db242018-10-19 16:11:01 +02003589}