blob: fa4792518a7db8f1aa4e3278fd3555499a511ca2 [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
15#define _BSD_SOURCE
16#define _DEFAULT_SOURCE
17#include <stdarg.h>
18#include <stddef.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include <stdio.h>
23#include <string.h>
24
25#include "libyang.h"
26#include "../../src/parser_yang.c"
Radek Krejci4c6d9bd2018-10-15 16:43:06 +020027#include "../../src/tree_schema.c"
Radek Krejci80dd33e2018-09-26 15:57:18 +020028
29#define BUFSIZE 1024
30char logbuf[BUFSIZE] = {0};
31
32/* set to 0 to printing error messages to stderr instead of checking them in code */
Radek Krejci70853c52018-10-15 14:46:16 +020033#define ENABLE_LOGGER_CHECKING 1
Radek Krejci80dd33e2018-09-26 15:57:18 +020034
Radek Krejcid5f2b5f2018-10-11 10:54:36 +020035#if ENABLE_LOGGER_CHECKING
Radek Krejci80dd33e2018-09-26 15:57:18 +020036static void
37logger(LY_LOG_LEVEL level, const char *msg, const char *path)
38{
39 (void) level; /* unused */
40
41 if (path) {
42 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
43 } else {
44 strncpy(logbuf, msg, BUFSIZE - 1);
45 }
46}
Radek Krejcid5f2b5f2018-10-11 10:54:36 +020047#endif
Radek Krejci80dd33e2018-09-26 15:57:18 +020048
49static int
50logger_setup(void **state)
51{
52 (void) state; /* unused */
53#if ENABLE_LOGGER_CHECKING
54 ly_set_log_clb(logger, 1);
55#endif
56 return 0;
57}
58
59void
60logbuf_clean(void)
61{
62 logbuf[0] = '\0';
63}
64
65#if ENABLE_LOGGER_CHECKING
66# define logbuf_assert(str) assert_string_equal(logbuf, str)
67#else
68# define logbuf_assert(str)
69#endif
70
Radek Krejci44ceedc2018-10-02 15:54:31 +020071static void
72test_helpers(void **state)
73{
74 (void) state; /* unused */
75
76 const char *str;
Radek Krejci404251e2018-10-09 12:06:44 +020077 char *buf, *p;
Radek Krejci44ceedc2018-10-02 15:54:31 +020078 size_t len, size;
79 int prefix;
80 struct ly_parser_ctx ctx;
81 ctx.ctx = NULL;
82 ctx.line = 1;
83
84 /* storing into buffer */
85 str = "abcd";
86 buf = NULL;
87 size = len = 0;
88 assert_int_equal(LY_SUCCESS, buf_add_char(NULL, &str, 2, &buf, &size, &len));
89 assert_int_not_equal(0, size);
90 assert_int_equal(2, len);
91 assert_string_equal("cd", str);
92 assert_false(strncmp("ab", buf, 2));
93 free(buf);
Radek Krejci404251e2018-10-09 12:06:44 +020094 buf = NULL;
95
96 /* invalid first characters */
97 len = 0;
98 str = "2invalid";
99 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1));
100 str = ".invalid";
101 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1));
102 str = "-invalid";
103 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1));
104 /* invalid following characters */
105 len = 3; /* number of characters read before the str content */
106 str = "!";
107 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1));
108 str = ":";
109 assert_int_equal(LY_EVALID, buf_store_char(&ctx, &str, Y_IDENTIF_ARG, &p, &len, &buf, &size, 1));
110 /* valid colon for prefixed identifiers */
111 len = size = 0;
112 p = NULL;
113 str = "x:id";
114 assert_int_equal(LY_SUCCESS, buf_store_char(&ctx, &str, Y_PREF_IDENTIF_ARG, &p, &len, &buf, &size, 0));
115 assert_int_equal(1, len);
116 assert_null(buf);
117 assert_string_equal(":id", str);
118 assert_int_equal('x', p[len - 1]);
119 assert_int_equal(LY_SUCCESS, buf_store_char(&ctx, &str, Y_PREF_IDENTIF_ARG, &p, &len, &buf, &size, 1));
120 assert_int_equal(2, len);
121 assert_string_equal("id", str);
122 assert_int_equal(':', p[len - 1]);
123 free(buf);
Radek Krejci44ceedc2018-10-02 15:54:31 +0200124
125 /* checking identifiers */
126 assert_int_equal(LY_EVALID, check_identifierchar(&ctx, ':', 0, NULL));
127 logbuf_assert("Invalid identifier character ':'. Line number 1.");
128 assert_int_equal(LY_EVALID, check_identifierchar(&ctx, '#', 1, NULL));
129 logbuf_assert("Invalid identifier first character '#'. Line number 1.");
130
131 assert_int_equal(LY_SUCCESS, check_identifierchar(&ctx, 'a', 1, &prefix));
132 assert_int_equal(0, prefix);
133 assert_int_equal(LY_SUCCESS, check_identifierchar(&ctx, ':', 0, &prefix));
134 assert_int_equal(1, prefix);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200135 assert_int_equal(LY_EVALID, check_identifierchar(&ctx, ':', 0, &prefix));
136 assert_int_equal(1, prefix);
Radek Krejci44ceedc2018-10-02 15:54:31 +0200137 assert_int_equal(LY_SUCCESS, check_identifierchar(&ctx, 'b', 0, &prefix));
138 assert_int_equal(2, prefix);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200139 /* second colon is invalid */
140 assert_int_equal(LY_EVALID, check_identifierchar(&ctx, ':', 0, &prefix));
141 logbuf_assert("Invalid identifier character ':'. Line number 1.");
Radek Krejci44ceedc2018-10-02 15:54:31 +0200142}
Radek Krejci80dd33e2018-09-26 15:57:18 +0200143
144static void
145test_comments(void **state)
146{
147 (void) state; /* unused */
148
Radek Krejci44ceedc2018-10-02 15:54:31 +0200149 struct ly_parser_ctx ctx;
Radek Krejci80dd33e2018-09-26 15:57:18 +0200150 const char *str, *p;
Radek Krejciefd22f62018-09-27 11:47:58 +0200151 char *word, *buf;
152 size_t len;
Radek Krejci80dd33e2018-09-26 15:57:18 +0200153
Radek Krejci44ceedc2018-10-02 15:54:31 +0200154 ctx.ctx = NULL;
155 ctx.line = 1;
156
Radek Krejciefd22f62018-09-27 11:47:58 +0200157 str = " // this is a text of / one * line */ comment\nargument";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200158 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200159 assert_string_equal("argument", word);
160 assert_null(buf);
161 assert_int_equal(8, len);
Radek Krejci80dd33e2018-09-26 15:57:18 +0200162
Radek Krejciefd22f62018-09-27 11:47:58 +0200163 str = "/* this is a \n * text // of / block * comment */\"arg\" + \"ume\" \n + \n \"nt\"";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200164 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200165 assert_string_equal("argument", word);
166 assert_ptr_equal(buf, word);
167 assert_int_equal(8, len);
168 free(word);
Radek Krejci80dd33e2018-09-26 15:57:18 +0200169
170 str = p = " this is one line comment on last line";
Radek Krejci44ceedc2018-10-02 15:54:31 +0200171 assert_int_equal(LY_SUCCESS, skip_comment(&ctx, &str, 1));
Radek Krejci80dd33e2018-09-26 15:57:18 +0200172 assert_true(str[0] == '\0');
173
174 str = p = " this is a not terminated comment x";
Radek Krejci44ceedc2018-10-02 15:54:31 +0200175 assert_int_equal(LY_EVALID, skip_comment(&ctx, &str, 2));
176 logbuf_assert("Unexpected end-of-file, non-terminated comment. Line number 5.");
Radek Krejci80dd33e2018-09-26 15:57:18 +0200177 assert_true(str[0] == '\0');
178}
179
Radek Krejciefd22f62018-09-27 11:47:58 +0200180static void
181test_arg(void **state)
182{
183 (void) state; /* unused */
184
Radek Krejci44ceedc2018-10-02 15:54:31 +0200185 struct ly_parser_ctx ctx;
Radek Krejciefd22f62018-09-27 11:47:58 +0200186 const char *str;
187 char *word, *buf;
188 size_t len;
189
Radek Krejci44ceedc2018-10-02 15:54:31 +0200190 ctx.ctx = NULL;
191 ctx.line = 1;
192
Radek Krejciefd22f62018-09-27 11:47:58 +0200193 /* missing argument */
194 str = ";";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200195 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_MAYBE_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200196 assert_null(word);
197
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200198 str = "{";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200199 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200200 logbuf_assert("Invalid character sequence \"{\", expected an argument. Line number 1.");
201
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200202 /* invalid escape sequence */
203 str = "\"\\s\"";
204 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200205 logbuf_assert("Double-quoted string unknown special character \'\\s\'. Line number 1.");
206 str = "\'\\s\'"; /* valid, since it is not an escape sequence in single quoted string */
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200207 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200208 assert_int_equal(2, len);
209 assert_string_equal("\\s\'", word);
210 assert_int_equal('\0', str[0]); /* input has been eaten */
211
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200212 /* invalid character after the argument */
213 str = "hello\"";
214 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
215 logbuf_assert("Invalid character sequence \"\"\", expected unquoted string character, optsep, semicolon or opening brace. Line number 1.");
216 str = "hello}";
217 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
218 logbuf_assert("Invalid character sequence \"}\", expected unquoted string character, optsep, semicolon or opening brace. Line number 1.");
219
220 str = "hello/x\t"; /* slash is not an invalid character */
221 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
222 assert_int_equal(7, len);
223 assert_string_equal("hello/x\t", word);
224
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200225 assert_null(buf);
Radek Krejciefd22f62018-09-27 11:47:58 +0200226
227 /* different quoting */
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200228 str = "hello ";
229 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200230 assert_null(buf);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200231 assert_int_equal(5, len);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200232 assert_string_equal("hello ", word);
Radek Krejciefd22f62018-09-27 11:47:58 +0200233
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200234 str = "hello/*comment*/\n";
235 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200236 assert_null(buf);
237 assert_int_equal(5, len);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200238 assert_false(strncmp("hello", word, len));
239
240
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200241 str = "\"hello\\n\\t\\\"\\\\\";";
242 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200243 assert_null(buf);
244 assert_int_equal(9, len);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200245 assert_string_equal("hello\\n\\t\\\"\\\\\";", word);
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200246
247 ctx.indent = 14;
248 str = "\"hello \t\n\t\t world!\"";
249 /* - space and tabs before newline are stripped out
250 * - space and tabs after newline (indentation) are stripped out
251 */
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200252 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200253 assert_non_null(buf);
254 assert_ptr_equal(word, buf);
255 assert_int_equal(14, len);
256 assert_string_equal("hello\n world!", word);
257 free(buf);
258
259 ctx.indent = 14;
260 str = "\"hello\n \tworld!\"";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200261 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejcid5f2b5f2018-10-11 10:54:36 +0200262 assert_non_null(buf);
263 assert_ptr_equal(word, buf);
264 assert_int_equal(12, len);
265 assert_string_equal("hello\nworld!", word);
266 free(buf);
Radek Krejciefd22f62018-09-27 11:47:58 +0200267
268 str = "\'hello\'";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200269 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200270 assert_null(buf);
271 assert_int_equal(5, len);
272 assert_false(strncmp("hello", word, 5));
273
274 str = "\"hel\" +\t\n\"lo\"";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200275 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200276 assert_ptr_equal(word, buf);
277 assert_int_equal(5, len);
278 assert_string_equal("hello", word);
279 free(buf);
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200280 str = "\"hel\" +\t\nlo"; /* unquoted the second part */
281 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
282 logbuf_assert("Both string parts divided by '+' must be quoted. Line number 5.");
Radek Krejciefd22f62018-09-27 11:47:58 +0200283
284 str = "\'he\'\t\n+ \"llo\"";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200285 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200286 assert_ptr_equal(word, buf);
287 assert_int_equal(5, len);
288 assert_string_equal("hello", word);
289 free(buf);
290
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200291 str = " \t\n\"he\"+\'llo\'";
292 assert_int_equal(LY_SUCCESS, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
Radek Krejciefd22f62018-09-27 11:47:58 +0200293 assert_ptr_equal(word, buf);
294 assert_int_equal(5, len);
295 assert_string_equal("hello", word);
296 free(buf);
297
Radek Krejci44ceedc2018-10-02 15:54:31 +0200298 /* missing argument */
299 str = ";";
Radek Krejcifc62d7e2018-10-11 12:56:42 +0200300 assert_int_equal(LY_EVALID, get_argument(&ctx, &str, Y_STR_ARG, &word, &buf, &len));
301 logbuf_assert("Invalid character sequence \";\", expected an argument. Line number 7.");
Radek Krejcidcc7b322018-10-11 14:24:02 +0200302}
303
304static void
305test_stmts(void **state)
306{
307 (void) state; /* unused */
308
309 struct ly_parser_ctx ctx;
310 const char *str, *p;
311 enum yang_keyword kw;
312 char *word;
313 size_t len;
314
315 ctx.ctx = NULL;
316 ctx.line = 1;
317
318 str = "\n// comment\n\tinput\t{";
319 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
320 assert_int_equal(YANG_INPUT, kw);
321 assert_int_equal(5, len);
322 assert_string_equal("input\t{", word);
323 assert_string_equal("\t{", str);
324
325 str = "\t /* comment */\t output\n\t{";
326 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
327 assert_int_equal(YANG_OUTPUT, kw);
328 assert_int_equal(6, len);
329 assert_string_equal("output\n\t{", word);
330 assert_string_equal("\n\t{", str);
331
332 str = "/input { "; /* invalid slash */
333 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
334 logbuf_assert("Invalid identifier first character '/'. Line number 4.");
335
336 str = "not-a-statement-nor-extension { "; /* invalid identifier */
337 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
338 logbuf_assert("Invalid character sequence \"not-a-statement-nor-extension\", expected a keyword. Line number 4.");
339
340 str = "path;"; /* missing sep after the keyword */
341 assert_int_equal(LY_EVALID, get_keyword(&ctx, &str, &kw, &word, &len));
342 logbuf_assert("Invalid character sequence \"path;\", expected a keyword followed by a separator. Line number 4.");
343
344 str = "action ";
345 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
346 assert_int_equal(YANG_ACTION, kw);
347 assert_int_equal(6, len);
348 str = "anydata ";
349 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
350 assert_int_equal(YANG_ANYDATA, kw);
351 assert_int_equal(7, len);
352 str = "anyxml ";
353 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
354 assert_int_equal(YANG_ANYXML, kw);
355 assert_int_equal(6, len);
356 str = "argument ";
357 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
358 assert_int_equal(YANG_ARGUMENT, kw);
359 assert_int_equal(8, len);
360 str = "augment ";
361 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
362 assert_int_equal(YANG_AUGMENT, kw);
363 assert_int_equal(7, len);
364 str = "base ";
365 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
366 assert_int_equal(YANG_BASE, kw);
367 assert_int_equal(4, len);
368 str = "belongs-to ";
369 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
370 assert_int_equal(YANG_BELONGS_TO, kw);
371 assert_int_equal(10, len);
372 str = "bit ";
373 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
374 assert_int_equal(YANG_BIT, kw);
375 assert_int_equal(3, len);
376 str = "case ";
377 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
378 assert_int_equal(YANG_CASE, kw);
379 assert_int_equal(4, len);
380 str = "choice ";
381 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
382 assert_int_equal(YANG_CHOICE, kw);
383 assert_int_equal(6, len);
384 str = "config ";
385 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
386 assert_int_equal(YANG_CONFIG, kw);
387 assert_int_equal(6, len);
388 str = "contact ";
389 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
390 assert_int_equal(YANG_CONTACT, kw);
391 assert_int_equal(7, len);
392 str = "container ";
393 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
394 assert_int_equal(YANG_CONTAINER, kw);
395 assert_int_equal(9, len);
396 str = "default ";
397 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
398 assert_int_equal(YANG_DEFAULT, kw);
399 assert_int_equal(7, len);
400 str = "description ";
401 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
402 assert_int_equal(YANG_DESCRIPTION, kw);
403 assert_int_equal(11, len);
404 str = "deviate ";
405 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
406 assert_int_equal(YANG_DEVIATE, kw);
407 assert_int_equal(7, len);
408 str = "deviation ";
409 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
410 assert_int_equal(YANG_DEVIATION, kw);
411 assert_int_equal(9, len);
412 str = "enum ";
413 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
414 assert_int_equal(YANG_ENUM, kw);
415 assert_int_equal(4, len);
416 str = "error-app-tag ";
417 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
418 assert_int_equal(YANG_ERROR_APP_TAG, kw);
419 assert_int_equal(13, len);
420 str = "error-message ";
421 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
422 assert_int_equal(YANG_ERROR_MESSAGE, kw);
423 assert_int_equal(13, len);
424 str = "extension ";
425 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
426 assert_int_equal(YANG_EXTENSION, kw);
427 assert_int_equal(9, len);
428 str = "feature ";
429 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
430 assert_int_equal(YANG_FEATURE, kw);
431 assert_int_equal(7, len);
432 str = "fraction-digits ";
433 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
434 assert_int_equal(YANG_FRACTION_DIGITS, kw);
435 assert_int_equal(15, len);
436 str = "grouping ";
437 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
438 assert_int_equal(YANG_GROUPING, kw);
439 assert_int_equal(8, len);
440 str = "identity ";
441 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
442 assert_int_equal(YANG_IDENTITY, kw);
443 assert_int_equal(8, len);
444 str = "if-feature ";
445 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
446 assert_int_equal(YANG_IF_FEATURE, kw);
447 assert_int_equal(10, len);
448 str = "import ";
449 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
450 assert_int_equal(YANG_IMPORT, kw);
451 assert_int_equal(6, len);
452 str = "include ";
453 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
454 assert_int_equal(YANG_INCLUDE, kw);
455 assert_int_equal(7, len);
456 str = "input{";
457 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
458 assert_int_equal(YANG_INPUT, kw);
459 assert_int_equal(5, len);
460 str = "key ";
461 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
462 assert_int_equal(YANG_KEY, kw);
463 assert_int_equal(3, len);
464 str = "leaf ";
465 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
466 assert_int_equal(YANG_LEAF, kw);
467 assert_int_equal(4, len);
468 str = "leaf-list ";
469 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
470 assert_int_equal(YANG_LEAF_LIST, kw);
471 assert_int_equal(9, len);
472 str = "length ";
473 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
474 assert_int_equal(YANG_LENGTH, kw);
475 assert_int_equal(6, len);
476 str = "list ";
477 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
478 assert_int_equal(YANG_LIST, kw);
479 assert_int_equal(4, len);
480 str = "mandatory ";
481 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
482 assert_int_equal(YANG_MANDATORY, kw);
483 assert_int_equal(9, len);
484 str = "max-elements ";
485 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
486 assert_int_equal(YANG_MAX_ELEMENTS, kw);
487 assert_int_equal(12, len);
488 str = "min-elements ";
489 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
490 assert_int_equal(YANG_MIN_ELEMENTS, kw);
491 assert_int_equal(12, len);
492 str = "modifier ";
493 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
494 assert_int_equal(YANG_MODIFIER, kw);
495 assert_int_equal(8, len);
496 str = "module ";
497 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
498 assert_int_equal(YANG_MODULE, kw);
499 assert_int_equal(6, len);
500 str = "must ";
501 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
502 assert_int_equal(YANG_MUST, kw);
503 assert_int_equal(4, len);
504 str = "namespace ";
505 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
506 assert_int_equal(YANG_NAMESPACE, kw);
507 assert_int_equal(9, len);
508 str = "notification ";
509 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
510 assert_int_equal(YANG_NOTIFICATION, kw);
511 assert_int_equal(12, len);
512 str = "ordered-by ";
513 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
514 assert_int_equal(YANG_ORDERED_BY, kw);
515 assert_int_equal(10, len);
516 str = "organization ";
517 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
518 assert_int_equal(YANG_ORGANIZATION, kw);
519 assert_int_equal(12, len);
520 str = "output ";
521 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
522 assert_int_equal(YANG_OUTPUT, kw);
523 assert_int_equal(6, len);
524 str = "path ";
525 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
526 assert_int_equal(YANG_PATH, kw);
527 assert_int_equal(4, len);
528 str = "pattern ";
529 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
530 assert_int_equal(YANG_PATTERN, kw);
531 assert_int_equal(7, len);
532 str = "position ";
533 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
534 assert_int_equal(YANG_POSITION, kw);
535 assert_int_equal(8, len);
536 str = "prefix ";
537 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
538 assert_int_equal(YANG_PREFIX, kw);
539 assert_int_equal(6, len);
540 str = "presence ";
541 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
542 assert_int_equal(YANG_PRESENCE, kw);
543 assert_int_equal(8, len);
544 str = "range ";
545 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
546 assert_int_equal(YANG_RANGE, kw);
547 assert_int_equal(5, len);
548 str = "reference ";
549 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
550 assert_int_equal(YANG_REFERENCE, kw);
551 assert_int_equal(9, len);
552 str = "refine ";
553 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
554 assert_int_equal(YANG_REFINE, kw);
555 assert_int_equal(6, len);
556 str = "require-instance ";
557 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
558 assert_int_equal(YANG_REQUIRE_INSTANCE, kw);
559 assert_int_equal(16, len);
560 str = "revision ";
561 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
562 assert_int_equal(YANG_REVISION, kw);
563 assert_int_equal(8, len);
564 str = "revision-date ";
565 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
566 assert_int_equal(YANG_REVISION_DATE, kw);
567 assert_int_equal(13, len);
568 str = "rpc ";
569 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
570 assert_int_equal(YANG_RPC, kw);
571 assert_int_equal(3, len);
572 str = "status ";
573 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
574 assert_int_equal(YANG_STATUS, kw);
575 assert_int_equal(6, len);
576 str = "submodule ";
577 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
578 assert_int_equal(YANG_SUBMODULE, kw);
579 assert_int_equal(9, len);
580 str = "type ";
581 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
582 assert_int_equal(YANG_TYPE, kw);
583 assert_int_equal(4, len);
584 str = "typedef ";
585 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
586 assert_int_equal(YANG_TYPEDEF, kw);
587 assert_int_equal(7, len);
588 str = "unique ";
589 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
590 assert_int_equal(YANG_UNIQUE, kw);
591 assert_int_equal(6, len);
592 str = "units ";
593 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
594 assert_int_equal(YANG_UNITS, kw);
595 assert_int_equal(5, len);
596 str = "uses ";
597 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
598 assert_int_equal(YANG_USES, kw);
599 assert_int_equal(4, len);
600 str = "value ";
601 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
602 assert_int_equal(YANG_VALUE, kw);
603 assert_int_equal(5, len);
604 str = "when ";
605 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
606 assert_int_equal(YANG_WHEN, kw);
607 assert_int_equal(4, len);
608 str = "yang-version ";
609 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
610 assert_int_equal(YANG_YANG_VERSION, kw);
611 assert_int_equal(12, len);
612 str = "yin-element ";
613 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
614 assert_int_equal(YANG_YIN_ELEMENT, kw);
615 assert_int_equal(11, len);
Radek Krejci626df482018-10-11 15:06:31 +0200616 str = ";config false;";
617 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
618 assert_int_equal(YANG_SEMICOLON, kw);
619 assert_int_equal(1, len);
620 assert_string_equal("config false;", str);
621 str = "{ config false;";
622 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
623 assert_int_equal(YANG_LEFT_BRACE, kw);
624 assert_int_equal(1, len);
625 assert_string_equal(" config false;", str);
626 str = "}";
627 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
628 assert_int_equal(YANG_RIGHT_BRACE, kw);
629 assert_int_equal(1, len);
630 assert_string_equal("", str);
Radek Krejcidcc7b322018-10-11 14:24:02 +0200631
632 /* geenric extension */
633 str = p = "nacm:default-deny-write;";
634 assert_int_equal(LY_SUCCESS, get_keyword(&ctx, &str, &kw, &word, &len));
635 assert_int_equal(YANG_CUSTOM, kw);
636 assert_int_equal(23, len);
637 assert_ptr_equal(p, word);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200638}
Radek Krejci44ceedc2018-10-02 15:54:31 +0200639
Radek Krejci9fcacc12018-10-11 15:59:11 +0200640static struct lysp_module *
Radek Krejci09306362018-10-15 15:26:01 +0200641mod_renew(struct ly_parser_ctx *ctx, struct lysp_module *mod, uint8_t submodule)
Radek Krejci9fcacc12018-10-11 15:59:11 +0200642{
643 lysp_module_free(mod);
644 mod = calloc(1, sizeof *mod);
645 mod->ctx = ctx->ctx;
Radek Krejci09306362018-10-15 15:26:01 +0200646 mod->submodule = submodule;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200647 assert_non_null(mod);
648 return mod;
649}
650
651static void
652test_module(void **state)
653{
654 (void) state; /* unused */
655
656 struct ly_parser_ctx ctx;
657 struct lysp_module *mod;
658 const char *str;
659
660 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
661 assert_non_null(ctx.ctx);
662 ctx.line = 1;
Radek Krejcia042ea12018-10-13 07:52:15 +0200663 ctx.indent = 0;
Radek Krejci9fcacc12018-10-11 15:59:11 +0200664
Radek Krejci09306362018-10-15 15:26:01 +0200665 mod = mod_renew(&ctx, NULL, 0);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200666
667 /* missing mandatory substatements */
668 str = " name {}";
669 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
670 assert_string_equal("name", mod->name);
671 logbuf_assert("Missing mandatory keyword \"namespace\" as a child of \"module\". Line number 1.");
Radek Krejci09306362018-10-15 15:26:01 +0200672 mod = mod_renew(&ctx, mod, 0);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200673
674 str = " name {namespace urn:x;}";
675 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
676 assert_string_equal("urn:x", mod->ns);
677 logbuf_assert("Missing mandatory keyword \"prefix\" as a child of \"module\". Line number 1.");
Radek Krejci09306362018-10-15 15:26:01 +0200678 mod = mod_renew(&ctx, mod, 0);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200679
680 str = " name {namespace urn:x;prefix \"x\";}";
681 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod));
682 assert_string_equal("x", mod->prefix);
Radek Krejci09306362018-10-15 15:26:01 +0200683 mod = mod_renew(&ctx, mod, 0);
Radek Krejci9fcacc12018-10-11 15:59:11 +0200684
Radek Krejcia042ea12018-10-13 07:52:15 +0200685#define SCHEMA_BEGINNING " name {namespace urn:x;prefix \"x\";"
686#define TEST_NODE(NODETYPE, INPUT, NAME) \
687 str = SCHEMA_BEGINNING INPUT; \
688 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod)); \
689 assert_non_null(mod->data); \
690 assert_int_equal(NODETYPE, mod->data->nodetype); \
691 assert_string_equal(NAME, mod->data->name); \
Radek Krejci09306362018-10-15 15:26:01 +0200692 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200693#define TEST_GENERIC(INPUT, TARGET, TEST) \
694 str = SCHEMA_BEGINNING INPUT; \
695 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod)); \
696 assert_non_null(TARGET); \
697 TEST; \
Radek Krejci09306362018-10-15 15:26:01 +0200698 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200699
700 /* duplicated namespace, prefix */
701 str = SCHEMA_BEGINNING "namespace y;}";
702 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
703 logbuf_assert("Duplicate keyword \"namespace\". Line number 1.");
Radek Krejci09306362018-10-15 15:26:01 +0200704 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200705 str = SCHEMA_BEGINNING "prefix y;}";
706 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
707 logbuf_assert("Duplicate keyword \"prefix\". Line number 1.");
Radek Krejci09306362018-10-15 15:26:01 +0200708 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200709
Radek Krejci70853c52018-10-15 14:46:16 +0200710 /* not allowed in module (submodule-specific) */
711 str = SCHEMA_BEGINNING "belongs-to master {prefix m;}}";
712 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
713 logbuf_assert("Invalid keyword \"belongs-to\" as a child of \"module\". Line number 1.");
Radek Krejci09306362018-10-15 15:26:01 +0200714 mod = mod_renew(&ctx, mod, 0);
Radek Krejci70853c52018-10-15 14:46:16 +0200715
Radek Krejcia042ea12018-10-13 07:52:15 +0200716 /* anydata */
717 TEST_NODE(LYS_ANYDATA, "anydata test;}", "test");
718 /* anyxml */
719 TEST_NODE(LYS_ANYXML, "anyxml test;}", "test");
720 /* augment */
721 TEST_GENERIC("augment /somepath;}", mod->augments,
722 assert_string_equal("/somepath", mod->augments[0].nodeid));
723 /* choice */
724 TEST_NODE(LYS_CHOICE, "choice test;}", "test");
725 /* contact 0..1 */
726 TEST_GENERIC("contact \"firstname\" + \n\t\" surname\";}", mod->contact,
727 assert_string_equal("firstname surname", mod->contact));
728 /* container */
729 TEST_NODE(LYS_CONTAINER, "container test;}", "test");
730 /* description 0..1 */
731 TEST_GENERIC("description \'some description\';}", mod->dsc,
732 assert_string_equal("some description", mod->dsc));
733 /* deviation */
734 TEST_GENERIC("deviation /somepath {deviate not-supported;}}", mod->deviations,
735 assert_string_equal("/somepath", mod->deviations[0].nodeid));
736 /* extension */
737 TEST_GENERIC("extension test;}", mod->extensions,
738 assert_string_equal("test", mod->extensions[0].name));
739 /* feature */
740 TEST_GENERIC("feature test;}", mod->features,
741 assert_string_equal("test", mod->features[0].name));
742 /* grouping */
743 TEST_GENERIC("grouping grp;}", mod->groupings,
744 assert_string_equal("grp", mod->groupings[0].name));
745 /* identity */
746 TEST_GENERIC("identity test;}", mod->identities,
747 assert_string_equal("test", mod->identities[0].name));
748 /* import */
749 TEST_GENERIC("import test {prefix z;}}", mod->imports,
750 assert_string_equal("test", mod->imports[0].name));
Radek Krejci70853c52018-10-15 14:46:16 +0200751
Radek Krejcia042ea12018-10-13 07:52:15 +0200752 /* import - prefix collision */
753 str = SCHEMA_BEGINNING "import test {prefix x;}}";
754 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
Radek Krejci70853c52018-10-15 14:46:16 +0200755 logbuf_assert("Prefix \"x\" already used as module prefix. Line number 2.");
Radek Krejci09306362018-10-15 15:26:01 +0200756 mod = mod_renew(&ctx, mod, 0);
Radek Krejci70853c52018-10-15 14:46:16 +0200757
Radek Krejcia042ea12018-10-13 07:52:15 +0200758 /* include */
Radek Krejci469f70d2018-10-15 15:27:29 +0200759 TEST_GENERIC("include test;}", mod->includes,
760 assert_string_equal("test", mod->includes[0].name));
Radek Krejcia042ea12018-10-13 07:52:15 +0200761 /* leaf */
762 TEST_NODE(LYS_LEAF, "leaf test {type string;}}", "test");
763 /* leaf-list */
764 TEST_NODE(LYS_LEAFLIST, "leaf-list test {type string;}}", "test");
765 /* list */
766 TEST_NODE(LYS_LIST, "list test {key a;leaf a {type string;}}}", "test");
767 /* notification */
768 TEST_GENERIC("notification test;}", mod->notifs,
769 assert_string_equal("test", mod->notifs[0].name));
770 /* organization 0..1 */
771 TEST_GENERIC("organization \"CESNET a.l.e.\";}", mod->org,
772 assert_string_equal("CESNET a.l.e.", mod->org));
773 /* reference 0..1 */
774 TEST_GENERIC("reference RFC7950;}", mod->ref,
775 assert_string_equal("RFC7950", mod->ref));
776 /* revision */
777 TEST_GENERIC("revision 2018-10-12;}", mod->revs,
778 assert_string_equal("2018-10-12", mod->revs[0].rev));
779 /* rpc */
780 TEST_GENERIC("rpc test;}", mod->rpcs,
781 assert_string_equal("test", mod->rpcs[0].name));
782 /* typedef */
783 TEST_GENERIC("typedef test{type string;}}", mod->typedefs,
784 assert_string_equal("test", mod->typedefs[0].name));
785 /* uses */
786 TEST_NODE(LYS_USES, "uses test;}", "test");
787 /* yang-version */
788 str = SCHEMA_BEGINNING "\n\tyang-version 10;}";
789 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
790 logbuf_assert("Invalid value \"10\" of \"yang-version\". Line number 3.");
Radek Krejci09306362018-10-15 15:26:01 +0200791 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200792 str = SCHEMA_BEGINNING "yang-version 1.0;yang-version 1.1;}";
793 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
794 logbuf_assert("Duplicate keyword \"yang-version\". Line number 3.");
Radek Krejci09306362018-10-15 15:26:01 +0200795 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200796 str = SCHEMA_BEGINNING "yang-version 1.0;}";
797 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod));
798 assert_int_equal(1, mod->version);
Radek Krejci09306362018-10-15 15:26:01 +0200799 mod = mod_renew(&ctx, mod, 0);
Radek Krejcia042ea12018-10-13 07:52:15 +0200800 str = SCHEMA_BEGINNING "yang-version \"1.1\";}";
801 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod));
802 assert_int_equal(2, mod->version);
Radek Krejci09306362018-10-15 15:26:01 +0200803 mod = mod_renew(&ctx, mod, 0);
804
Radek Krejci156ccaf2018-10-15 15:49:17 +0200805 /* extensions */
806 TEST_GENERIC("prefix:test;}", mod->exts,
807 assert_string_equal("prefix:test", mod->exts[0].name);
808 assert_int_equal(LYEXT_SUBSTMT_SELF, mod->exts[0].insubstmt));
809 mod = mod_renew(&ctx, mod, 0);
810
Radek Krejci09306362018-10-15 15:26:01 +0200811 /* submodule */
812 mod->submodule = 1;
813
814 /* missing mandatory substatements */
815 str = " subname {}";
816 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
817 assert_string_equal("subname", mod->name);
818 logbuf_assert("Missing mandatory keyword \"belongs-to\" as a child of \"submodule\". Line number 3.");
819 mod = mod_renew(&ctx, mod, 1);
820
821 str = " subname {belongs-to name;}";
822 assert_int_equal(LY_SUCCESS, parse_sub_module(&ctx, &str, mod));
823 assert_string_equal("name", mod->belongsto);
824 mod = mod_renew(&ctx, mod, 1);
825
826#undef SCHEMA_BEGINNING
827#define SCHEMA_BEGINNING " subname {belongs-to name;"
828
829 /* duplicated namespace, prefix */
830 str = SCHEMA_BEGINNING "belongs-to othermodule;}";
831 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
832 logbuf_assert("Duplicate keyword \"belongs-to\". Line number 3.");
833 mod = mod_renew(&ctx, mod, 1);
834
835 /* not allowed in submodule (module-specific) */
836 str = SCHEMA_BEGINNING "namespace \"urn:z\";}";
837 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
838 logbuf_assert("Invalid keyword \"namespace\" as a child of \"submodule\". Line number 3.");
839 mod = mod_renew(&ctx, mod, 1);
840 str = SCHEMA_BEGINNING "prefix m;}}";
841 assert_int_equal(LY_EVALID, parse_sub_module(&ctx, &str, mod));
842 logbuf_assert("Invalid keyword \"prefix\" as a child of \"submodule\". Line number 3.");
843 mod = mod_renew(&ctx, mod, 1);
Radek Krejcia042ea12018-10-13 07:52:15 +0200844
845#undef TEST_GENERIC
846#undef TEST_NODE
847#undef SCHEMA_BEGINNING
848
Radek Krejci9fcacc12018-10-11 15:59:11 +0200849 lysp_module_free(mod);
850 ly_ctx_destroy(ctx.ctx, NULL);
Radek Krejciefd22f62018-09-27 11:47:58 +0200851}
852
Radek Krejci4c6d9bd2018-10-15 16:43:06 +0200853static void
854test_identity(void **state)
855{
856 (void) state; /* unused */
857
858 struct ly_parser_ctx ctx;
859 struct lysp_ident *ident = NULL;
860 const char *str;
861 unsigned int u;
862
863 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx.ctx));
864 assert_non_null(ctx.ctx);
865 ctx.line = 1;
866 ctx.indent = 0;
867
868 /* invalid cardinality */
869#define TEST_DUP(MEMBER, VALUE1, VALUE2) \
870 str = " test {"MEMBER" "VALUE1";"MEMBER" "VALUE2";} ..."; \
871 assert_int_equal(LY_EVALID, parse_identity(&ctx, &str, &ident)); \
872 logbuf_assert("Duplicate keyword \""MEMBER"\". Line number 1."); \
873 FREE_ARRAY(ctx.ctx, ident, u, lysp_ident_free); \
874 ident = NULL;
875
876 TEST_DUP("description", "a", "b");
877 TEST_DUP("reference", "a", "b");
878 TEST_DUP("status", "current", "obsolete");
879
880 /* full identity */
881 str = " test {base \"a\";base b; description text;reference \'another text\';status current; if-feature x;if-feature y;} ...";
882 assert_int_equal(LY_SUCCESS, parse_identity(&ctx, &str, &ident));
883 assert_non_null(ident);
884 assert_string_equal(" ...", str);
885 FREE_ARRAY(ctx.ctx, ident, u, lysp_ident_free);
886
887 ly_ctx_destroy(ctx.ctx, NULL);
888}
889
Radek Krejci80dd33e2018-09-26 15:57:18 +0200890int main(void)
891{
892 const struct CMUnitTest tests[] = {
Radek Krejci44ceedc2018-10-02 15:54:31 +0200893 cmocka_unit_test_setup(test_helpers, logger_setup),
Radek Krejci80dd33e2018-09-26 15:57:18 +0200894 cmocka_unit_test_setup(test_comments, logger_setup),
Radek Krejciefd22f62018-09-27 11:47:58 +0200895 cmocka_unit_test_setup(test_arg, logger_setup),
Radek Krejcidcc7b322018-10-11 14:24:02 +0200896 cmocka_unit_test_setup(test_stmts, logger_setup),
Radek Krejci9fcacc12018-10-11 15:59:11 +0200897 cmocka_unit_test_setup(test_module, logger_setup),
Radek Krejci4c6d9bd2018-10-15 16:43:06 +0200898 cmocka_unit_test_setup(test_identity, logger_setup),
Radek Krejci80dd33e2018-09-26 15:57:18 +0200899 };
900
901 return cmocka_run_group_tests(tests, NULL, NULL);
902}