blob: cfe8cd28bf35bd4e2fd0c07c424fe6bc405ebf75 [file] [log] [blame]
Radek Krejci80dd33e2018-09-26 15:57:18 +02001/*
2 * @file test_parser_yang.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from parser_yang.c
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
Radek Krejci80dd33e2018-09-26 15:57:18 +020015#include <stdarg.h>
16#include <stddef.h>
17#include <setjmp.h>
18#include <cmocka.h>
19
20#include <stdio.h>
21#include <string.h>
22
Radek Krejci2d7a47b2019-05-16 13:34:10 +020023#include "../../src/common.h"
24#include "../../src/tree_schema.h"
25#include "../../src/tree_schema_internal.h"
26
27/* originally static functions from tree_schema_free.c and parser_yang.c */
28void lysp_ext_instance_free(struct ly_ctx *ctx, struct lysp_ext_instance *ext);
29void lysp_ident_free(struct ly_ctx *ctx, struct lysp_ident *ident);
30void lysp_feature_free(struct ly_ctx *ctx, struct lysp_feature *feat);
31void lysp_deviation_free(struct ly_ctx *ctx, struct lysp_deviation *dev);
32void lysp_grp_free(struct ly_ctx *ctx, struct lysp_grp *grp);
33void lysp_action_free(struct ly_ctx *ctx, struct lysp_action *action);
34void lysp_notif_free(struct ly_ctx *ctx, struct lysp_notif *notif);
35void lysp_augment_free(struct ly_ctx *ctx, struct lysp_augment *augment);
36void lysp_deviate_free(struct ly_ctx *ctx, struct lysp_deviate *d);
37void lysp_node_free(struct ly_ctx *ctx, struct lysp_node *node);
Radek Krejcif09e4e82019-06-14 15:08:11 +020038void lysp_when_free(struct ly_ctx *ctx, struct lysp_when *when);
Radek Krejci2d7a47b2019-05-16 13:34:10 +020039
40LY_ERR buf_add_char(struct ly_ctx *ctx, const char **input, size_t len, char **buf, size_t *buf_len, size_t *buf_used);
David Sedlák40bb13b2019-07-10 14:34:18 +020041LY_ERR buf_store_char(struct lys_parser_ctx *ctx, const char **input, enum yang_arg arg, char **word_p,
42 size_t *word_len, char **word_b, size_t *buf_len, int need_buf, int *prefix);
Radek Krejci2d7a47b2019-05-16 13:34:10 +020043LY_ERR get_keyword(struct lys_parser_ctx *ctx, const char **data, enum yang_keyword *kw, char **word_p, size_t *word_len);
44LY_ERR get_argument(struct lys_parser_ctx *ctx, const char **data, enum yang_arg arg,
45 uint16_t *flags, char **word_p, char **word_b, size_t *word_len);
46LY_ERR skip_comment(struct lys_parser_ctx *ctx, const char **data, int comment);
Radek Krejci2d7a47b2019-05-16 13:34:10 +020047
48LY_ERR parse_action(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_action **actions);
49LY_ERR parse_any(struct lys_parser_ctx *ctx, const char **data, enum yang_keyword kw, struct lysp_node *parent, struct lysp_node **siblings);
50LY_ERR parse_augment(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_augment **augments);
51LY_ERR parse_case(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
52LY_ERR parse_container(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
53LY_ERR parse_deviate(struct lys_parser_ctx *ctx, const char **data, struct lysp_deviate **deviates);
54LY_ERR parse_deviation(struct lys_parser_ctx *ctx, const char **data, struct lysp_deviation **deviations);
55LY_ERR parse_feature(struct lys_parser_ctx *ctx, const char **data, struct lysp_feature **features);
56LY_ERR parse_grouping(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_grp **groupings);
57LY_ERR parse_choice(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
58LY_ERR parse_identity(struct lys_parser_ctx *ctx, const char **data, struct lysp_ident **identities);
59LY_ERR parse_leaf(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
60LY_ERR parse_leaflist(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
61LY_ERR parse_list(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
62LY_ERR parse_maxelements(struct lys_parser_ctx *ctx, const char **data, uint32_t *max, uint16_t *flags, struct lysp_ext_instance **exts);
63LY_ERR parse_minelements(struct lys_parser_ctx *ctx, const char **data, uint32_t *min, uint16_t *flags, struct lysp_ext_instance **exts);
64LY_ERR parse_module(struct lys_parser_ctx *ctx, const char **data, struct lysp_module *mod);
65LY_ERR parse_notif(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_notif **notifs);
66LY_ERR parse_submodule(struct lys_parser_ctx *ctx, const char **data, struct lysp_submodule *submod);
67LY_ERR parse_uses(struct lys_parser_ctx *ctx, const char **data, struct lysp_node *parent, struct lysp_node **siblings);
Radek Krejcif09e4e82019-06-14 15:08:11 +020068LY_ERR parse_when(struct lys_parser_ctx *ctx, const char **data, struct lysp_when **when_p);
Radek Krejci80dd33e2018-09-26 15:57:18 +020069
70#define BUFSIZE 1024
71char logbuf[BUFSIZE] = {0};
Radek Krejci9ed7a192018-10-31 16:23:51 +010072int store = -1; /* negative for infinite logging, positive for limited logging */
Radek Krejci80dd33e2018-09-26 15:57:18 +020073
74/* set to 0 to printing error messages to stderr instead of checking them in code */
Radek Krejci70853c52018-10-15 14:46:16 +020075#define ENABLE_LOGGER_CHECKING 1
Radek Krejci80dd33e2018-09-26 15:57:18 +020076
Radek Krejcid5f2b5f2018-10-11 10:54:36 +020077#if ENABLE_LOGGER_CHECKING
Radek Krejci80dd33e2018-09-26 15:57:18 +020078static void
79logger(LY_LOG_LEVEL level, const char *msg, const char *path)
80{
81 (void) level; /* unused */
Radek Krejci9ed7a192018-10-31 16:23:51 +010082 if (store) {
83 if (path && path[0]) {
84 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
85 } else {
86 strncpy(logbuf, msg, BUFSIZE - 1);
87 }
88 if (store > 0) {
89 --store;
90 }
Radek Krejci80dd33e2018-09-26 15:57:18 +020091 }
92}
Radek Krejcid5f2b5f2018-10-11 10:54:36 +020093#endif
Radek Krejci80dd33e2018-09-26 15:57:18 +020094
95static int
96logger_setup(void **state)
97{
98 (void) state; /* unused */
99#if ENABLE_LOGGER_CHECKING
100 ly_set_log_clb(logger, 1);
101#endif
102 return 0;
103}
104
Radek Krejcib1a5dcc2018-11-26 14:50:05 +0100105static int
106logger_teardown(void **state)
107{
108 (void) state; /* unused */
109#if ENABLE_LOGGER_CHECKING
110 if (*state) {
111 fprintf(stderr, "%s\n", logbuf);
112 }
113#endif
114 return 0;
115}
116
Radek Krejci80dd33e2018-09-26 15:57:18 +0200117void
118logbuf_clean(void)
119{
120 logbuf[0] = '\0';
121}
122
123#if ENABLE_LOGGER_CHECKING
124# define logbuf_assert(str) assert_string_equal(logbuf, str)
125#else
126# define logbuf_assert(str)
127#endif
128
Radek Krejci2c02f3e2018-10-16 10:54:38 +0200129#define TEST_DUP_GENERIC(PREFIX, MEMBER, VALUE1, VALUE2, FUNC, RESULT, LINE, CLEANUP) \
130 str = PREFIX MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
131 assert_int_equal(LY_EVALID, FUNC(&ctx, &str, RESULT)); \
132 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number "LINE"."); \
133 CLEANUP
134
Radek Krejci44ceedc2018-10-02 15:54:31 +0200135static void
136test_helpers(void **state)
137{
138 (void) state; /* unused */
139
140 const char *str;
Radek Krejci404251e2018-10-09 12:06:44 +0200141 char *buf, *p;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200142 size_t len, size;
Radek Krejcie7b95092019-05-15 11:03:07 +0200143 struct lys_parser_ctx ctx;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200144 ctx.ctx = NULL;
145 ctx.line = 1;
David Sedlák40bb13b2019-07-10 14:34:18 +0200146 int prefix = 0;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200147
148 /* storing into buffer */
149 str = "abcd";
150 buf = NULL;
151 size = len = 0;
152 assert_int_equal(LY_SUCCESS, buf_add_char(NULL, &str, 2, &buf, &size, &len));
153 assert_int_not_equal(0, size);
154 assert_int_equal(2, len);
155 assert_string_equal("cd", str);
156 assert_false(strncmp("ab", buf, 2));
157 free(buf);
Radek Krejci404251e2018-10-09 12:06:44 +0200158 buf = NULL;
159
160 /* invalid first characters */
161 len = 0;
162 str = "2invalid";
David Sedlák40bb13b2019-07-10 14:34:18 +0200163 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200164 str = ".invalid";
David Sedlák40bb13b2019-07-10 14:34:18 +0200165 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200166 str = "-invalid";
David Sedlák40bb13b2019-07-10 14:34:18 +0200167 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200168 /* invalid following characters */
169 len = 3; /* number of characters read before the str content */
170 str = "!";
David Sedlák40bb13b2019-07-10 14:34:18 +0200171 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200172 str = ":";
David Sedlák40bb13b2019-07-10 14:34:18 +0200173 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200174 /* valid colon for prefixed identifiers */
175 len = size = 0;
176 p = NULL;
David Sedlák40bb13b2019-07-10 14:34:18 +0200177 prefix = 0;
Radek Krejci404251e2018-10-09 12:06:44 +0200178 str = "x:id";
David Sedlák40bb13b2019-07-10 14:34:18 +0200179 assert_int_equal(LY_SUCCESS, buf_store_char(&ctx, &str, Y_PREF_IDENTIF_ARG, &p, &len, &buf, &size, 0, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200180 assert_int_equal(1, len);
181 assert_null(buf);
182 assert_string_equal(":id", str);
183 assert_int_equal('x', p[len - 1]);
David Sedlák40bb13b2019-07-10 14:34:18 +0200184 assert_int_equal(LY_SUCCESS, buf_store_char(&ctx, &str, Y_PREF_IDENTIF_ARG, &p, &len, &buf, &size, 1, &prefix));
Radek Krejci404251e2018-10-09 12:06:44 +0200185 assert_int_equal(2, len);
186 assert_string_equal("id", str);
187 assert_int_equal(':', p[len - 1]);
188 free(buf);
David Sedlák40bb13b2019-07-10 14:34:18 +0200189 prefix = 0;
Radek Krejci44ceedc2018-10-02 15:54:31 +0200190
191 /* checking identifiers */
David Sedlák4ccd7c32019-07-10 12:02:04 +0200192 assert_int_equal(LY_EVALID, lysp_check_identifierchar(&ctx, ':', 0, NULL));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200193 logbuf_assert("Invalid identifier character ':'. Line number 1.");
David Sedlák4ccd7c32019-07-10 12:02:04 +0200194 assert_int_equal(LY_EVALID, lysp_check_identifierchar(&ctx, '#', 1, NULL));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200195 logbuf_assert("Invalid identifier first character '#'. Line number 1.");
196
David Sedlák4ccd7c32019-07-10 12:02:04 +0200197 assert_int_equal(LY_SUCCESS, lysp_check_identifierchar(&ctx, 'a', 1, &prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200198 assert_int_equal(0, prefix);
David Sedlák4ccd7c32019-07-10 12:02:04 +0200199 assert_int_equal(LY_SUCCESS, lysp_check_identifierchar(&ctx, ':', 0, &prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200200 assert_int_equal(1, prefix);
David Sedlák4ccd7c32019-07-10 12:02:04 +0200201 assert_int_equal(LY_EVALID, lysp_check_identifierchar(&ctx, ':', 0, &prefix));
Radek Krejcidcc7b322018-10-11 14:24:02 +0200202 assert_int_equal(1, prefix);
David Sedlák4ccd7c32019-07-10 12:02:04 +0200203 assert_int_equal(LY_SUCCESS, lysp_check_identifierchar(&ctx, 'b', 0, &prefix));
Radek Krejci44ceedc2018-10-02 15:54:31 +0200204 assert_int_equal(2, prefix);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200205 /* second colon is invalid */
David Sedlák4ccd7c32019-07-10 12:02:04 +0200206 assert_int_equal(LY_EVALID, lysp_check_identifierchar(&ctx, ':', 0, &prefix));
Radek Krejcidcc7b322018-10-11 14:24:02 +0200207 logbuf_assert("Invalid identifier character ':'. Line number 1.");
Radek Krejci44ceedc2018-10-02 15:54:31 +0200208}
Radek Krejci80dd33e2018-09-26 15:57:18 +0200209
210static void
211test_comments(void **state)
212{
213 (void) state; /* unused */
214
Radek Krejcie7b95092019-05-15 11:03:07 +0200215 struct lys_parser_ctx ctx;
Radek Krejci80dd33e2018-09-26 15:57:18 +0200216 const char *str, *p;
Radek Krejciefd22f62018-09-27 11:47:58 +0200217 char *word, *buf;
218 size_t len;
Radek Krejci80dd33e2018-09-26 15:57:18 +0200219
Radek Krejci44ceedc2018-10-02 15:54:31 +0200220 ctx.ctx = NULL;
221 ctx.line = 1;
222
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200223 str = " // this is a text of / one * line */ comment\nargument;";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200224 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200225 assert_string_equal("argument;", word);
Radek Krejciefd22f62018-09-27 11:47:58 +0200226 assert_null(buf);
227 assert_int_equal(8, len);
Radek Krejci80dd33e2018-09-26 15:57:18 +0200228
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200229 str = "/* this is a \n * text // of / block * comment */\"arg\" + \"ume\" \n + \n \"nt\";";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200230 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200231 assert_string_equal("argument", word);
232 assert_ptr_equal(buf, word);
233 assert_int_equal(8, len);
234 free(word);
Radek Krejci80dd33e2018-09-26 15:57:18 +0200235
236 str = p = " this is one line comment on last line";
Radek Krejci44ceedc2018-10-02 15:54:31 +0200237 assert_int_equal(LY_SUCCESS, skip_comment(&ctx, &str, 1));
Radek Krejci80dd33e2018-09-26 15:57:18 +0200238 assert_true(str[0] == '\0');
239
240 str = p = " this is a not terminated comment x";
Radek Krejci44ceedc2018-10-02 15:54:31 +0200241 assert_int_equal(LY_EVALID, skip_comment(&ctx, &str, 2));
Radek Krejci0a1d0d42019-05-16 15:14:51 +0200242 logbuf_assert("Unexpected end-of-input, non-terminated comment. Line number 5.");
Radek Krejci80dd33e2018-09-26 15:57:18 +0200243 assert_true(str[0] == '\0');
244}
245
Radek Krejciefd22f62018-09-27 11:47:58 +0200246static void
247test_arg(void **state)
248{
249 (void) state; /* unused */
250
Radek Krejcie7b95092019-05-15 11:03:07 +0200251 struct lys_parser_ctx ctx;
Radek Krejciefd22f62018-09-27 11:47:58 +0200252 const char *str;
253 char *word, *buf;
254 size_t len;
255
Radek Krejci44ceedc2018-10-02 15:54:31 +0200256 ctx.ctx = NULL;
257 ctx.line = 1;
258
Radek Krejciefd22f62018-09-27 11:47:58 +0200259 /* missing argument */
260 str = ";";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200261 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_MAYBE_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200262 assert_null(word);
263
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200264 str = "{";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200265 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200266 logbuf_assert("Invalid character sequence \"{\", expected an argument. Line number 1.");
267
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200268 /* invalid escape sequence */
269 str = "\"\\s\"";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200270 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200271 logbuf_assert("Double-quoted string unknown special character \'\\s\'. Line number 1.");
272 str = "\'\\s\'"; /* valid, since it is not an escape sequence in single quoted string */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200273 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200274 assert_int_equal(2, len);
275 assert_string_equal("\\s\'", word);
276 assert_int_equal('\0', str[0]); /* input has been eaten */
277
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200278 /* invalid character after the argument */
279 str = "hello\"";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200280 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200281 logbuf_assert("Invalid character sequence \"\"\", expected unquoted string character, optsep, semicolon or opening brace. Line number 1.");
282 str = "hello}";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200283 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200284 logbuf_assert("Invalid character sequence \"}\", expected unquoted string character, optsep, semicolon or opening brace. Line number 1.");
285
David Sedlák40bb13b2019-07-10 14:34:18 +0200286 /* invalid identifier-ref-arg-str */
287 str = "pre:pre:value";
288 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_PREF_IDENTIF_ARG, NULL, &word, &buf, &len));
289
Radek Krejci4e199f52019-05-28 09:09:28 +0200290 str = "\"\";"; /* empty identifier is not allowed */
291 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_IDENTIF_ARG, NULL, &word, &buf, &len));
292 logbuf_assert("Statement argument is required. Line number 1.");
293 logbuf_clean();
294 str = "\"\";"; /* empty reference identifier is not allowed */
295 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_PREF_IDENTIF_ARG, NULL, &word, &buf, &len));
296 logbuf_assert("Statement argument is required. Line number 1.");
297
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200298 str = "hello/x\t"; /* slash is not an invalid character */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200299 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200300 assert_int_equal(7, len);
301 assert_string_equal("hello/x\t", word);
302
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200303 assert_null(buf);
Radek Krejciefd22f62018-09-27 11:47:58 +0200304
305 /* different quoting */
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200306 str = "hello ";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200307 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200308 assert_null(buf);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200309 assert_int_equal(5, len);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200310 assert_string_equal("hello ", word);
Radek Krejciefd22f62018-09-27 11:47:58 +0200311
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200312 str = "hello/*comment*/\n";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200313 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200314 assert_null(buf);
315 assert_int_equal(5, len);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200316 assert_false(strncmp("hello", word, len));
317
318
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200319 str = "\"hello\\n\\t\\\"\\\\\";";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200320 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200321 assert_null(buf);
322 assert_int_equal(9, len);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200323 assert_string_equal("hello\\n\\t\\\"\\\\\";", word);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200324
325 ctx.indent = 14;
326 str = "\"hello \t\n\t\t world!\"";
327 /* - space and tabs before newline are stripped out
328 * - space and tabs after newline (indentation) are stripped out
329 */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200330 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200331 assert_non_null(buf);
332 assert_ptr_equal(word, buf);
333 assert_int_equal(14, len);
334 assert_string_equal("hello\n world!", word);
335 free(buf);
336
337 ctx.indent = 14;
338 str = "\"hello\n \tworld!\"";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200339 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200340 assert_non_null(buf);
341 assert_ptr_equal(word, buf);
342 assert_int_equal(12, len);
343 assert_string_equal("hello\nworld!", word);
344 free(buf);
Radek Krejciefd22f62018-09-27 11:47:58 +0200345
346 str = "\'hello\'";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200347 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200348 assert_null(buf);
349 assert_int_equal(5, len);
350 assert_false(strncmp("hello", word, 5));
351
352 str = "\"hel\" +\t\n\"lo\"";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200353 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200354 assert_ptr_equal(word, buf);
355 assert_int_equal(5, len);
356 assert_string_equal("hello", word);
357 free(buf);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200358 str = "\"hel\" +\t\nlo"; /* unquoted the second part */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200359 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200360 logbuf_assert("Both string parts divided by '+' must be quoted. Line number 5.");
Radek Krejciefd22f62018-09-27 11:47:58 +0200361
362 str = "\'he\'\t\n+ \"llo\"";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200363 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200364 assert_ptr_equal(word, buf);
365 assert_int_equal(5, len);
366 assert_string_equal("hello", word);
367 free(buf);
368
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200369 str = " \t\n\"he\"+\'llo\'";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200370 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200371 assert_ptr_equal(word, buf);
372 assert_int_equal(5, len);
373 assert_string_equal("hello", word);
374 free(buf);
375
Radek Krejci44ceedc2018-10-02 15:54:31 +0200376 /* missing argument */
377 str = ";";
Radek Krejcid3ca0632019-04-16 16:54:54 +0200378 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, NULL, &word, &buf, &len));
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200379 logbuf_assert("Invalid character sequence \";\", expected an argument. Line number 7.");
Radek Krejcidcc7b322018-10-11 14:24:02 +0200380}
381
382static void
383test_stmts(void **state)
384{
385 (void) state; /* unused */
386
Radek Krejcie7b95092019-05-15 11:03:07 +0200387 struct lys_parser_ctx ctx;
Radek Krejcidcc7b322018-10-11 14:24:02 +0200388 const char *str, *p;
389 enum yang_keyword kw;
390 char *word;
391 size_t len;
392
393 ctx.ctx = NULL;
394 ctx.line = 1;
395
396 str = "\n// comment\n\tinput\t{";
397 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
398 assert_int_equal(YANG_INPUT, kw);
399 assert_int_equal(5, len);
400 assert_string_equal("input\t{", word);
401 assert_string_equal("\t{", str);
402
403 str = "\t /* comment */\t output\n\t{";
404 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
405 assert_int_equal(YANG_OUTPUT, kw);
406 assert_int_equal(6, len);
407 assert_string_equal("output\n\t{", word);
408 assert_string_equal("\n\t{", str);
Radek Krejciabdd8062019-06-11 16:44:19 +0200409 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
410 assert_int_equal(YANG_LEFT_BRACE, kw);
411 assert_int_equal(1, len);
412 assert_string_equal("{", word);
413 assert_string_equal("", str);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200414
415 str = "/input { "; /* invalid slash */
416 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
417 logbuf_assert("Invalid identifier first character '/'. Line number 4.");
418
419 str = "not-a-statement-nor-extension { "; /* invalid identifier */
420 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
421 logbuf_assert("Invalid character sequence \"not-a-statement-nor-extension\", expected a keyword. Line number 4.");
422
423 str = "path;"; /* missing sep after the keyword */
424 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
425 logbuf_assert("Invalid character sequence \"path;\", expected a keyword followed by a separator. Line number 4.");
426
427 str = "action ";
428 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
429 assert_int_equal(YANG_ACTION, kw);
430 assert_int_equal(6, len);
431 str = "anydata ";
432 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
433 assert_int_equal(YANG_ANYDATA, kw);
434 assert_int_equal(7, len);
435 str = "anyxml ";
436 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
437 assert_int_equal(YANG_ANYXML, kw);
438 assert_int_equal(6, len);
439 str = "argument ";
440 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
441 assert_int_equal(YANG_ARGUMENT, kw);
442 assert_int_equal(8, len);
443 str = "augment ";
444 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
445 assert_int_equal(YANG_AUGMENT, kw);
446 assert_int_equal(7, len);
447 str = "base ";
448 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
449 assert_int_equal(YANG_BASE, kw);
450 assert_int_equal(4, len);
451 str = "belongs-to ";
452 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
453 assert_int_equal(YANG_BELONGS_TO, kw);
454 assert_int_equal(10, len);
455 str = "bit ";
456 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
457 assert_int_equal(YANG_BIT, kw);
458 assert_int_equal(3, len);
459 str = "case ";
460 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
461 assert_int_equal(YANG_CASE, kw);
462 assert_int_equal(4, len);
463 str = "choice ";
464 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
465 assert_int_equal(YANG_CHOICE, kw);
466 assert_int_equal(6, len);
467 str = "config ";
468 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
469 assert_int_equal(YANG_CONFIG, kw);
470 assert_int_equal(6, len);
471 str = "contact ";
472 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
473 assert_int_equal(YANG_CONTACT, kw);
474 assert_int_equal(7, len);
475 str = "container ";
476 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
477 assert_int_equal(YANG_CONTAINER, kw);
478 assert_int_equal(9, len);
479 str = "default ";
480 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
481 assert_int_equal(YANG_DEFAULT, kw);
482 assert_int_equal(7, len);
483 str = "description ";
484 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
485 assert_int_equal(YANG_DESCRIPTION, kw);
486 assert_int_equal(11, len);
487 str = "deviate ";
488 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
489 assert_int_equal(YANG_DEVIATE, kw);
490 assert_int_equal(7, len);
491 str = "deviation ";
492 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
493 assert_int_equal(YANG_DEVIATION, kw);
494 assert_int_equal(9, len);
495 str = "enum ";
496 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
497 assert_int_equal(YANG_ENUM, kw);
498 assert_int_equal(4, len);
499 str = "error-app-tag ";
500 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
501 assert_int_equal(YANG_ERROR_APP_TAG, kw);
502 assert_int_equal(13, len);
503 str = "error-message ";
504 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
505 assert_int_equal(YANG_ERROR_MESSAGE, kw);
506 assert_int_equal(13, len);
507 str = "extension ";
508 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
509 assert_int_equal(YANG_EXTENSION, kw);
510 assert_int_equal(9, len);
511 str = "feature ";
512 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
513 assert_int_equal(YANG_FEATURE, kw);
514 assert_int_equal(7, len);
515 str = "fraction-digits ";
516 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
517 assert_int_equal(YANG_FRACTION_DIGITS, kw);
518 assert_int_equal(15, len);
519 str = "grouping ";
520 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
521 assert_int_equal(YANG_GROUPING, kw);
522 assert_int_equal(8, len);
523 str = "identity ";
524 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
525 assert_int_equal(YANG_IDENTITY, kw);
526 assert_int_equal(8, len);
527 str = "if-feature ";
528 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
529 assert_int_equal(YANG_IF_FEATURE, kw);
530 assert_int_equal(10, len);
531 str = "import ";
532 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
533 assert_int_equal(YANG_IMPORT, kw);
534 assert_int_equal(6, len);
535 str = "include ";
536 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
537 assert_int_equal(YANG_INCLUDE, kw);
538 assert_int_equal(7, len);
539 str = "input{";
540 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
541 assert_int_equal(YANG_INPUT, kw);
542 assert_int_equal(5, len);
543 str = "key ";
544 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
545 assert_int_equal(YANG_KEY, kw);
546 assert_int_equal(3, len);
547 str = "leaf ";
548 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
549 assert_int_equal(YANG_LEAF, kw);
550 assert_int_equal(4, len);
551 str = "leaf-list ";
552 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
553 assert_int_equal(YANG_LEAF_LIST, kw);
554 assert_int_equal(9, len);
555 str = "length ";
556 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
557 assert_int_equal(YANG_LENGTH, kw);
558 assert_int_equal(6, len);
559 str = "list ";
560 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
561 assert_int_equal(YANG_LIST, kw);
562 assert_int_equal(4, len);
563 str = "mandatory ";
564 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
565 assert_int_equal(YANG_MANDATORY, kw);
566 assert_int_equal(9, len);
567 str = "max-elements ";
568 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
569 assert_int_equal(YANG_MAX_ELEMENTS, kw);
570 assert_int_equal(12, len);
571 str = "min-elements ";
572 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
573 assert_int_equal(YANG_MIN_ELEMENTS, kw);
574 assert_int_equal(12, len);
575 str = "modifier ";
576 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
577 assert_int_equal(YANG_MODIFIER, kw);
578 assert_int_equal(8, len);
579 str = "module ";
580 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
581 assert_int_equal(YANG_MODULE, kw);
582 assert_int_equal(6, len);
583 str = "must ";
584 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
585 assert_int_equal(YANG_MUST, kw);
586 assert_int_equal(4, len);
587 str = "namespace ";
588 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
589 assert_int_equal(YANG_NAMESPACE, kw);
590 assert_int_equal(9, len);
591 str = "notification ";
592 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
593 assert_int_equal(YANG_NOTIFICATION, kw);
594 assert_int_equal(12, len);
595 str = "ordered-by ";
596 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
597 assert_int_equal(YANG_ORDERED_BY, kw);
598 assert_int_equal(10, len);
599 str = "organization ";
600 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
601 assert_int_equal(YANG_ORGANIZATION, kw);
602 assert_int_equal(12, len);
603 str = "output ";
604 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
605 assert_int_equal(YANG_OUTPUT, kw);
606 assert_int_equal(6, len);
607 str = "path ";
608 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
609 assert_int_equal(YANG_PATH, kw);
610 assert_int_equal(4, len);
611 str = "pattern ";
612 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
613 assert_int_equal(YANG_PATTERN, kw);
614 assert_int_equal(7, len);
615 str = "position ";
616 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
617 assert_int_equal(YANG_POSITION, kw);
618 assert_int_equal(8, len);
619 str = "prefix ";
620 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
621 assert_int_equal(YANG_PREFIX, kw);
622 assert_int_equal(6, len);
623 str = "presence ";
624 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
625 assert_int_equal(YANG_PRESENCE, kw);
626 assert_int_equal(8, len);
627 str = "range ";
628 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
629 assert_int_equal(YANG_RANGE, kw);
630 assert_int_equal(5, len);
631 str = "reference ";
632 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
633 assert_int_equal(YANG_REFERENCE, kw);
634 assert_int_equal(9, len);
635 str = "refine ";
636 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
637 assert_int_equal(YANG_REFINE, kw);
638 assert_int_equal(6, len);
639 str = "require-instance ";
640 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
641 assert_int_equal(YANG_REQUIRE_INSTANCE, kw);
642 assert_int_equal(16, len);
643 str = "revision ";
644 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
645 assert_int_equal(YANG_REVISION, kw);
646 assert_int_equal(8, len);
647 str = "revision-date ";
648 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
649 assert_int_equal(YANG_REVISION_DATE, kw);
650 assert_int_equal(13, len);
651 str = "rpc ";
652 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
653 assert_int_equal(YANG_RPC, kw);
654 assert_int_equal(3, len);
655 str = "status ";
656 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
657 assert_int_equal(YANG_STATUS, kw);
658 assert_int_equal(6, len);
659 str = "submodule ";
660 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
661 assert_int_equal(YANG_SUBMODULE, kw);
662 assert_int_equal(9, len);
663 str = "type ";
664 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
665 assert_int_equal(YANG_TYPE, kw);
666 assert_int_equal(4, len);
667 str = "typedef ";
668 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
669 assert_int_equal(YANG_TYPEDEF, kw);
670 assert_int_equal(7, len);
671 str = "unique ";
672 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
673 assert_int_equal(YANG_UNIQUE, kw);
674 assert_int_equal(6, len);
675 str = "units ";
676 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
677 assert_int_equal(YANG_UNITS, kw);
678 assert_int_equal(5, len);
679 str = "uses ";
680 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
681 assert_int_equal(YANG_USES, kw);
682 assert_int_equal(4, len);
683 str = "value ";
684 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
685 assert_int_equal(YANG_VALUE, kw);
686 assert_int_equal(5, len);
687 str = "when ";
688 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
689 assert_int_equal(YANG_WHEN, kw);
690 assert_int_equal(4, len);
691 str = "yang-version ";
692 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
693 assert_int_equal(YANG_YANG_VERSION, kw);
694 assert_int_equal(12, len);
695 str = "yin-element ";
696 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
697 assert_int_equal(YANG_YIN_ELEMENT, kw);
698 assert_int_equal(11, len);
Radek Krejci626df482018-10-11 15:06:31 +0200699 str = ";config false;";
700 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
701 assert_int_equal(YANG_SEMICOLON, kw);
702 assert_int_equal(1, len);
703 assert_string_equal("config false;", str);
704 str = "{ config false;";
705 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
706 assert_int_equal(YANG_LEFT_BRACE, kw);
707 assert_int_equal(1, len);
708 assert_string_equal(" config false;", str);
709 str = "}";
710 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
711 assert_int_equal(YANG_RIGHT_BRACE, kw);
712 assert_int_equal(1, len);
713 assert_string_equal("", str);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200714
715 /* geenric extension */
716 str = p = "nacm:default-deny-write;";
717 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
718 assert_int_equal(YANG_CUSTOM, kw);
719 assert_int_equal(23, len);
720 assert_ptr_equal(p, word);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200721}
Radek Krejci44ceedc2018-10-02 15:54:31 +0200722
Radek Krejci05b13982018-11-28 16:22:07 +0100723static void
724test_minmax(void **state)
725{
726 *state = test_minmax;
727
Radek Krejcie7b95092019-05-15 11:03:07 +0200728 struct lys_parser_ctx ctx = {0};
Radek Krejci05b13982018-11-28 16:22:07 +0100729 uint16_t flags = 0;
730 uint32_t value = 0;
731 struct lysp_ext_instance *ext = NULL;
732 const char *str;
733
734 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
735 assert_non_null(ctx.ctx);
736 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100737 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci05b13982018-11-28 16:22:07 +0100738
Radek Krejcidf6cad12018-11-28 17:10:55 +0100739 str = " 1invalid; ...";
Radek Krejci05b13982018-11-28 16:22:07 +0100740 assert_int_equal(LY_EVALID, parse_minelements(&ctx, &str, &value, &flags, &ext));
Radek Krejcidf6cad12018-11-28 17:10:55 +0100741 logbuf_assert("Invalid value \"1invalid\" of \"min-elements\". Line number 1.");
Radek Krejci05b13982018-11-28 16:22:07 +0100742
743 flags = value = 0;
744 str = " -1; ...";
745 assert_int_equal(LY_EVALID, parse_minelements(&ctx, &str, &value, &flags, &ext));
746 logbuf_assert("Invalid value \"-1\" of \"min-elements\". Line number 1.");
747
Radek Krejcidf6cad12018-11-28 17:10:55 +0100748 /* implementation limit */
749 flags = value = 0;
750 str = " 4294967296; ...";
751 assert_int_equal(LY_EVALID, parse_minelements(&ctx, &str, &value, &flags, &ext));
752 logbuf_assert("Value \"4294967296\" is out of \"min-elements\" bounds. Line number 1.");
753
Radek Krejci05b13982018-11-28 16:22:07 +0100754 flags = value = 0;
755 str = " 1; ...";
756 assert_int_equal(LY_SUCCESS, parse_minelements(&ctx, &str, &value, &flags, &ext));
757 assert_int_equal(LYS_SET_MIN, flags);
758 assert_int_equal(1, value);
759
760 flags = value = 0;
761 str = " 1 {m:ext;} ...";
762 assert_int_equal(LY_SUCCESS, parse_minelements(&ctx, &str, &value, &flags, &ext));
763 assert_int_equal(LYS_SET_MIN, flags);
764 assert_int_equal(1, value);
765 assert_non_null(ext);
766 FREE_ARRAY(ctx.ctx, ext, lysp_ext_instance_free);
767 ext = NULL;
768
769 flags = value = 0;
770 str = " 1 {config true;} ...";
771 assert_int_equal(LY_EVALID, parse_minelements(&ctx, &str, &value, &flags, &ext));
772 logbuf_assert("Invalid keyword \"config\" as a child of \"min-elements\". Line number 1.");
773
Radek Krejcidf6cad12018-11-28 17:10:55 +0100774 str = " 1invalid; ...";
Radek Krejci05b13982018-11-28 16:22:07 +0100775 assert_int_equal(LY_EVALID, parse_maxelements(&ctx, &str, &value, &flags, &ext));
Radek Krejcidf6cad12018-11-28 17:10:55 +0100776 logbuf_assert("Invalid value \"1invalid\" of \"max-elements\". Line number 1.");
Radek Krejci05b13982018-11-28 16:22:07 +0100777
778 flags = value = 0;
779 str = " -1; ...";
780 assert_int_equal(LY_EVALID, parse_maxelements(&ctx, &str, &value, &flags, &ext));
781 logbuf_assert("Invalid value \"-1\" of \"max-elements\". Line number 1.");
782
Radek Krejcidf6cad12018-11-28 17:10:55 +0100783 /* implementation limit */
784 flags = value = 0;
785 str = " 4294967296; ...";
786 assert_int_equal(LY_EVALID, parse_maxelements(&ctx, &str, &value, &flags, &ext));
787 logbuf_assert("Value \"4294967296\" is out of \"max-elements\" bounds. Line number 1.");
788
Radek Krejci05b13982018-11-28 16:22:07 +0100789 flags = value = 0;
790 str = " 1; ...";
791 assert_int_equal(LY_SUCCESS, parse_maxelements(&ctx, &str, &value, &flags, &ext));
792 assert_int_equal(LYS_SET_MAX, flags);
793 assert_int_equal(1, value);
794
795 flags = value = 0;
796 str = " unbounded; ...";
797 assert_int_equal(LY_SUCCESS, parse_maxelements(&ctx, &str, &value, &flags, &ext));
798 assert_int_equal(LYS_SET_MAX, flags);
799 assert_int_equal(0, value);
800
801 flags = value = 0;
802 str = " 1 {m:ext;} ...";
803 assert_int_equal(LY_SUCCESS, parse_maxelements(&ctx, &str, &value, &flags, &ext));
804 assert_int_equal(LYS_SET_MAX, flags);
805 assert_int_equal(1, value);
806 assert_non_null(ext);
807 FREE_ARRAY(ctx.ctx, ext, lysp_ext_instance_free);
808 ext = NULL;
809
810 flags = value = 0;
811 str = " 1 {config true;} ...";
812 assert_int_equal(LY_EVALID, parse_maxelements(&ctx, &str, &value, &flags, &ext));
813 logbuf_assert("Invalid keyword \"config\" as a child of \"max-elements\". Line number 1.");
814
815 *state = NULL;
816 ly_ctx_destroy(ctx.ctx, NULL);
817}
818
Radek Krejci9fcacc12018-10-11 15:59:11 +0200819static struct lysp_module *
Radek Krejcie7b95092019-05-15 11:03:07 +0200820mod_renew(struct lys_parser_ctx *ctx)
Radek Krejci9fcacc12018-10-11 15:59:11 +0200821{
Radek Krejci40544fa2019-01-11 09:38:37 +0100822 struct lysp_module *mod_p;
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100823 static struct lys_module mod = {0};
824
825 lysc_module_free(mod.compiled, NULL);
826 lysp_module_free(mod.parsed);
827 FREE_STRING(mod.ctx, mod.name);
828 FREE_STRING(mod.ctx, mod.ns);
829 FREE_STRING(mod.ctx, mod.prefix);
830 FREE_STRING(mod.ctx, mod.filepath);
831 FREE_STRING(mod.ctx, mod.org);
832 FREE_STRING(mod.ctx, mod.contact);
833 FREE_STRING(mod.ctx, mod.dsc);
834 FREE_STRING(mod.ctx, mod.ref);
835 memset(&mod, 0, sizeof mod);
836 mod.ctx = ctx->ctx;
837
838 mod_p = calloc(1, sizeof *mod_p);
839 mod.parsed = mod_p;
840 mod_p->mod = &mod;
841 assert_non_null(mod_p);
842 return mod_p;
843}
844
845static struct lysp_submodule *
Radek Krejcie7b95092019-05-15 11:03:07 +0200846submod_renew(struct lys_parser_ctx *ctx, struct lysp_submodule *submod)
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100847{
848 lysp_submodule_free(ctx->ctx, submod);
849 submod = calloc(1, sizeof *submod);
850 assert_non_null(submod);
851 return submod;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200852}
853
Radek Krejcid33273d2018-10-25 14:55:52 +0200854static LY_ERR test_imp_clb(const char *UNUSED(mod_name), const char *UNUSED(mod_rev), const char *UNUSED(submod_name),
855 const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format,
856 const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
857{
858 *module_data = user_data;
859 *format = LYS_IN_YANG;
860 *free_module_data = NULL;
861 return LY_SUCCESS;
862}
863
Radek Krejci9fcacc12018-10-11 15:59:11 +0200864static void
865test_module(void **state)
866{
Radek Krejci40544fa2019-01-11 09:38:37 +0100867 *state = test_module;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200868
Radek Krejcie7b95092019-05-15 11:03:07 +0200869 struct lys_parser_ctx ctx;
Radek Krejci40544fa2019-01-11 09:38:37 +0100870 struct lysp_module *mod = NULL;
871 struct lysp_submodule *submod = NULL;
872 struct lys_module *m;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200873 const char *str;
874
875 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
876 assert_non_null(ctx.ctx);
877 ctx.line = 1;
Radek Krejcia042ea12018-10-13 07:52:15 +0200878 ctx.indent = 0;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200879
Radek Krejci40544fa2019-01-11 09:38:37 +0100880 mod = mod_renew(&ctx);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200881
882 /* missing mandatory substatements */
883 str = " name {}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100884 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
885 assert_string_equal("name", mod->mod->name);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200886 logbuf_assert("Missing mandatory keyword \"namespace\" as a child of \"module\". Line number 1.");
Radek Krejci40544fa2019-01-11 09:38:37 +0100887 mod = mod_renew(&ctx);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200888
889 str = " name {namespace urn:x;}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100890 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
891 assert_string_equal("urn:x", mod->mod->ns);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200892 logbuf_assert("Missing mandatory keyword \"prefix\" as a child of \"module\". Line number 1.");
Radek Krejci40544fa2019-01-11 09:38:37 +0100893 mod = mod_renew(&ctx);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200894
895 str = " name {namespace urn:x;prefix \"x\";}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100896 assert_int_equal(LY_SUCCESS, parse_module(&ctx, &str, mod));
897 assert_string_equal("x", mod->mod->prefix);
Radek Krejci40544fa2019-01-11 09:38:37 +0100898 mod = mod_renew(&ctx);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200899
Radek Krejci027d5802018-11-14 16:57:28 +0100900#define SCHEMA_BEGINNING " name {yang-version 1.1;namespace urn:x;prefix \"x\";"
901#define SCHEMA_BEGINNING2 " name {namespace urn:x;prefix \"x\";"
Radek Krejcia042ea12018-10-13 07:52:15 +0200902#define TEST_NODE(NODETYPE, INPUT, NAME) \
903 str = SCHEMA_BEGINNING INPUT; \
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100904 assert_int_equal(LY_SUCCESS, parse_module(&ctx, &str, mod)); \
Radek Krejcia042ea12018-10-13 07:52:15 +0200905 assert_non_null(mod->data); \
906 assert_int_equal(NODETYPE, mod->data->nodetype); \
907 assert_string_equal(NAME, mod->data->name); \
Radek Krejci40544fa2019-01-11 09:38:37 +0100908 mod = mod_renew(&ctx);
Radek Krejcia042ea12018-10-13 07:52:15 +0200909#define TEST_GENERIC(INPUT, TARGET, TEST) \
910 str = SCHEMA_BEGINNING INPUT; \
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100911 assert_int_equal(LY_SUCCESS, parse_module(&ctx, &str, mod)); \
Radek Krejcia042ea12018-10-13 07:52:15 +0200912 assert_non_null(TARGET); \
913 TEST; \
Radek Krejci40544fa2019-01-11 09:38:37 +0100914 mod = mod_renew(&ctx);
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100915#define TEST_DUP(MEMBER, VALUE1, VALUE2, LINE) \
Radek Krejci2c02f3e2018-10-16 10:54:38 +0200916 TEST_DUP_GENERIC(SCHEMA_BEGINNING, MEMBER, VALUE1, VALUE2, \
Radek Krejci40544fa2019-01-11 09:38:37 +0100917 parse_module, mod, LINE, mod = mod_renew(&ctx))
Radek Krejcia042ea12018-10-13 07:52:15 +0200918
919 /* duplicated namespace, prefix */
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100920 TEST_DUP("namespace", "y", "z", "1");
921 TEST_DUP("prefix", "y", "z", "1");
922 TEST_DUP("contact", "a", "b", "1");
923 TEST_DUP("description", "a", "b", "1");
924 TEST_DUP("organization", "a", "b", "1");
925 TEST_DUP("reference", "a", "b", "1");
Radek Krejcia042ea12018-10-13 07:52:15 +0200926
Radek Krejci70853c52018-10-15 14:46:16 +0200927 /* not allowed in module (submodule-specific) */
928 str = SCHEMA_BEGINNING "belongs-to master {prefix m;}}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100929 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejci70853c52018-10-15 14:46:16 +0200930 logbuf_assert("Invalid keyword \"belongs-to\" as a child of \"module\". Line number 1.");
Radek Krejci40544fa2019-01-11 09:38:37 +0100931 mod = mod_renew(&ctx);
Radek Krejci70853c52018-10-15 14:46:16 +0200932
Radek Krejcia042ea12018-10-13 07:52:15 +0200933 /* anydata */
934 TEST_NODE(LYS_ANYDATA, "anydata test;}", "test");
935 /* anyxml */
936 TEST_NODE(LYS_ANYXML, "anyxml test;}", "test");
937 /* augment */
938 TEST_GENERIC("augment /somepath;}", mod->augments,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200939 assert_string_equal("/somepath", mod->augments[0].nodeid));
Radek Krejcia042ea12018-10-13 07:52:15 +0200940 /* choice */
941 TEST_NODE(LYS_CHOICE, "choice test;}", "test");
942 /* contact 0..1 */
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100943 TEST_GENERIC("contact \"firstname\" + \n\t\" surname\";}", mod->mod->contact,
944 assert_string_equal("firstname surname", mod->mod->contact));
Radek Krejcia042ea12018-10-13 07:52:15 +0200945 /* container */
946 TEST_NODE(LYS_CONTAINER, "container test;}", "test");
947 /* description 0..1 */
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100948 TEST_GENERIC("description \'some description\';}", mod->mod->dsc,
949 assert_string_equal("some description", mod->mod->dsc));
Radek Krejcia042ea12018-10-13 07:52:15 +0200950 /* deviation */
951 TEST_GENERIC("deviation /somepath {deviate not-supported;}}", mod->deviations,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200952 assert_string_equal("/somepath", mod->deviations[0].nodeid));
Radek Krejcia042ea12018-10-13 07:52:15 +0200953 /* extension */
954 TEST_GENERIC("extension test;}", mod->extensions,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200955 assert_string_equal("test", mod->extensions[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +0200956 /* feature */
957 TEST_GENERIC("feature test;}", mod->features,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200958 assert_string_equal("test", mod->features[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +0200959 /* grouping */
960 TEST_GENERIC("grouping grp;}", mod->groupings,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200961 assert_string_equal("grp", mod->groupings[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +0200962 /* identity */
963 TEST_GENERIC("identity test;}", mod->identities,
Radek Krejci2c4e7172018-10-19 15:56:26 +0200964 assert_string_equal("test", mod->identities[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +0200965 /* import */
Radek Krejci086c7132018-10-26 15:29:04 +0200966 ly_ctx_set_module_imp_clb(ctx.ctx, test_imp_clb, "module zzz { namespace urn:zzz; prefix z;}");
967 TEST_GENERIC("import zzz {prefix z;}}", mod->imports,
968 assert_string_equal("zzz", mod->imports[0].name));
Radek Krejci70853c52018-10-15 14:46:16 +0200969
Radek Krejcia042ea12018-10-13 07:52:15 +0200970 /* import - prefix collision */
Radek Krejci086c7132018-10-26 15:29:04 +0200971 str = SCHEMA_BEGINNING "import zzz {prefix x;}}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100972 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejci70853c52018-10-15 14:46:16 +0200973 logbuf_assert("Prefix \"x\" already used as module prefix. Line number 2.");
Radek Krejci40544fa2019-01-11 09:38:37 +0100974 mod = mod_renew(&ctx);
Radek Krejci086c7132018-10-26 15:29:04 +0200975 str = SCHEMA_BEGINNING "import zzz {prefix y;}import zzz {prefix y;}}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100976 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejci086c7132018-10-26 15:29:04 +0200977 logbuf_assert("Prefix \"y\" already used to import \"zzz\" module. Line number 2.");
Radek Krejci40544fa2019-01-11 09:38:37 +0100978 mod = mod_renew(&ctx);
Radek Krejci086c7132018-10-26 15:29:04 +0200979 str = "module" SCHEMA_BEGINNING "import zzz {prefix y;}import zzz {prefix z;}}";
980 assert_null(lys_parse_mem(ctx.ctx, str, LYS_IN_YANG));
981 assert_int_equal(LY_EVALID, ly_errcode(ctx.ctx));
982 logbuf_assert("Single revision of the module \"zzz\" referred twice.");
Radek Krejci70853c52018-10-15 14:46:16 +0200983
Radek Krejcia042ea12018-10-13 07:52:15 +0200984 /* include */
Radek Krejci9ed7a192018-10-31 16:23:51 +0100985 store = 1;
Radek Krejcid33273d2018-10-25 14:55:52 +0200986 ly_ctx_set_module_imp_clb(ctx.ctx, test_imp_clb, "module xxx { namespace urn:xxx; prefix x;}");
Radek Krejci086c7132018-10-26 15:29:04 +0200987 str = "module" SCHEMA_BEGINNING "include xxx;}";
988 assert_null(lys_parse_mem(ctx.ctx, str, LYS_IN_YANG));
989 assert_int_equal(LY_EVALID, ly_errcode(ctx.ctx));
Radek Krejci0bcdaed2019-01-10 10:21:34 +0100990 logbuf_assert("Input data contains module in situation when a submodule is expected.");
Radek Krejci9ed7a192018-10-31 16:23:51 +0100991 store = -1;
Radek Krejcid33273d2018-10-25 14:55:52 +0200992
Radek Krejci9ed7a192018-10-31 16:23:51 +0100993 store = 1;
Radek Krejci313d9902018-11-08 09:42:58 +0100994 ly_ctx_set_module_imp_clb(ctx.ctx, test_imp_clb, "submodule xxx {belongs-to wrong-name {prefix w;}}");
Radek Krejci086c7132018-10-26 15:29:04 +0200995 str = "module" SCHEMA_BEGINNING "include xxx;}";
996 assert_null(lys_parse_mem(ctx.ctx, str, LYS_IN_YANG));
997 assert_int_equal(LY_EVALID, ly_errcode(ctx.ctx));
998 logbuf_assert("Included \"xxx\" submodule from \"name\" belongs-to a different module \"wrong-name\".");
Radek Krejci9ed7a192018-10-31 16:23:51 +0100999 store = -1;
Radek Krejcid33273d2018-10-25 14:55:52 +02001000
Radek Krejci313d9902018-11-08 09:42:58 +01001001 ly_ctx_set_module_imp_clb(ctx.ctx, test_imp_clb, "submodule xxx {belongs-to name {prefix x;}}");
Radek Krejcid33273d2018-10-25 14:55:52 +02001002 TEST_GENERIC("include xxx;}", mod->includes,
Radek Krejci086c7132018-10-26 15:29:04 +02001003 assert_string_equal("xxx", mod->includes[0].name));
Radek Krejcid33273d2018-10-25 14:55:52 +02001004
Radek Krejcia042ea12018-10-13 07:52:15 +02001005 /* leaf */
1006 TEST_NODE(LYS_LEAF, "leaf test {type string;}}", "test");
1007 /* leaf-list */
1008 TEST_NODE(LYS_LEAFLIST, "leaf-list test {type string;}}", "test");
1009 /* list */
1010 TEST_NODE(LYS_LIST, "list test {key a;leaf a {type string;}}}", "test");
1011 /* notification */
1012 TEST_GENERIC("notification test;}", mod->notifs,
Radek Krejci2c4e7172018-10-19 15:56:26 +02001013 assert_string_equal("test", mod->notifs[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +02001014 /* organization 0..1 */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001015 TEST_GENERIC("organization \"CESNET a.l.e.\";}", mod->mod->org,
1016 assert_string_equal("CESNET a.l.e.", mod->mod->org));
Radek Krejcia042ea12018-10-13 07:52:15 +02001017 /* reference 0..1 */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001018 TEST_GENERIC("reference RFC7950;}", mod->mod->ref,
1019 assert_string_equal("RFC7950", mod->mod->ref));
Radek Krejcia042ea12018-10-13 07:52:15 +02001020 /* revision */
1021 TEST_GENERIC("revision 2018-10-12;}", mod->revs,
Radek Krejcib7db73a2018-10-24 14:18:40 +02001022 assert_string_equal("2018-10-12", mod->revs[0].date));
Radek Krejcia042ea12018-10-13 07:52:15 +02001023 /* rpc */
1024 TEST_GENERIC("rpc test;}", mod->rpcs,
Radek Krejci2c4e7172018-10-19 15:56:26 +02001025 assert_string_equal("test", mod->rpcs[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +02001026 /* typedef */
1027 TEST_GENERIC("typedef test{type string;}}", mod->typedefs,
Radek Krejci2c4e7172018-10-19 15:56:26 +02001028 assert_string_equal("test", mod->typedefs[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +02001029 /* uses */
1030 TEST_NODE(LYS_USES, "uses test;}", "test");
1031 /* yang-version */
Radek Krejci027d5802018-11-14 16:57:28 +01001032 str = SCHEMA_BEGINNING2 "\n\tyang-version 10;}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001033 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejcia042ea12018-10-13 07:52:15 +02001034 logbuf_assert("Invalid value \"10\" of \"yang-version\". Line number 3.");
Radek Krejci40544fa2019-01-11 09:38:37 +01001035 mod = mod_renew(&ctx);
Radek Krejci027d5802018-11-14 16:57:28 +01001036 str = SCHEMA_BEGINNING2 "yang-version 1.0;yang-version 1.1;}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001037 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejcia042ea12018-10-13 07:52:15 +02001038 logbuf_assert("Duplicate keyword \"yang-version\". Line number 3.");
Radek Krejci40544fa2019-01-11 09:38:37 +01001039 mod = mod_renew(&ctx);
Radek Krejci027d5802018-11-14 16:57:28 +01001040 str = SCHEMA_BEGINNING2 "yang-version 1.0;}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001041 assert_int_equal(LY_SUCCESS, parse_module(&ctx, &str, mod));
1042 assert_int_equal(1, mod->mod->version);
Radek Krejci40544fa2019-01-11 09:38:37 +01001043 mod = mod_renew(&ctx);
Radek Krejci027d5802018-11-14 16:57:28 +01001044 str = SCHEMA_BEGINNING2 "yang-version \"1.1\";}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001045 assert_int_equal(LY_SUCCESS, parse_module(&ctx, &str, mod));
1046 assert_int_equal(2, mod->mod->version);
Radek Krejci40544fa2019-01-11 09:38:37 +01001047 mod = mod_renew(&ctx);
1048
1049 str = "module " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";
1050 m = mod->mod;
1051 free(mod);
1052 m->parsed = NULL;
1053 assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
Radek Krejci0a1d0d42019-05-16 15:14:51 +02001054 logbuf_assert("Trailing garbage \"module q {names...\" after module, expected end-of-input. Line number 3.");
Radek Krejci40544fa2019-01-11 09:38:37 +01001055 mod = mod_renew(&ctx);
1056
1057 str = "prefix " SCHEMA_BEGINNING "}";
1058 m = mod->mod;
1059 free(mod);
1060 m->parsed = NULL;
1061 assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
1062 logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 3.");
1063 mod = mod_renew(&ctx);
Radek Krejci09306362018-10-15 15:26:01 +02001064
David Sedlák9fb515f2019-07-11 10:33:58 +02001065 str = "module " SCHEMA_BEGINNING "}";
1066 str = "module " SCHEMA_BEGINNING "leaf enum {type enumeration {enum seven { position 7;}}}}";
1067 m = mod->mod;
1068 free(mod);
1069 m->parsed = NULL;
1070 assert_int_equal(LY_EVALID, yang_parse_module(&ctx, str, m));
1071 logbuf_assert("Invalid keyword \"position\" as a child of \"enum\". Line number 3.");
1072 mod = mod_renew(&ctx);
1073
Radek Krejci156ccaf2018-10-15 15:49:17 +02001074 /* extensions */
1075 TEST_GENERIC("prefix:test;}", mod->exts,
Radek Krejci2c4e7172018-10-19 15:56:26 +02001076 assert_string_equal("prefix:test", mod->exts[0].name);
1077 assert_int_equal(LYEXT_SUBSTMT_SELF, mod->exts[0].insubstmt));
Radek Krejci40544fa2019-01-11 09:38:37 +01001078 mod = mod_renew(&ctx);
Radek Krejci156ccaf2018-10-15 15:49:17 +02001079
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001080 /* invalid substatement */
1081 str = SCHEMA_BEGINNING "must false;}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001082 assert_int_equal(LY_EVALID, parse_module(&ctx, &str, mod));
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001083 logbuf_assert("Invalid keyword \"must\" as a child of \"module\". Line number 3.");
Radek Krejci40544fa2019-01-11 09:38:37 +01001084 mod = mod_renew(&ctx);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001085
Radek Krejci09306362018-10-15 15:26:01 +02001086 /* submodule */
Radek Krejci40544fa2019-01-11 09:38:37 +01001087 submod = submod_renew(&ctx, submod);
Radek Krejci09306362018-10-15 15:26:01 +02001088
1089 /* missing mandatory substatements */
1090 str = " subname {}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001091 lydict_remove(ctx.ctx, submod->name);
1092 assert_int_equal(LY_EVALID, parse_submodule(&ctx, &str, submod));
1093 assert_string_equal("subname", submod->name);
Radek Krejci09306362018-10-15 15:26:01 +02001094 logbuf_assert("Missing mandatory keyword \"belongs-to\" as a child of \"submodule\". Line number 3.");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001095 submod = submod_renew(&ctx, submod);
Radek Krejci09306362018-10-15 15:26:01 +02001096
Radek Krejci313d9902018-11-08 09:42:58 +01001097 str = " subname {belongs-to name {prefix x;}}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001098 lydict_remove(ctx.ctx, submod->name);
1099 assert_int_equal(LY_SUCCESS, parse_submodule(&ctx, &str, submod));
1100 assert_string_equal("name", submod->belongsto);
1101 submod = submod_renew(&ctx, submod);
Radek Krejci09306362018-10-15 15:26:01 +02001102
1103#undef SCHEMA_BEGINNING
Radek Krejci313d9902018-11-08 09:42:58 +01001104#define SCHEMA_BEGINNING " subname {belongs-to name {prefix x;}"
Radek Krejci09306362018-10-15 15:26:01 +02001105
1106 /* duplicated namespace, prefix */
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001107 str = " subname {belongs-to name {prefix x;}belongs-to module1;belongs-to module2;} ...";
1108 assert_int_equal(LY_EVALID, parse_submodule(&ctx, &str, submod)); \
1109 logbuf_assert("Duplicate keyword \"belongs-to\". Line number 3."); \
1110 submod = submod_renew(&ctx, submod);
Radek Krejci09306362018-10-15 15:26:01 +02001111
1112 /* not allowed in submodule (module-specific) */
1113 str = SCHEMA_BEGINNING "namespace \"urn:z\";}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001114 assert_int_equal(LY_EVALID, parse_submodule(&ctx, &str, submod));
Radek Krejci09306362018-10-15 15:26:01 +02001115 logbuf_assert("Invalid keyword \"namespace\" as a child of \"submodule\". Line number 3.");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001116 submod = submod_renew(&ctx, submod);
Radek Krejci09306362018-10-15 15:26:01 +02001117 str = SCHEMA_BEGINNING "prefix m;}}";
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001118 assert_int_equal(LY_EVALID, parse_submodule(&ctx, &str, submod));
Radek Krejci09306362018-10-15 15:26:01 +02001119 logbuf_assert("Invalid keyword \"prefix\" as a child of \"submodule\". Line number 3.");
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001120 submod = submod_renew(&ctx, submod);
Radek Krejcia042ea12018-10-13 07:52:15 +02001121
Radek Krejci40544fa2019-01-11 09:38:37 +01001122 str = "submodule " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";
1123 lysp_submodule_free(ctx.ctx, submod);
1124 submod = NULL;
1125 assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
Radek Krejci0a1d0d42019-05-16 15:14:51 +02001126 logbuf_assert("Trailing garbage \"module q {names...\" after submodule, expected end-of-input. Line number 3.");
Radek Krejci40544fa2019-01-11 09:38:37 +01001127
1128 str = "prefix " SCHEMA_BEGINNING "}";
1129 assert_int_equal(LY_EVALID, yang_parse_submodule(&ctx, str, &submod));
1130 logbuf_assert("Invalid keyword \"prefix\", expected \"module\" or \"submodule\". Line number 3.");
1131 submod = submod_renew(&ctx, submod);
1132
Radek Krejcia042ea12018-10-13 07:52:15 +02001133#undef TEST_GENERIC
1134#undef TEST_NODE
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001135#undef TEST_DUP
Radek Krejcia042ea12018-10-13 07:52:15 +02001136#undef SCHEMA_BEGINNING
1137
Radek Krejci9fcacc12018-10-11 15:59:11 +02001138 lysp_module_free(mod);
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001139 lysp_submodule_free(ctx.ctx, submod);
Radek Krejci9fcacc12018-10-11 15:59:11 +02001140 ly_ctx_destroy(ctx.ctx, NULL);
Radek Krejci40544fa2019-01-11 09:38:37 +01001141
1142 *state = NULL;
Radek Krejciefd22f62018-09-27 11:47:58 +02001143}
1144
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001145static void
1146test_identity(void **state)
1147{
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001148 *state = test_identity;
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001149
Radek Krejcie7b95092019-05-15 11:03:07 +02001150 struct lys_parser_ctx ctx;
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001151 struct lysp_ident *ident = NULL;
1152 const char *str;
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001153
1154 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1155 assert_non_null(ctx.ctx);
1156 ctx.line = 1;
1157 ctx.indent = 0;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001158 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001159
1160 /* invalid cardinality */
1161#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001162 TEST_DUP_GENERIC(" test {", MEMBER, VALUE1, VALUE2, parse_identity, \
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001163 &ident, "1", FREE_ARRAY(ctx.ctx, ident, lysp_ident_free); ident = NULL)
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001164
Radek Krejci38222632019-02-12 16:55:05 +01001165 TEST_DUP("description", "a", "b");
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001166 TEST_DUP("reference", "a", "b");
1167 TEST_DUP("status", "current", "obsolete");
1168
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001169 /* full content */
David Sedlák40bb13b2019-07-10 14:34:18 +02001170 str = " test {base \"a\";base b; description text;reference \'another text\';status current; if-feature x;if-feature y;prefix:ext;} ...";
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001171 assert_int_equal(LY_SUCCESS, parse_identity(&ctx, &str, &ident));
1172 assert_non_null(ident);
1173 assert_string_equal(" ...", str);
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001174 FREE_ARRAY(ctx.ctx, ident, lysp_ident_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001175 ident = NULL;
1176
1177 /* invalid substatement */
1178 str = " test {organization XXX;}";
1179 assert_int_equal(LY_EVALID, parse_identity(&ctx, &str, &ident));
1180 logbuf_assert("Invalid keyword \"organization\" as a child of \"identity\". Line number 1.");
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001181 FREE_ARRAY(ctx.ctx, ident, lysp_ident_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001182 ident = NULL;
1183
1184#undef TEST_DUP
1185
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001186 *state = NULL;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001187 ly_ctx_destroy(ctx.ctx, NULL);
1188}
1189
1190static void
1191test_feature(void **state)
1192{
1193 (void) state; /* unused */
1194
Radek Krejcie7b95092019-05-15 11:03:07 +02001195 struct lys_parser_ctx ctx;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001196 struct lysp_feature *features = NULL;
1197 const char *str;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001198
1199 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1200 assert_non_null(ctx.ctx);
1201 ctx.line = 1;
1202 ctx.indent = 0;
1203
1204 /* invalid cardinality */
1205#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1206 TEST_DUP_GENERIC(" test {", MEMBER, VALUE1, VALUE2, parse_feature, \
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001207 &features, "1", FREE_ARRAY(ctx.ctx, features, lysp_feature_free); features = NULL)
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001208
1209 TEST_DUP("description", "a", "b");
1210 TEST_DUP("reference", "a", "b");
1211 TEST_DUP("status", "current", "obsolete");
1212
1213 /* full content */
1214 str = " test {description text;reference \'another text\';status current; if-feature x;if-feature y;prefix:ext;} ...";
1215 assert_int_equal(LY_SUCCESS, parse_feature(&ctx, &str, &features));
1216 assert_non_null(features);
1217 assert_string_equal(" ...", str);
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001218 FREE_ARRAY(ctx.ctx, features, lysp_feature_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001219 features = NULL;
1220
1221 /* invalid substatement */
1222 str = " test {organization XXX;}";
1223 assert_int_equal(LY_EVALID, parse_feature(&ctx, &str, &features));
1224 logbuf_assert("Invalid keyword \"organization\" as a child of \"feature\". Line number 1.");
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001225 FREE_ARRAY(ctx.ctx, features, lysp_feature_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001226 features = NULL;
1227
1228#undef TEST_DUP
1229
1230 ly_ctx_destroy(ctx.ctx, NULL);
1231}
1232
1233static void
1234test_deviation(void **state)
1235{
1236 (void) state; /* unused */
1237
Radek Krejcie7b95092019-05-15 11:03:07 +02001238 struct lys_parser_ctx ctx;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001239 struct lysp_deviation *d = NULL;
1240 const char *str;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001241
1242 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1243 assert_non_null(ctx.ctx);
1244 ctx.line = 1;
1245 ctx.indent = 0;
1246
1247 /* invalid cardinality */
1248#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1249 TEST_DUP_GENERIC(" test {deviate not-supported;", MEMBER, VALUE1, VALUE2, parse_deviation, \
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001250 &d, "1", FREE_ARRAY(ctx.ctx, d, lysp_deviation_free); d = NULL)
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001251
1252 TEST_DUP("description", "a", "b");
1253 TEST_DUP("reference", "a", "b");
1254
1255 /* full content */
1256 str = " test {deviate not-supported;description text;reference \'another text\';prefix:ext;} ...";
1257 assert_int_equal(LY_SUCCESS, parse_deviation(&ctx, &str, &d));
1258 assert_non_null(d);
1259 assert_string_equal(" ...", str);
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001260 FREE_ARRAY(ctx.ctx, d, lysp_deviation_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001261 d = NULL;
1262
1263 /* missing mandatory substatement */
1264 str = " test {description text;}";
1265 assert_int_equal(LY_EVALID, parse_deviation(&ctx, &str, &d));
1266 logbuf_assert("Missing mandatory keyword \"deviate\" as a child of \"deviation\". Line number 1.");
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001267 FREE_ARRAY(ctx.ctx, d, lysp_deviation_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001268 d = NULL;
1269
1270 /* invalid substatement */
1271 str = " test {deviate not-supported; status obsolete;}";
1272 assert_int_equal(LY_EVALID, parse_deviation(&ctx, &str, &d));
1273 logbuf_assert("Invalid keyword \"status\" as a child of \"deviation\". Line number 1.");
Radek Krejcie53a8dc2018-10-17 12:52:40 +02001274 FREE_ARRAY(ctx.ctx, d, lysp_deviation_free);
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001275 d = NULL;
1276
1277#undef TEST_DUP
1278
1279 ly_ctx_destroy(ctx.ctx, NULL);
1280}
1281
1282static void
1283test_deviate(void **state)
1284{
1285 (void) state; /* unused */
1286
Radek Krejcie7b95092019-05-15 11:03:07 +02001287 struct lys_parser_ctx ctx;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001288 struct lysp_deviate *d = NULL;
1289 const char *str;
1290
1291 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1292 assert_non_null(ctx.ctx);
1293 ctx.line = 1;
1294 ctx.indent = 0;
1295
1296 /* invalid cardinality */
1297#define TEST_DUP(TYPE, MEMBER, VALUE1, VALUE2) \
1298 TEST_DUP_GENERIC(TYPE" {", MEMBER, VALUE1, VALUE2, parse_deviate, \
Radek Krejci4f28eda2018-11-12 11:46:16 +01001299 &d, "1", lysp_deviate_free(ctx.ctx, d); free(d); d = NULL)
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001300
1301 TEST_DUP("add", "config", "true", "false");
1302 TEST_DUP("replace", "default", "int8", "uint8");
1303 TEST_DUP("add", "mandatory", "true", "false");
1304 TEST_DUP("add", "max-elements", "1", "2");
1305 TEST_DUP("add", "min-elements", "1", "2");
1306 TEST_DUP("replace", "type", "int8", "uint8");
1307 TEST_DUP("add", "units", "kilometers", "miles");
1308
1309 /* full contents */
1310 str = " not-supported {prefix:ext;} ...";
1311 assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
1312 assert_non_null(d);
1313 assert_string_equal(" ...", str);
Radek Krejci4f28eda2018-11-12 11:46:16 +01001314 lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001315 str = " add {units meters; must 1; must 2; unique x; unique y; default a; default b; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
1316 assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
1317 assert_non_null(d);
1318 assert_string_equal(" ...", str);
Radek Krejci4f28eda2018-11-12 11:46:16 +01001319 lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001320 str = " delete {units meters; must 1; must 2; unique x; unique y; default a; default b; prefix:ext;} ...";
1321 assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
1322 assert_non_null(d);
1323 assert_string_equal(" ...", str);
Radek Krejci4f28eda2018-11-12 11:46:16 +01001324 lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001325 str = " replace {type string; units meters; default a; config true; mandatory true; min-elements 1; max-elements 2; prefix:ext;} ...";
1326 assert_int_equal(LY_SUCCESS, parse_deviate(&ctx, &str, &d));
1327 assert_non_null(d);
1328 assert_string_equal(" ...", str);
Radek Krejci4f28eda2018-11-12 11:46:16 +01001329 lysp_deviate_free(ctx.ctx, d); free(d); d = NULL;
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001330
1331 /* invalid substatements */
1332#define TEST_NOT_SUP(DEV, STMT, VALUE) \
1333 str = " "DEV" {"STMT" "VALUE";}..."; \
1334 assert_int_equal(LY_EVALID, parse_deviate(&ctx, &str, &d)); \
1335 logbuf_assert("Deviate \""DEV"\" does not support keyword \""STMT"\". Line number 1."); \
Radek Krejci4f28eda2018-11-12 11:46:16 +01001336 lysp_deviate_free(ctx.ctx, d); free(d); d = NULL
Radek Krejci2c02f3e2018-10-16 10:54:38 +02001337
1338 TEST_NOT_SUP("not-supported", "units", "meters");
1339 TEST_NOT_SUP("not-supported", "must", "1");
1340 TEST_NOT_SUP("not-supported", "unique", "x");
1341 TEST_NOT_SUP("not-supported", "default", "a");
1342 TEST_NOT_SUP("not-supported", "config", "true");
1343 TEST_NOT_SUP("not-supported", "mandatory", "true");
1344 TEST_NOT_SUP("not-supported", "min-elements", "1");
1345 TEST_NOT_SUP("not-supported", "max-elements", "2");
1346 TEST_NOT_SUP("not-supported", "type", "string");
1347 TEST_NOT_SUP("add", "type", "string");
1348 TEST_NOT_SUP("delete", "config", "true");
1349 TEST_NOT_SUP("delete", "mandatory", "true");
1350 TEST_NOT_SUP("delete", "min-elements", "1");
1351 TEST_NOT_SUP("delete", "max-elements", "2");
1352 TEST_NOT_SUP("delete", "type", "string");
1353 TEST_NOT_SUP("replace", "must", "1");
1354 TEST_NOT_SUP("replace", "unique", "a");
1355
1356 str = " nonsence; ...";
1357 assert_int_equal(LY_EVALID, parse_deviate(&ctx, &str, &d));
1358 logbuf_assert("Invalid value \"nonsence\" of \"deviate\". Line number 1.");
1359 assert_null(d);
1360
1361#undef TEST_NOT_SUP
1362#undef TEST_DUP
Radek Krejci4c6d9bd2018-10-15 16:43:06 +02001363
1364 ly_ctx_destroy(ctx.ctx, NULL);
1365}
1366
Radek Krejci8c370832018-11-02 15:10:03 +01001367static void
1368test_container(void **state)
1369{
1370 (void) state; /* unused */
1371
Radek Krejcie7b95092019-05-15 11:03:07 +02001372 struct lys_parser_ctx ctx = {0};
Radek Krejci8c370832018-11-02 15:10:03 +01001373 struct lysp_node_container *c = NULL;
1374 const char *str;
1375
1376 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1377 assert_non_null(ctx.ctx);
1378 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001379 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci8c370832018-11-02 15:10:03 +01001380
1381 /* invalid cardinality */
1382#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1383 str = "cont {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1384 assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c)); \
1385 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
Radek Krejci4f28eda2018-11-12 11:46:16 +01001386 lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
Radek Krejci8c370832018-11-02 15:10:03 +01001387
1388 TEST_DUP("config", "true", "false");
1389 TEST_DUP("description", "text1", "text2");
1390 TEST_DUP("presence", "true", "false");
1391 TEST_DUP("reference", "1", "2");
1392 TEST_DUP("status", "current", "obsolete");
1393 TEST_DUP("when", "true", "false");
1394#undef TEST_DUP
1395
1396 /* full content */
Radek Krejci313d9902018-11-08 09:42:58 +01001397 str = "cont {action x;anydata any;anyxml anyxml; choice ch;config false;container c;description test;grouping g;if-feature f; leaf l {type string;}"
1398 "leaf-list ll {type string;} list li;must 'expr';notification not; presence true; reference test;status current;typedef t {type int8;}uses g;when true;m:ext;} ...";
Radek Krejci8c370832018-11-02 15:10:03 +01001399 assert_int_equal(LY_SUCCESS, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
1400 assert_non_null(c);
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001401 assert_int_equal(LYS_CONTAINER, c->nodetype);
1402 assert_string_equal("cont", c->name);
Radek Krejci8c370832018-11-02 15:10:03 +01001403 assert_non_null(c->actions);
1404 assert_non_null(c->child);
1405 assert_string_equal("test", c->dsc);
1406 assert_non_null(c->exts);
1407 assert_non_null(c->groupings);
1408 assert_non_null(c->iffeatures);
1409 assert_non_null(c->musts);
1410 assert_non_null(c->notifs);
1411 assert_string_equal("true", c->presence);
1412 assert_string_equal("test", c->ref);
1413 assert_non_null(c->typedefs);
1414 assert_non_null(c->when);
1415 assert_null(c->parent);
1416 assert_null(c->next);
1417 assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR, c->flags);
Radek Krejci313d9902018-11-08 09:42:58 +01001418 ly_set_erase(&ctx.tpdfs_nodes, NULL);
Radek Krejci4f28eda2018-11-12 11:46:16 +01001419 lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
Radek Krejci8c370832018-11-02 15:10:03 +01001420
1421 /* invalid */
1422 str = " cont {augment /root;} ...";
1423 assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
1424 logbuf_assert("Invalid keyword \"augment\" as a child of \"container\". Line number 1.");
Radek Krejci4f28eda2018-11-12 11:46:16 +01001425 lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
Radek Krejci8c370832018-11-02 15:10:03 +01001426 str = " cont {nonsence true;} ...";
1427 assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
1428 logbuf_assert("Invalid character sequence \"nonsence\", expected a keyword. Line number 1.");
Radek Krejci4f28eda2018-11-12 11:46:16 +01001429 lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
Radek Krejci8c370832018-11-02 15:10:03 +01001430
Radek Krejcif538ce52019-03-05 10:46:14 +01001431 ctx.mod_version = 1; /* simulate YANG 1.0 */
1432 str = " cont {action x;} ...";
1433 assert_int_equal(LY_EVALID, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
1434 logbuf_assert("Invalid keyword \"action\" as a child of \"container\" - the statement is allowed only in YANG 1.1 modules. Line number 1.");
1435 lysp_node_free(ctx.ctx, (struct lysp_node*)c); c = NULL;
1436
Radek Krejci8c370832018-11-02 15:10:03 +01001437 ly_ctx_destroy(ctx.ctx, NULL);
1438}
1439
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001440static void
1441test_leaf(void **state)
1442{
1443 *state = test_leaf;
1444
Radek Krejcie7b95092019-05-15 11:03:07 +02001445 struct lys_parser_ctx ctx = {0};
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001446 struct lysp_node_leaf *l = NULL;
1447 const char *str;
1448
1449 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1450 assert_non_null(ctx.ctx);
1451 ctx.line = 1;
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001452 //ctx.mod->version = 2; /* simulate YANG 1.1 */
1453
1454 /* invalid cardinality */
1455#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1456 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1457 assert_int_equal(LY_EVALID, parse_leaf(&ctx, &str, NULL, (struct lysp_node**)&l)); \
1458 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1459 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1460
1461 TEST_DUP("config", "true", "false");
1462 TEST_DUP("default", "x", "y");
1463 TEST_DUP("description", "text1", "text2");
1464 TEST_DUP("mandatory", "true", "false");
1465 TEST_DUP("reference", "1", "2");
1466 TEST_DUP("status", "current", "obsolete");
Radek Krejci0e5d8382018-11-28 16:37:53 +01001467 TEST_DUP("type", "int8", "uint8");
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001468 TEST_DUP("units", "text1", "text2");
1469 TEST_DUP("when", "true", "false");
1470#undef TEST_DUP
1471
1472 /* full content - without mandatory which is mutual exclusive with default */
1473 str = "l {config false;default \"xxx\";description test;if-feature f;"
1474 "must 'expr';reference test;status current;type string; units yyy;when true;m:ext;} ...";
1475 assert_int_equal(LY_SUCCESS, parse_leaf(&ctx, &str, NULL, (struct lysp_node**)&l));
1476 assert_non_null(l);
1477 assert_int_equal(LYS_LEAF, l->nodetype);
1478 assert_string_equal("l", l->name);
1479 assert_string_equal("test", l->dsc);
1480 assert_string_equal("xxx", l->dflt);
1481 assert_string_equal("yyy", l->units);
1482 assert_string_equal("string", l->type.name);
1483 assert_non_null(l->exts);
1484 assert_non_null(l->iffeatures);
1485 assert_non_null(l->musts);
1486 assert_string_equal("test", l->ref);
1487 assert_non_null(l->when);
1488 assert_null(l->parent);
1489 assert_null(l->next);
1490 assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR, l->flags);
1491 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1492
1493 /* full content - now with mandatory */
1494 str = "l {mandatory true; type string;} ...";
1495 assert_int_equal(LY_SUCCESS, parse_leaf(&ctx, &str, NULL, (struct lysp_node**)&l));
1496 assert_non_null(l);
1497 assert_int_equal(LYS_LEAF, l->nodetype);
1498 assert_string_equal("l", l->name);
1499 assert_string_equal("string", l->type.name);
1500 assert_int_equal(LYS_MAND_TRUE, l->flags);
1501 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1502
1503 /* invalid */
1504 str = " l {mandatory true; default xx; type string;} ...";
1505 assert_int_equal(LY_EVALID, parse_leaf(&ctx, &str, NULL, (struct lysp_node**)&l));
Radek Krejcia9026eb2018-12-12 16:04:47 +01001506 logbuf_assert("Invalid combination of keywords \"mandatory\" and \"default\" as substatements of \"leaf\". Line number 1.");
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01001507 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1508
1509 str = " l {description \"missing type\";} ...";
1510 assert_int_equal(LY_EVALID, parse_leaf(&ctx, &str, NULL, (struct lysp_node**)&l));
1511 logbuf_assert("Missing mandatory keyword \"type\" as a child of \"leaf\". Line number 1.");
1512 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1513
1514 *state = NULL;
1515 ly_ctx_destroy(ctx.ctx, NULL);
1516}
1517
Radek Krejci0e5d8382018-11-28 16:37:53 +01001518static void
1519test_leaflist(void **state)
1520{
1521 *state = test_leaf;
1522
Radek Krejcie7b95092019-05-15 11:03:07 +02001523 struct lys_parser_ctx ctx = {0};
Radek Krejci0e5d8382018-11-28 16:37:53 +01001524 struct lysp_node_leaflist *ll = NULL;
1525 const char *str;
1526
1527 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1528 assert_non_null(ctx.ctx);
1529 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001530 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci0e5d8382018-11-28 16:37:53 +01001531
1532 /* invalid cardinality */
1533#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1534 str = "ll {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1535 assert_int_equal(LY_EVALID, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll)); \
1536 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1537 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1538
1539 TEST_DUP("config", "true", "false");
1540 TEST_DUP("description", "text1", "text2");
1541 TEST_DUP("max-elements", "10", "20");
1542 TEST_DUP("min-elements", "10", "20");
1543 TEST_DUP("ordered-by", "user", "system");
1544 TEST_DUP("reference", "1", "2");
1545 TEST_DUP("status", "current", "obsolete");
1546 TEST_DUP("type", "int8", "uint8");
1547 TEST_DUP("units", "text1", "text2");
1548 TEST_DUP("when", "true", "false");
1549#undef TEST_DUP
1550
1551 /* full content - without min-elements which is mutual exclusive with default */
1552 str = "ll {config false;default \"xxx\"; default \"yyy\";description test;if-feature f;"
1553 "max-elements 10;must 'expr';ordered-by user;reference test;"
1554 "status current;type string; units zzz;when true;m:ext;} ...";
1555 assert_int_equal(LY_SUCCESS, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
1556 assert_non_null(ll);
1557 assert_int_equal(LYS_LEAFLIST, ll->nodetype);
1558 assert_string_equal("ll", ll->name);
1559 assert_string_equal("test", ll->dsc);
1560 assert_non_null(ll->dflts);
1561 assert_int_equal(2, LY_ARRAY_SIZE(ll->dflts));
1562 assert_string_equal("xxx", ll->dflts[0]);
1563 assert_string_equal("yyy", ll->dflts[1]);
1564 assert_string_equal("zzz", ll->units);
1565 assert_int_equal(10, ll->max);
1566 assert_int_equal(0, ll->min);
1567 assert_string_equal("string", ll->type.name);
1568 assert_non_null(ll->exts);
1569 assert_non_null(ll->iffeatures);
1570 assert_non_null(ll->musts);
1571 assert_string_equal("test", ll->ref);
1572 assert_non_null(ll->when);
1573 assert_null(ll->parent);
1574 assert_null(ll->next);
1575 assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_USER | LYS_SET_MAX, ll->flags);
1576 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1577
1578 /* full content - now with min-elements */
1579 str = "ll {min-elements 10; type string;} ...";
1580 assert_int_equal(LY_SUCCESS, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
1581 assert_non_null(ll);
1582 assert_int_equal(LYS_LEAFLIST, ll->nodetype);
1583 assert_string_equal("ll", ll->name);
1584 assert_string_equal("string", ll->type.name);
1585 assert_int_equal(0, ll->max);
1586 assert_int_equal(10, ll->min);
1587 assert_int_equal(LYS_SET_MIN, ll->flags);
1588 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1589
1590 /* invalid */
1591 str = " ll {min-elements 1; default xx; type string;} ...";
1592 assert_int_equal(LY_EVALID, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
Radek Krejcia9026eb2018-12-12 16:04:47 +01001593 logbuf_assert("Invalid combination of keywords \"min-elements\" and \"default\" as substatements of \"leaf-list\". Line number 1.");
Radek Krejci0e5d8382018-11-28 16:37:53 +01001594 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1595
1596 str = " ll {description \"missing type\";} ...";
1597 assert_int_equal(LY_EVALID, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
1598 logbuf_assert("Missing mandatory keyword \"type\" as a child of \"leaf-list\". Line number 1.");
1599 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1600
Radek Krejcidf6cad12018-11-28 17:10:55 +01001601 str = " ll {type string; min-elements 10; max-elements 1;} ..."; /* invalid combination of min/max */
1602 assert_int_equal(LY_EVALID, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
1603 logbuf_assert("Invalid combination of min-elements and max-elements: min value 10 is bigger than the max value 1. Line number 1.");
1604 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1605
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001606 ctx.mod_version = 1; /* simulate YANG 1.0 - default statement is not allowed */
Radek Krejci0e5d8382018-11-28 16:37:53 +01001607 str = " ll {default xx; type string;} ...";
1608 assert_int_equal(LY_EVALID, parse_leaflist(&ctx, &str, NULL, (struct lysp_node**)&ll));
1609 logbuf_assert("Invalid keyword \"default\" as a child of \"leaf-list\" - the statement is allowed only in YANG 1.1 modules. Line number 1.");
1610 lysp_node_free(ctx.ctx, (struct lysp_node*)ll); ll = NULL;
1611
1612 *state = NULL;
1613 ly_ctx_destroy(ctx.ctx, NULL);
1614}
1615
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001616static void
1617test_list(void **state)
1618{
1619 *state = test_list;
1620
Radek Krejcie7b95092019-05-15 11:03:07 +02001621 struct lys_parser_ctx ctx = {0};
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001622 struct lysp_node_list *l = NULL;
1623 const char *str;
1624
1625 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1626 assert_non_null(ctx.ctx);
1627 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001628 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001629
1630 /* invalid cardinality */
1631#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1632 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1633 assert_int_equal(LY_EVALID, parse_list(&ctx, &str, NULL, (struct lysp_node**)&l)); \
1634 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1635 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1636
1637 TEST_DUP("config", "true", "false");
1638 TEST_DUP("description", "text1", "text2");
1639 TEST_DUP("key", "one", "two");
1640 TEST_DUP("max-elements", "10", "20");
1641 TEST_DUP("min-elements", "10", "20");
1642 TEST_DUP("ordered-by", "user", "system");
1643 TEST_DUP("reference", "1", "2");
1644 TEST_DUP("status", "current", "obsolete");
1645 TEST_DUP("when", "true", "false");
1646#undef TEST_DUP
1647
1648 /* full content */
1649 str = "l {action x;anydata any;anyxml anyxml; choice ch;config false;container c;description test;grouping g;if-feature f; key l; leaf l {type string;}"
1650 "leaf-list ll {type string;} list li;max-elements 10; min-elements 1;must 'expr';notification not; ordered-by system; reference test;"
1651 "status current;typedef t {type int8;}unique xxx;unique yyy;uses g;when true;m:ext;} ...";
1652 assert_int_equal(LY_SUCCESS, parse_list(&ctx, &str, NULL, (struct lysp_node**)&l));
1653 assert_non_null(l);
1654 assert_int_equal(LYS_LIST, l->nodetype);
1655 assert_string_equal("l", l->name);
1656 assert_string_equal("test", l->dsc);
1657 assert_string_equal("l", l->key);
1658 assert_non_null(l->uniques);
1659 assert_int_equal(2, LY_ARRAY_SIZE(l->uniques));
1660 assert_string_equal("xxx", l->uniques[0]);
1661 assert_string_equal("yyy", l->uniques[1]);
1662 assert_int_equal(10, l->max);
1663 assert_int_equal(1, l->min);
1664 assert_non_null(l->exts);
1665 assert_non_null(l->iffeatures);
1666 assert_non_null(l->musts);
1667 assert_string_equal("test", l->ref);
1668 assert_non_null(l->when);
1669 assert_null(l->parent);
1670 assert_null(l->next);
1671 assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM | LYS_SET_MAX | LYS_SET_MIN, l->flags);
1672 ly_set_erase(&ctx.tpdfs_nodes, NULL);
1673 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1674
Radek Krejcif538ce52019-03-05 10:46:14 +01001675 /* invalid content */
1676 ctx.mod_version = 1; /* simulate YANG 1.0 */
1677 str = "l {action x;} ...";
1678 assert_int_equal(LY_EVALID, parse_list(&ctx, &str, NULL, (struct lysp_node**)&l));
1679 logbuf_assert("Invalid keyword \"action\" as a child of \"list\" - the statement is allowed only in YANG 1.1 modules. Line number 1.");
1680 lysp_node_free(ctx.ctx, (struct lysp_node*)l); l = NULL;
1681
Radek Krejci9bb94eb2018-12-04 16:48:35 +01001682 *state = NULL;
1683 ly_ctx_destroy(ctx.ctx, NULL);
1684}
1685
Radek Krejci056d0a82018-12-06 16:57:25 +01001686static void
1687test_choice(void **state)
1688{
1689 *state = test_choice;
1690
Radek Krejcie7b95092019-05-15 11:03:07 +02001691 struct lys_parser_ctx ctx = {0};
Radek Krejci056d0a82018-12-06 16:57:25 +01001692 struct lysp_node_choice *ch = NULL;
1693 const char *str;
1694
1695 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1696 assert_non_null(ctx.ctx);
1697 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001698 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci056d0a82018-12-06 16:57:25 +01001699
1700 /* invalid cardinality */
1701#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1702 str = "ch {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1703 assert_int_equal(LY_EVALID, parse_choice(&ctx, &str, NULL, (struct lysp_node**)&ch)); \
1704 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1705 lysp_node_free(ctx.ctx, (struct lysp_node*)ch); ch = NULL;
1706
1707 TEST_DUP("config", "true", "false");
1708 TEST_DUP("default", "a", "b");
1709 TEST_DUP("description", "text1", "text2");
1710 TEST_DUP("mandatory", "true", "false");
1711 TEST_DUP("reference", "1", "2");
1712 TEST_DUP("status", "current", "obsolete");
1713 TEST_DUP("when", "true", "false");
1714#undef TEST_DUP
1715
Radek Krejcia9026eb2018-12-12 16:04:47 +01001716 /* full content - without default due to a collision with mandatory */
1717 str = "ch {anydata any;anyxml anyxml; case c;choice ch;config false;container c;description test;if-feature f;leaf l {type string;}"
Radek Krejci056d0a82018-12-06 16:57:25 +01001718 "leaf-list ll {type string;} list li;mandatory true;reference test;status current;when true;m:ext;} ...";
1719 assert_int_equal(LY_SUCCESS, parse_choice(&ctx, &str, NULL, (struct lysp_node**)&ch));
1720 assert_non_null(ch);
1721 assert_int_equal(LYS_CHOICE, ch->nodetype);
1722 assert_string_equal("ch", ch->name);
1723 assert_string_equal("test", ch->dsc);
1724 assert_non_null(ch->exts);
1725 assert_non_null(ch->iffeatures);
1726 assert_string_equal("test", ch->ref);
1727 assert_non_null(ch->when);
1728 assert_null(ch->parent);
1729 assert_null(ch->next);
1730 assert_int_equal(LYS_CONFIG_R | LYS_STATUS_CURR | LYS_MAND_TRUE, ch->flags);
1731 lysp_node_free(ctx.ctx, (struct lysp_node*)ch); ch = NULL;
1732
Radek Krejcia9026eb2018-12-12 16:04:47 +01001733 /* full content - the default missing from the previous node */
1734 str = "ch {default c;case c;} ...";
1735 assert_int_equal(LY_SUCCESS, parse_choice(&ctx, &str, NULL, (struct lysp_node**)&ch));
1736 assert_non_null(ch);
1737 assert_int_equal(LYS_CHOICE, ch->nodetype);
1738 assert_string_equal("ch", ch->name);
1739 assert_string_equal("c", ch->dflt);
1740 assert_int_equal(0, ch->flags);
1741 lysp_node_free(ctx.ctx, (struct lysp_node*)ch); ch = NULL;
1742
1743 /* invalid content */
1744 str = "ch {mandatory true; default c1; case c1 {leaf x{type string;}}} ...";
1745 assert_int_equal(LY_EVALID, parse_choice(&ctx, &str, NULL, (struct lysp_node**)&ch));
1746 logbuf_assert("Invalid combination of keywords \"mandatory\" and \"default\" as substatements of \"choice\". Line number 1.");
1747 lysp_node_free(ctx.ctx, (struct lysp_node*)ch); ch = NULL;
1748
1749 *state = NULL;
1750 ly_ctx_destroy(ctx.ctx, NULL);
1751}
1752
1753static void
1754test_case(void **state)
1755{
1756 *state = test_case;
1757
Radek Krejcie7b95092019-05-15 11:03:07 +02001758 struct lys_parser_ctx ctx = {0};
Radek Krejcia9026eb2018-12-12 16:04:47 +01001759 struct lysp_node_case *cs = NULL;
1760 const char *str;
1761
1762 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1763 assert_non_null(ctx.ctx);
1764 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001765 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejcia9026eb2018-12-12 16:04:47 +01001766
1767 /* invalid cardinality */
1768#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1769 str = "cs {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1770 assert_int_equal(LY_EVALID, parse_case(&ctx, &str, NULL, (struct lysp_node**)&cs)); \
1771 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1772 lysp_node_free(ctx.ctx, (struct lysp_node*)cs); cs = NULL;
1773
1774 TEST_DUP("description", "text1", "text2");
1775 TEST_DUP("reference", "1", "2");
1776 TEST_DUP("status", "current", "obsolete");
1777 TEST_DUP("when", "true", "false");
1778#undef TEST_DUP
1779
1780 /* full content */
1781 str = "cs {anydata any;anyxml anyxml; choice ch;container c;description test;if-feature f;leaf l {type string;}"
1782 "leaf-list ll {type string;} list li;reference test;status current;uses grp;when true;m:ext;} ...";
1783 assert_int_equal(LY_SUCCESS, parse_case(&ctx, &str, NULL, (struct lysp_node**)&cs));
1784 assert_non_null(cs);
1785 assert_int_equal(LYS_CASE, cs->nodetype);
1786 assert_string_equal("cs", cs->name);
1787 assert_string_equal("test", cs->dsc);
1788 assert_non_null(cs->exts);
1789 assert_non_null(cs->iffeatures);
1790 assert_string_equal("test", cs->ref);
1791 assert_non_null(cs->when);
1792 assert_null(cs->parent);
1793 assert_null(cs->next);
1794 assert_int_equal(LYS_STATUS_CURR, cs->flags);
1795 lysp_node_free(ctx.ctx, (struct lysp_node*)cs); cs = NULL;
1796
1797 /* invalid content */
1798 str = "cs {config true} ...";
1799 assert_int_equal(LY_EVALID, parse_case(&ctx, &str, NULL, (struct lysp_node**)&cs));
1800 logbuf_assert("Invalid keyword \"config\" as a child of \"case\". Line number 1.");
1801 lysp_node_free(ctx.ctx, (struct lysp_node*)cs); cs = NULL;
1802
Radek Krejci056d0a82018-12-06 16:57:25 +01001803 *state = NULL;
1804 ly_ctx_destroy(ctx.ctx, NULL);
1805}
1806
Radek Krejci9800fb82018-12-13 14:26:23 +01001807static void
1808test_any(void **state, enum yang_keyword kw)
1809{
1810 *state = test_any;
1811
Radek Krejcie7b95092019-05-15 11:03:07 +02001812 struct lys_parser_ctx ctx = {0};
Radek Krejci9800fb82018-12-13 14:26:23 +01001813 struct lysp_node_anydata *any = NULL;
1814 const char *str;
1815
1816 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1817 assert_non_null(ctx.ctx);
1818 ctx.line = 1;
Radek Krejci9800fb82018-12-13 14:26:23 +01001819 if (kw == YANG_ANYDATA) {
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001820 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci9800fb82018-12-13 14:26:23 +01001821 } else {
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001822 ctx.mod_version = 1; /* simulate YANG 1.0 */
Radek Krejci9800fb82018-12-13 14:26:23 +01001823 }
1824
1825 /* invalid cardinality */
1826#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1827 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1828 assert_int_equal(LY_EVALID, parse_any(&ctx, &str, kw, NULL, (struct lysp_node**)&any)); \
1829 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1830 lysp_node_free(ctx.ctx, (struct lysp_node*)any); any = NULL;
1831
1832 TEST_DUP("config", "true", "false");
1833 TEST_DUP("description", "text1", "text2");
1834 TEST_DUP("mandatory", "true", "false");
1835 TEST_DUP("reference", "1", "2");
1836 TEST_DUP("status", "current", "obsolete");
1837 TEST_DUP("when", "true", "false");
1838#undef TEST_DUP
1839
1840 /* full content */
1841 str = "any {config true;description test;if-feature f;mandatory true;must 'expr';reference test;status current;when true;m:ext;} ...";
1842 assert_int_equal(LY_SUCCESS, parse_any(&ctx, &str, kw, NULL, (struct lysp_node**)&any));
1843 assert_non_null(any);
1844 assert_int_equal(kw == YANG_ANYDATA ? LYS_ANYDATA : LYS_ANYXML, any->nodetype);
1845 assert_string_equal("any", any->name);
1846 assert_string_equal("test", any->dsc);
1847 assert_non_null(any->exts);
1848 assert_non_null(any->iffeatures);
1849 assert_non_null(any->musts);
1850 assert_string_equal("test", any->ref);
1851 assert_non_null(any->when);
1852 assert_null(any->parent);
1853 assert_null(any->next);
1854 assert_int_equal(LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE, any->flags);
1855 lysp_node_free(ctx.ctx, (struct lysp_node*)any); any = NULL;
1856
1857 *state = NULL;
1858 ly_ctx_destroy(ctx.ctx, NULL);
1859}
1860
1861static void
1862test_anydata(void **state)
1863{
1864 return test_any(state, YANG_ANYDATA);
1865}
1866
1867static void
1868test_anyxml(void **state)
1869{
1870 return test_any(state, YANG_ANYXML);
1871}
1872
Radek Krejcie86bf772018-12-14 11:39:53 +01001873static void
1874test_grouping(void **state)
1875{
1876 *state = test_grouping;
1877
Radek Krejcie7b95092019-05-15 11:03:07 +02001878 struct lys_parser_ctx ctx = {0};
Radek Krejcie86bf772018-12-14 11:39:53 +01001879 struct lysp_grp *grp = NULL;
1880 const char *str;
1881
1882 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1883 assert_non_null(ctx.ctx);
1884 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01001885 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejcie86bf772018-12-14 11:39:53 +01001886
1887 /* invalid cardinality */
1888#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1889 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1890 assert_int_equal(LY_EVALID, parse_grouping(&ctx, &str, NULL, &grp)); \
1891 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1892 FREE_ARRAY(ctx.ctx, grp, lysp_grp_free); grp = NULL;
1893
1894 TEST_DUP("description", "text1", "text2");
1895 TEST_DUP("reference", "1", "2");
1896 TEST_DUP("status", "current", "obsolete");
1897#undef TEST_DUP
1898
1899 /* full content */
1900 str = "grp {action x;anydata any;anyxml anyxml; choice ch;container c;description test;grouping g;leaf l {type string;}"
1901 "leaf-list ll {type string;} list li;notification not;reference test;status current;typedef t {type int8;}uses g;m:ext;} ...";
1902 assert_int_equal(LY_SUCCESS, parse_grouping(&ctx, &str, NULL, &grp));
1903 assert_non_null(grp);
1904 assert_int_equal(LYS_GROUPING, grp->nodetype);
1905 assert_string_equal("grp", grp->name);
1906 assert_string_equal("test", grp->dsc);
1907 assert_non_null(grp->exts);
1908 assert_string_equal("test", grp->ref);
1909 assert_null(grp->parent);
1910 assert_int_equal( LYS_STATUS_CURR, grp->flags);
1911 ly_set_erase(&ctx.tpdfs_nodes, NULL);
1912 FREE_ARRAY(ctx.ctx, grp, lysp_grp_free); grp = NULL;
1913
1914 /* invalid content */
1915 str = "grp {config true} ...";
1916 assert_int_equal(LY_EVALID, parse_grouping(&ctx, &str, NULL, &grp));
1917 logbuf_assert("Invalid keyword \"config\" as a child of \"grouping\". Line number 1.");
1918 FREE_ARRAY(ctx.ctx, grp, lysp_grp_free); grp = NULL;
1919
1920 str = "grp {must 'expr'} ...";
1921 assert_int_equal(LY_EVALID, parse_grouping(&ctx, &str, NULL, &grp));
1922 logbuf_assert("Invalid keyword \"must\" as a child of \"grouping\". Line number 1.");
1923 FREE_ARRAY(ctx.ctx, grp, lysp_grp_free); grp = NULL;
1924
1925 *state = NULL;
1926 ly_ctx_destroy(ctx.ctx, NULL);
1927}
1928
1929static void
Radek Krejcif538ce52019-03-05 10:46:14 +01001930test_action(void **state)
1931{
1932 *state = test_action;
1933
Radek Krejcie7b95092019-05-15 11:03:07 +02001934 struct lys_parser_ctx ctx = {0};
Radek Krejcif538ce52019-03-05 10:46:14 +01001935 struct lysp_action *rpcs = NULL;
1936 struct lysp_node_container *c = NULL;
1937 const char *str;
1938
1939 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
1940 assert_non_null(ctx.ctx);
1941 ctx.line = 1;
1942 ctx.mod_version = 2; /* simulate YANG 1.1 */
1943
1944 /* invalid cardinality */
1945#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
1946 str = "func {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
1947 assert_int_equal(LY_EVALID, parse_action(&ctx, &str, NULL, &rpcs)); \
1948 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
1949 FREE_ARRAY(ctx.ctx, rpcs, lysp_action_free); rpcs = NULL;
1950
1951 TEST_DUP("description", "text1", "text2");
1952 TEST_DUP("input", "", "");
1953 TEST_DUP("output", "", "");
1954 TEST_DUP("reference", "1", "2");
1955 TEST_DUP("status", "current", "obsolete");
1956#undef TEST_DUP
1957
1958 /* full content */
1959 str = "top;";
1960 assert_int_equal(LY_SUCCESS, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
1961 str = "func {description test;grouping grp;if-feature f;reference test;status current;typedef mytype {type int8;} m:ext;"
1962 "input {anydata a1; anyxml a2; choice ch; container c; grouping grp; leaf l {type int8;} leaf-list ll {type int8;}"
1963 " list li; must 1; typedef mytypei {type int8;} uses grp; m:ext;}"
1964 "output {anydata a1; anyxml a2; choice ch; container c; grouping grp; leaf l {type int8;} leaf-list ll {type int8;}"
1965 " list li; must 1; typedef mytypeo {type int8;} uses grp; m:ext;}} ...";
1966 assert_int_equal(LY_SUCCESS, parse_action(&ctx, &str, (struct lysp_node*)c, &rpcs));
1967 assert_non_null(rpcs);
1968 assert_int_equal(LYS_ACTION, rpcs->nodetype);
1969 assert_string_equal("func", rpcs->name);
1970 assert_string_equal("test", rpcs->dsc);
1971 assert_non_null(rpcs->exts);
1972 assert_non_null(rpcs->iffeatures);
1973 assert_string_equal("test", rpcs->ref);
1974 assert_non_null(rpcs->groupings);
1975 assert_non_null(rpcs->typedefs);
1976 assert_int_equal(LYS_STATUS_CURR, rpcs->flags);
1977 /* input */
Radek Krejcid3ca0632019-04-16 16:54:54 +02001978 assert_int_equal(rpcs->input.nodetype, LYS_INPUT);
Radek Krejcif538ce52019-03-05 10:46:14 +01001979 assert_non_null(rpcs->input.groupings);
1980 assert_non_null(rpcs->input.exts);
1981 assert_non_null(rpcs->input.musts);
1982 assert_non_null(rpcs->input.typedefs);
1983 assert_non_null(rpcs->input.data);
1984 /* output */
Radek Krejcid3ca0632019-04-16 16:54:54 +02001985 assert_int_equal(rpcs->output.nodetype, LYS_OUTPUT);
Radek Krejcif538ce52019-03-05 10:46:14 +01001986 assert_non_null(rpcs->output.groupings);
1987 assert_non_null(rpcs->output.exts);
1988 assert_non_null(rpcs->output.musts);
1989 assert_non_null(rpcs->output.typedefs);
1990 assert_non_null(rpcs->output.data);
1991
1992 ly_set_erase(&ctx.tpdfs_nodes, NULL);
1993 FREE_ARRAY(ctx.ctx, rpcs, lysp_action_free); rpcs = NULL;
1994
1995 /* invalid content */
1996 str = "func {config true} ...";
1997 assert_int_equal(LY_EVALID, parse_action(&ctx, &str, NULL, &rpcs));
1998 logbuf_assert("Invalid keyword \"config\" as a child of \"rpc\". Line number 1.");
1999 FREE_ARRAY(ctx.ctx, rpcs, lysp_action_free); rpcs = NULL;
2000
2001 *state = NULL;
2002 lysp_node_free(ctx.ctx, (struct lysp_node*)c);
2003 ly_ctx_destroy(ctx.ctx, NULL);
2004}
2005
2006static void
Radek Krejcifc11bd72019-04-11 16:00:05 +02002007test_notification(void **state)
2008{
2009 *state = test_notification;
2010
Radek Krejcie7b95092019-05-15 11:03:07 +02002011 struct lys_parser_ctx ctx = {0};
Radek Krejcifc11bd72019-04-11 16:00:05 +02002012 struct lysp_notif *notifs = NULL;
2013 struct lysp_node_container *c = NULL;
2014 const char *str;
2015
2016 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
2017 assert_non_null(ctx.ctx);
2018 ctx.line = 1;
2019 ctx.mod_version = 2; /* simulate YANG 1.1 */
2020
2021 /* invalid cardinality */
2022#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
2023 str = "func {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
2024 assert_int_equal(LY_EVALID, parse_notif(&ctx, &str, NULL, &notifs)); \
2025 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
2026 FREE_ARRAY(ctx.ctx, notifs, lysp_notif_free); notifs = NULL;
2027
2028 TEST_DUP("description", "text1", "text2");
2029 TEST_DUP("reference", "1", "2");
2030 TEST_DUP("status", "current", "obsolete");
2031#undef TEST_DUP
2032
2033 /* full content */
2034 str = "top;";
2035 assert_int_equal(LY_SUCCESS, parse_container(&ctx, &str, NULL, (struct lysp_node**)&c));
2036 str = "ntf {anydata a1; anyxml a2; choice ch; container c; description test; grouping grp; if-feature f; leaf l {type int8;}"
2037 "leaf-list ll {type int8;} list li; must 1; reference test; status current; typedef mytype {type int8;} uses grp; m:ext;}";
2038 assert_int_equal(LY_SUCCESS, parse_notif(&ctx, &str, (struct lysp_node*)c, &notifs));
2039 assert_non_null(notifs);
2040 assert_int_equal(LYS_NOTIF, notifs->nodetype);
2041 assert_string_equal("ntf", notifs->name);
2042 assert_string_equal("test", notifs->dsc);
2043 assert_non_null(notifs->exts);
2044 assert_non_null(notifs->iffeatures);
2045 assert_string_equal("test", notifs->ref);
2046 assert_non_null(notifs->groupings);
2047 assert_non_null(notifs->typedefs);
2048 assert_non_null(notifs->musts);
2049 assert_non_null(notifs->data);
2050 assert_int_equal(LYS_STATUS_CURR, notifs->flags);
2051
2052 ly_set_erase(&ctx.tpdfs_nodes, NULL);
2053 FREE_ARRAY(ctx.ctx, notifs, lysp_notif_free); notifs = NULL;
2054
2055 /* invalid content */
2056 str = "ntf {config true} ...";
2057 assert_int_equal(LY_EVALID, parse_notif(&ctx, &str, NULL, &notifs));
2058 logbuf_assert("Invalid keyword \"config\" as a child of \"notification\". Line number 1.");
2059 FREE_ARRAY(ctx.ctx, notifs, lysp_notif_free); notifs = NULL;
2060
2061 *state = NULL;
2062 lysp_node_free(ctx.ctx, (struct lysp_node*)c);
2063 ly_ctx_destroy(ctx.ctx, NULL);
2064}
2065
2066static void
Radek Krejcie86bf772018-12-14 11:39:53 +01002067test_uses(void **state)
2068{
2069 *state = test_uses;
2070
Radek Krejcie7b95092019-05-15 11:03:07 +02002071 struct lys_parser_ctx ctx = {0};
Radek Krejcie86bf772018-12-14 11:39:53 +01002072 struct lysp_node_uses *u = NULL;
2073 const char *str;
2074
2075 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
2076 assert_non_null(ctx.ctx);
2077 ctx.line = 1;
Radek Krejci0bcdaed2019-01-10 10:21:34 +01002078 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejcie86bf772018-12-14 11:39:53 +01002079
2080 /* invalid cardinality */
2081#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
2082 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
2083 assert_int_equal(LY_EVALID, parse_uses(&ctx, &str, NULL, (struct lysp_node**)&u)); \
2084 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
2085 lysp_node_free(ctx.ctx, (struct lysp_node*)u); u = NULL;
2086
2087 TEST_DUP("description", "text1", "text2");
2088 TEST_DUP("reference", "1", "2");
2089 TEST_DUP("status", "current", "obsolete");
2090 TEST_DUP("when", "true", "false");
2091#undef TEST_DUP
2092
2093 /* full content */
2094 str = "grpref {augment some/node;description test;if-feature f;reference test;refine some/other/node;status current;when true;m:ext;} ...";
2095 assert_int_equal(LY_SUCCESS, parse_uses(&ctx, &str, NULL, (struct lysp_node**)&u));
2096 assert_non_null(u);
2097 assert_int_equal(LYS_USES, u->nodetype);
2098 assert_string_equal("grpref", u->name);
2099 assert_string_equal("test", u->dsc);
2100 assert_non_null(u->exts);
2101 assert_non_null(u->iffeatures);
2102 assert_string_equal("test", u->ref);
2103 assert_non_null(u->augments);
2104 assert_non_null(u->refines);
2105 assert_non_null(u->when);
2106 assert_null(u->parent);
2107 assert_null(u->next);
2108 assert_int_equal(LYS_STATUS_CURR, u->flags);
2109 lysp_node_free(ctx.ctx, (struct lysp_node*)u); u = NULL;
2110
2111 *state = NULL;
2112 ly_ctx_destroy(ctx.ctx, NULL);
2113}
Radek Krejci5a7c4a52019-02-12 15:45:11 +01002114
2115
2116static void
2117test_augment(void **state)
2118{
2119 *state = test_augment;
2120
Radek Krejcie7b95092019-05-15 11:03:07 +02002121 struct lys_parser_ctx ctx = {0};
Radek Krejci5a7c4a52019-02-12 15:45:11 +01002122 struct lysp_augment *a = NULL;
2123 const char *str;
2124
2125 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
2126 assert_non_null(ctx.ctx);
2127 ctx.line = 1;
Radek Krejcib4adbf12019-02-25 13:35:22 +01002128 ctx.mod_version = 2; /* simulate YANG 1.1 */
Radek Krejci5a7c4a52019-02-12 15:45:11 +01002129
2130 /* invalid cardinality */
2131#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
2132 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
2133 assert_int_equal(LY_EVALID, parse_augment(&ctx, &str, NULL, &a)); \
2134 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
Radek Krejcib4adbf12019-02-25 13:35:22 +01002135 FREE_ARRAY(ctx.ctx, a, lysp_augment_free); a = NULL;
Radek Krejci5a7c4a52019-02-12 15:45:11 +01002136
2137 TEST_DUP("description", "text1", "text2");
2138 TEST_DUP("reference", "1", "2");
2139 TEST_DUP("status", "current", "obsolete");
2140 TEST_DUP("when", "true", "false");
2141#undef TEST_DUP
2142
2143 /* full content */
2144 str = "/target/nodeid {action x; anydata any;anyxml anyxml; case cs; choice ch;container c;description test;if-feature f;leaf l {type string;}"
2145 "leaf-list ll {type string;} list li;notification not;reference test;status current;uses g;when true;m:ext;} ...";
2146 assert_int_equal(LY_SUCCESS, parse_augment(&ctx, &str, NULL, &a));
2147 assert_non_null(a);
2148 assert_int_equal(LYS_AUGMENT, a->nodetype);
2149 assert_string_equal("/target/nodeid", a->nodeid);
2150 assert_string_equal("test", a->dsc);
2151 assert_non_null(a->exts);
2152 assert_non_null(a->iffeatures);
2153 assert_string_equal("test", a->ref);
2154 assert_non_null(a->when);
2155 assert_null(a->parent);
2156 assert_int_equal(LYS_STATUS_CURR, a->flags);
Radek Krejcib4adbf12019-02-25 13:35:22 +01002157 FREE_ARRAY(ctx.ctx, a, lysp_augment_free); a = NULL;
Radek Krejci5a7c4a52019-02-12 15:45:11 +01002158
2159 *state = NULL;
2160 ly_ctx_destroy(ctx.ctx, NULL);
2161}
2162
Radek Krejcif09e4e82019-06-14 15:08:11 +02002163static void
2164test_when(void **state)
2165{
2166 *state = test_when;
2167
2168 struct lys_parser_ctx ctx = {0};
2169 struct lysp_when *w = NULL;
2170 const char *str;
2171
2172 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
2173 assert_non_null(ctx.ctx);
2174 ctx.line = 1;
2175 ctx.mod_version = 2; /* simulate YANG 1.1 */
2176
2177 /* invalid cardinality */
2178#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
2179 str = "l {" MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
2180 assert_int_equal(LY_EVALID, parse_when(&ctx, &str, &w)); \
2181 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
2182 FREE_MEMBER(ctx.ctx, w, lysp_when_free); w = NULL;
2183
2184 TEST_DUP("description", "text1", "text2");
2185 TEST_DUP("reference", "1", "2");
2186#undef TEST_DUP
2187
2188 /* full content */
2189 str = "expression {description test;reference test;m:ext;} ...";
2190 assert_int_equal(LY_SUCCESS, parse_when(&ctx, &str, &w));
2191 assert_non_null(w);
2192 assert_string_equal("expression", w->cond);
2193 assert_string_equal("test", w->dsc);
2194 assert_string_equal("test", w->ref);
2195 assert_non_null(w->exts);
2196 FREE_MEMBER(ctx.ctx, w, lysp_when_free); w = NULL;
2197
2198 /* empty condition */
2199 str = "\"\";";
2200 assert_int_equal(LY_SUCCESS, parse_when(&ctx, &str, &w));
2201 logbuf_assert("Empty argument of when statement does not make sense.");
2202 assert_non_null(w);
2203 assert_string_equal("", w->cond);
2204 FREE_MEMBER(ctx.ctx, w, lysp_when_free); w = NULL;
2205
2206 *state = NULL;
2207 ly_ctx_destroy(ctx.ctx, NULL);
2208}
2209
Radek Krejci80dd33e2018-09-26 15:57:18 +02002210int main(void)
2211{
2212 const struct CMUnitTest tests[] = {
Radek Krejci44ceedc2018-10-02 15:54:31 +02002213 cmocka_unit_test_setup(test_helpers, logger_setup),
Radek Krejci80dd33e2018-09-26 15:57:18 +02002214 cmocka_unit_test_setup(test_comments, logger_setup),
Radek Krejciefd22f62018-09-27 11:47:58 +02002215 cmocka_unit_test_setup(test_arg, logger_setup),
Radek Krejcidcc7b322018-10-11 14:24:02 +02002216 cmocka_unit_test_setup(test_stmts, logger_setup),
Radek Krejci05b13982018-11-28 16:22:07 +01002217 cmocka_unit_test_setup_teardown(test_minmax, logger_setup, logger_teardown),
Radek Krejci40544fa2019-01-11 09:38:37 +01002218 cmocka_unit_test_setup_teardown(test_module, logger_setup, logger_teardown),
Radek Krejci0bcdaed2019-01-10 10:21:34 +01002219 cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
Radek Krejci2c02f3e2018-10-16 10:54:38 +02002220 cmocka_unit_test_setup(test_feature, logger_setup),
2221 cmocka_unit_test_setup(test_deviation, logger_setup),
2222 cmocka_unit_test_setup(test_deviate, logger_setup),
Radek Krejci8c370832018-11-02 15:10:03 +01002223 cmocka_unit_test_setup(test_container, logger_setup),
Radek Krejcib1a5dcc2018-11-26 14:50:05 +01002224 cmocka_unit_test_setup_teardown(test_leaf, logger_setup, logger_teardown),
Radek Krejci0e5d8382018-11-28 16:37:53 +01002225 cmocka_unit_test_setup_teardown(test_leaflist, logger_setup, logger_teardown),
Radek Krejci9bb94eb2018-12-04 16:48:35 +01002226 cmocka_unit_test_setup_teardown(test_list, logger_setup, logger_teardown),
Radek Krejci056d0a82018-12-06 16:57:25 +01002227 cmocka_unit_test_setup_teardown(test_choice, logger_setup, logger_teardown),
Radek Krejcia9026eb2018-12-12 16:04:47 +01002228 cmocka_unit_test_setup_teardown(test_case, logger_setup, logger_teardown),
Radek Krejci9800fb82018-12-13 14:26:23 +01002229 cmocka_unit_test_setup_teardown(test_anydata, logger_setup, logger_teardown),
2230 cmocka_unit_test_setup_teardown(test_anyxml, logger_setup, logger_teardown),
Radek Krejcif538ce52019-03-05 10:46:14 +01002231 cmocka_unit_test_setup_teardown(test_action, logger_setup, logger_teardown),
Radek Krejcifc11bd72019-04-11 16:00:05 +02002232 cmocka_unit_test_setup_teardown(test_notification, logger_setup, logger_teardown),
Radek Krejcie86bf772018-12-14 11:39:53 +01002233 cmocka_unit_test_setup_teardown(test_grouping, logger_setup, logger_teardown),
2234 cmocka_unit_test_setup_teardown(test_uses, logger_setup, logger_teardown),
Radek Krejcib4adbf12019-02-25 13:35:22 +01002235 cmocka_unit_test_setup_teardown(test_augment, logger_setup, logger_teardown),
Radek Krejcif09e4e82019-06-14 15:08:11 +02002236 cmocka_unit_test_setup_teardown(test_when, logger_setup, logger_teardown),
Radek Krejci80dd33e2018-09-26 15:57:18 +02002237 };
2238
2239 return cmocka_run_group_tests(tests, NULL, NULL);
2240}