blob: f66deb28ebf8bb6671e73783a6799e7d3f5722c7 [file] [log] [blame]
Radek Krejci3a4889a2020-05-19 17:01:58 +02001/*
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_schema_common.c
Radek Krejci3a4889a2020-05-19 17:01:58 +02003 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from common.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 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#include "test_schema.h"
Radek Krejci3a4889a2020-05-19 17:01:58 +020015
Radek Krejci3a4889a2020-05-19 17:01:58 +020016#include <string.h>
17
Radek Krejci8297b792020-08-16 14:49:05 +020018#include "compat.h"
Radek Krejci18abde42020-06-13 20:04:39 +020019#include "context.h"
20#include "log.h"
Radek Krejci859a15a2021-03-05 20:56:59 +010021#include "tree_edit.h"
Radek Krejci18abde42020-06-13 20:04:39 +020022#include "tree_schema.h"
23#include "tree_schema_internal.h"
Radek Krejci18abde42020-06-13 20:04:39 +020024
aPiecek4f49a142021-06-29 15:32:39 +020025struct module_clb_list {
26 const char *name;
27 const char *data;
28};
29
30static LY_ERR
31module_clb(const char *mod_name, const char *UNUSED(mod_rev), const char *submod_name,
32 const char *UNUSED(sub_rev), void *user_data, LYS_INFORMAT *format,
33 const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
34{
35 struct module_clb_list *list = (struct module_clb_list *)user_data;
36
37 for (unsigned int i = 0; list[i].data; i++) {
38
39 if ((submod_name && !strcmp(list[i].name, submod_name)) ||
40 (!submod_name && mod_name && !strcmp(list[i].name, mod_name))) {
41 *module_data = list[i].data;
42 *format = LYS_IN_YANG;
43 *free_module_data = NULL;
44 return LY_SUCCESS;
45 }
46 }
47 return LY_EINVAL;
48}
49
Radek Krejci18abde42020-06-13 20:04:39 +020050void
Radek Krejci3a4889a2020-05-19 17:01:58 +020051test_getnext(void **state)
52{
Michal Vasko4de7d072021-07-09 09:13:18 +020053 struct lys_module *mod;
Radek Krejci3a4889a2020-05-19 17:01:58 +020054 const struct lysc_node *node = NULL, *four;
55 const struct lysc_node_container *cont;
56 const struct lysc_action *rpc;
57
Radek Iša56ca9e42020-09-08 18:42:00 +020058 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module a {yang-version 1.1; namespace urn:a;prefix a;"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010059 "container a { container one {presence test;} leaf two {type string;} leaf-list three {type string;}"
60 " list four {config false;} choice x { leaf five {type string;} case y {leaf six {type string;}}}"
61 " anyxml seven; action eight {input {leaf eight-input {type string;}} output {leaf eight-output {type string;}}}"
62 " notification nine {leaf nine-data {type string;}}}"
63 "leaf b {type string;} leaf-list c {type string;} list d {config false;}"
64 "choice x { case empty-x { choice empty-xc { case nothing;}} leaf e {type string;} case y {leaf f {type string;}}} anyxml g;"
65 "rpc h {input {leaf h-input {type string;}} output {leaf h-output {type string;}}}"
66 "rpc i;"
67 "notification j {leaf i-data {type string;}}"
68 "notification k;}", LYS_IN_YANG, &mod));
Radek Krejci3a4889a2020-05-19 17:01:58 +020069 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
70 assert_string_equal("a", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010071 cont = (const struct lysc_node_container *)node;
Radek Krejci3a4889a2020-05-19 17:01:58 +020072 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
73 assert_string_equal("b", node->name);
74 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
75 assert_string_equal("c", node->name);
76 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
77 assert_string_equal("d", node->name);
78 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
79 assert_string_equal("e", node->name);
80 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
81 assert_string_equal("f", node->name);
82 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
83 assert_string_equal("g", node->name);
84 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
85 assert_string_equal("h", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010086 rpc = (const struct lysc_action *)node;
Radek Krejci3a4889a2020-05-19 17:01:58 +020087 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
88 assert_string_equal("i", node->name);
89 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
90 assert_string_equal("j", node->name);
91 assert_non_null(node = lys_getnext(node, NULL, mod->compiled, 0));
92 assert_string_equal("k", node->name);
93 assert_null(node = lys_getnext(node, NULL, mod->compiled, 0));
94 /* Inside container */
Radek Krejcib4ac5a92020-11-23 17:54:33 +010095 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +020096 assert_string_equal("one", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010097 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +020098 assert_string_equal("two", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010099 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200100 assert_string_equal("three", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100101 assert_non_null(node = four = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200102 assert_string_equal("four", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100103 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200104 assert_string_equal("five", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100105 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200106 assert_string_equal("six", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100107 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200108 assert_string_equal("seven", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100109 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200110 assert_string_equal("eight", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100111 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200112 assert_string_equal("nine", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100113 assert_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200114 /* Inside RPC */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100115 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)rpc, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200116 assert_string_equal("h-input", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100117 assert_null(node = lys_getnext(node, (const struct lysc_node *)rpc, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200118
119 /* options */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100120 assert_non_null(node = lys_getnext(four, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200121 assert_string_equal("x", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100122 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_WITHCHOICE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200123 assert_string_equal("seven", node->name);
124
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100125 assert_non_null(node = lys_getnext(four, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_NOCHOICE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200126 assert_string_equal("seven", node->name);
127
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100128 assert_non_null(node = lys_getnext(four, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200129 assert_string_equal("five", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100130 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200131 assert_string_equal("y", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100132 assert_non_null(node = lys_getnext(node, (const struct lysc_node *)cont, mod->compiled, LYS_GETNEXT_WITHCASE));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200133 assert_string_equal("seven", node->name);
134
135 assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_INTONPCONT));
136 assert_string_equal("one", node->name);
137
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100138 assert_non_null(node = lys_getnext(NULL, (const struct lysc_node *)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200139 assert_string_equal("h-output", node->name);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100140 assert_null(node = lys_getnext(node, (const struct lysc_node *)rpc, mod->compiled, LYS_GETNEXT_OUTPUT));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200141
Radek Iša56ca9e42020-09-08 18:42:00 +0200142 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module c {namespace urn:c;prefix c; rpc c;}", LYS_IN_YANG, &mod));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200143 assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
144 assert_string_equal("c", node->name);
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100145 assert_null(node = lys_getnext(node, NULL, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200146
Radek Iša56ca9e42020-09-08 18:42:00 +0200147 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module d {namespace urn:d;prefix d; notification d;}", LYS_IN_YANG, &mod));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200148 assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
149 assert_string_equal("d", node->name);
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100150 assert_null(node = lys_getnext(node, NULL, mod->compiled, 0));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200151
Radek Iša56ca9e42020-09-08 18:42:00 +0200152 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, "module e {namespace urn:e;prefix e; container c {container cc;} leaf a {type string;}}", LYS_IN_YANG, &mod));
Radek Krejcib93bd412020-11-02 13:23:11 +0100153 assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, 0));
154 assert_string_equal("c", node->name);
155 assert_non_null(node = lys_getnext(NULL, NULL, mod->compiled, LYS_GETNEXT_INTONPCONT));
156 assert_string_equal("a", node->name);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200157}
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100158
Radek Krejci18abde42020-06-13 20:04:39 +0200159void
Radek Krejci3a4889a2020-05-19 17:01:58 +0200160test_date(void **state)
161{
Radek Krejci3a4889a2020-05-19 17:01:58 +0200162 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, NULL, 0, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200163 CHECK_LOG("Invalid argument date (lysp_check_date()).", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200164 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "x", 1, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200165 CHECK_LOG("Invalid argument date_len (lysp_check_date()).", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200166 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "nonsencexx", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200167 CHECK_LOG("Invalid value \"nonsencexx\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200168 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "123x-11-11", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200169 CHECK_LOG("Invalid value \"123x-11-11\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200170 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-13-11", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200171 CHECK_LOG("Invalid value \"2018-13-11\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200172 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-11-41", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200173 CHECK_LOG("Invalid value \"2018-11-41\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200174 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02-29", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200175 CHECK_LOG("Invalid value \"2018-02-29\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200176 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018.02-28", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200177 CHECK_LOG("Invalid value \"2018.02-28\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200178 assert_int_equal(LY_EINVAL, lysp_check_date(NULL, "2018-02.28", 10, "date"));
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 CHECK_LOG("Invalid value \"2018-02.28\" of \"date\".", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200180
181 assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-11-11", 10, "date"));
182 assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2018-02-28", 10, "date"));
183 assert_int_equal(LY_SUCCESS, lysp_check_date(NULL, "2016-02-29", 10, "date"));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200184}
185
Radek Krejci18abde42020-06-13 20:04:39 +0200186void
Radek Krejci3a4889a2020-05-19 17:01:58 +0200187test_revisions(void **state)
188{
Radek Krejci3a4889a2020-05-19 17:01:58 +0200189 struct lysp_revision *revs = NULL, *rev;
190
Radek Krejci3a4889a2020-05-19 17:01:58 +0200191 /* no error, it just does nothing */
192 lysp_sort_revisions(NULL);
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 CHECK_LOG(NULL, NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200194
195 /* revisions are stored in wrong order - the newest is the last */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100196 LY_ARRAY_NEW_RET(NULL, revs, rev, );
Radek Krejci3a4889a2020-05-19 17:01:58 +0200197 strcpy(rev->date, "2018-01-01");
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100198 LY_ARRAY_NEW_RET(NULL, revs, rev, );
Radek Krejci3a4889a2020-05-19 17:01:58 +0200199 strcpy(rev->date, "2018-12-31");
200
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200201 assert_int_equal(2, LY_ARRAY_COUNT(revs));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200202 assert_string_equal("2018-01-01", &revs[0]);
203 assert_string_equal("2018-12-31", &revs[1]);
204 /* the order should be fixed, so the newest revision will be the first in the array */
205 lysp_sort_revisions(revs);
206 assert_string_equal("2018-12-31", &revs[0]);
207 assert_string_equal("2018-01-01", &revs[1]);
208
209 LY_ARRAY_FREE(revs);
210}
211
Radek Krejci18abde42020-06-13 20:04:39 +0200212void
aPiecek4f49a142021-06-29 15:32:39 +0200213test_collision_typedef(void **state)
Radek Krejci3a4889a2020-05-19 17:01:58 +0200214{
Radek Krejci3a4889a2020-05-19 17:01:58 +0200215 const char *str;
aPiecek28afeef2021-06-30 07:57:18 +0200216 char *submod;
217 struct module_clb_list list[3] = {0};
218
219 list[0].name = "asub";
220 list[1].name = "bsub";
Radek Krejci3a4889a2020-05-19 17:01:58 +0200221
aPiecek4f49a142021-06-29 15:32:39 +0200222 /* collision with a built-in type */
Radek Krejci3a4889a2020-05-19 17:01:58 +0200223 str = "module a {namespace urn:a; prefix a; typedef binary {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200224 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200225 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
226 "Duplicate identifier \"binary\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200227 str = "module a {namespace urn:a; prefix a; typedef bits {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200228 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200229 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
230 "Duplicate identifier \"bits\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200231 str = "module a {namespace urn:a; prefix a; typedef boolean {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200232 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200233 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
234 "Duplicate identifier \"boolean\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200235 str = "module a {namespace urn:a; prefix a; typedef decimal64 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200236 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200237 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
238 "Duplicate identifier \"decimal64\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200239 str = "module a {namespace urn:a; prefix a; typedef empty {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200240 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200241 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
242 "Duplicate identifier \"empty\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200243 str = "module a {namespace urn:a; prefix a; typedef enumeration {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200244 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200245 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
246 "Duplicate identifier \"enumeration\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200247 str = "module a {namespace urn:a; prefix a; typedef int8 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200248 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200249 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
250 "Duplicate identifier \"int8\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200251 str = "module a {namespace urn:a; prefix a; typedef int16 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200252 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200253 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
254 "Duplicate identifier \"int16\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200255 str = "module a {namespace urn:a; prefix a; typedef int32 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200256 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200257 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
258 "Duplicate identifier \"int32\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200259 str = "module a {namespace urn:a; prefix a; typedef int64 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200260 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200261 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
262 "Duplicate identifier \"int64\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200263 str = "module a {namespace urn:a; prefix a; typedef instance-identifier {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200264 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200265 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
266 "Duplicate identifier \"instance-identifier\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200267 str = "module a {namespace urn:a; prefix a; typedef identityref {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200268 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200269 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
270 "Duplicate identifier \"identityref\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200271 str = "module a {namespace urn:a; prefix a; typedef leafref {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200272 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200273 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
274 "Duplicate identifier \"leafref\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200275 str = "module a {namespace urn:a; prefix a; typedef string {type int8;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200276 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200277 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
278 "Duplicate identifier \"string\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200279 str = "module a {namespace urn:a; prefix a; typedef union {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200280 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200281 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
282 "Duplicate identifier \"union\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200283 str = "module a {namespace urn:a; prefix a; typedef uint8 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200284 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200285 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
286 "Duplicate identifier \"uint8\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200287 str = "module a {namespace urn:a; prefix a; typedef uint16 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200288 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200289 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
290 "Duplicate identifier \"uint16\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200291 str = "module a {namespace urn:a; prefix a; typedef uint32 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200292 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200293 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
294 "Duplicate identifier \"uint32\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200295 str = "module a {namespace urn:a; prefix a; typedef uint64 {type string;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200296 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200297 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
298 "Duplicate identifier \"uint64\" of typedef statement - name collision with a built-in type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200299
300 str = "module mytypes {namespace urn:types; prefix t; typedef binary_ {type string;} typedef bits_ {type string;} typedef boolean_ {type string;} "
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100301 "typedef decimal64_ {type string;} typedef empty_ {type string;} typedef enumeration_ {type string;} typedef int8_ {type string;} typedef int16_ {type string;}"
302 "typedef int32_ {type string;} typedef int64_ {type string;} typedef instance-identifier_ {type string;} typedef identityref_ {type string;}"
303 "typedef leafref_ {type string;} typedef string_ {type int8;} typedef union_ {type string;} typedef uint8_ {type string;} typedef uint16_ {type string;}"
304 "typedef uint32_ {type string;} typedef uint64_ {type string;}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200305 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200306
aPiecek4f49a142021-06-29 15:32:39 +0200307 /* collision in node's scope */
Radek Krejci3a4889a2020-05-19 17:01:58 +0200308 str = "module a {namespace urn:a; prefix a; container c {typedef y {type int8;} typedef y {type string;}}}";
aPiecekc7594b72021-06-29 09:00:03 +0200309 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200310 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
311 "Duplicate identifier \"y\" of typedef statement - name collision with sibling type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200312
aPiecek4f49a142021-06-29 15:32:39 +0200313 /* collision with parent node */
314 str = "module a {namespace urn:a; prefix a; container c {container d {typedef y {type int8;}} typedef y {type string;}}}";
aPiecek8d4e75d2021-06-24 14:47:06 +0200315 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200316 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
317 "Duplicate identifier \"y\" of typedef statement - name collision with another scoped type.", NULL);
aPiecek8d4e75d2021-06-24 14:47:06 +0200318
aPiecek4f49a142021-06-29 15:32:39 +0200319 /* collision with module's top-level */
320 str = "module a {namespace urn:a; prefix a; typedef x {type string;} container c {typedef x {type int8;}}}";
aPiecekc7594b72021-06-29 09:00:03 +0200321 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200322 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
323 "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200324
aPiecek4f49a142021-06-29 15:32:39 +0200325 /* collision of submodule's node with module's top-level */
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} container c {typedef x {type string;}}}");
Radek Krejci3a4889a2020-05-19 17:01:58 +0200327 str = "module a {namespace urn:a; prefix a; include b; typedef x {type int8;}}";
aPiecekc7594b72021-06-29 09:00:03 +0200328 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200329 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
330 "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL);
Radek Krejci3a4889a2020-05-19 17:01:58 +0200331
aPiecek4f49a142021-06-29 15:32:39 +0200332 /* collision of module's node with submodule's top-level */
Radek Iša56ca9e42020-09-08 18:42:00 +0200333 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} typedef x {type int8;}}");
Radek Krejci3a4889a2020-05-19 17:01:58 +0200334 str = "module a {namespace urn:a; prefix a; include b; container c {typedef x {type string;}}}";
aPiecekc7594b72021-06-29 09:00:03 +0200335 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200336 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
337 "Duplicate identifier \"x\" of typedef statement - scoped type collide with a top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200338
339 /* collision of submodule's node with another submodule's top-level */
aPiecek28afeef2021-06-30 07:57:18 +0200340 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
341 list[0].data = "submodule asub {belongs-to a {prefix a;} typedef g {type int;}}";
342 list[1].data = "submodule bsub {belongs-to a {prefix a;} container c {typedef g {type int;}}}";
343 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
344 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200345 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
346 "Duplicate identifier \"g\" of typedef statement - scoped type collide with a top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200347
348 /* collision of module's top-levels */
349 str = "module a {namespace urn:a; prefix a; typedef test {type string;} typedef test {type int8;}}";
350 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200351 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
352 "Duplicate identifier \"test\" of typedef statement - name collision with another top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200353
354 /* collision of submodule's top-levels */
aPiecek28afeef2021-06-30 07:57:18 +0200355 submod = "submodule asub {belongs-to a {prefix a;} typedef g {type int;} typedef g {type int;}}";
356 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}";
357 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
358 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200359 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
360 "Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200361
362 /* collision of module's top-level with submodule's top-levels */
363 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} typedef x {type string;}}");
364 str = "module a {namespace urn:a; prefix a; include b; typedef x {type int8;}}";
365 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200366 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
367 "Duplicate identifier \"x\" of typedef statement - name collision with another top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200368
369 /* collision of submodule's top-level with another submodule's top-levels */
aPiecek28afeef2021-06-30 07:57:18 +0200370 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
371 list[0].data = "submodule asub {belongs-to a {prefix a;} typedef g {type int;}}";
372 list[1].data = "submodule bsub {belongs-to a {prefix a;} typedef g {type int;}}";
373 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
374 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200375 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
376 "Duplicate identifier \"g\" of typedef statement - name collision with another top-level type.", NULL);
aPiecek4f49a142021-06-29 15:32:39 +0200377
378 /* error in type-stmt */
379 str = "module a {namespace urn:a; prefix a; container c {typedef x {type t{}}";
380 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200381 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
382 "Unexpected end-of-input.", "Line number 1.");
aPiecek4f49a142021-06-29 15:32:39 +0200383 UTEST_LOG_CLEAN;
384
385 /* no collision if the same names are in different scope */
aPiecek28afeef2021-06-30 07:57:18 +0200386 str = "module a {yang-version 1.1; namespace urn:a; prefix a;"
387 "container c {typedef g {type int;}} container d {typedef g {type int;}}}";
388 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci3a4889a2020-05-19 17:01:58 +0200389}
Michal Vasko6b26e742020-07-17 15:02:10 +0200390
391void
aPiecek0b365612021-06-30 13:12:58 +0200392test_collision_grouping(void **state)
393{
394 const char *str;
395 char *submod;
396 struct module_clb_list list[3] = {0};
397
398 list[0].name = "asub";
399 list[1].name = "bsub";
400
401 /* collision in node's scope */
402 str = "module a {namespace urn:a; prefix a; container c {grouping y; grouping y;}}";
403 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200404 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
405 "Duplicate identifier \"y\" of grouping statement - name collision with sibling grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200406
407 /* collision with parent node */
408 str = "module a {namespace urn:a; prefix a; container c {container d {grouping y;} grouping y;}}";
409 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200410 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
411 "Duplicate identifier \"y\" of grouping statement - name collision with another scoped grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200412
413 /* collision with module's top-level */
414 str = "module a {namespace urn:a; prefix a; grouping x; container c {grouping x;}}";
415 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200416 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
417 "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200418
419 /* collision of submodule's node with module's top-level */
420 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} container c {grouping x;}}");
421 str = "module a {namespace urn:a; prefix a; include b; grouping x;}";
422 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200423 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
424 "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200425
426 /* collision of module's node with submodule's top-level */
427 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} grouping x;}");
428 str = "module a {namespace urn:a; prefix a; include b; container c {grouping x;}}";
429 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200430 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
431 "Duplicate identifier \"x\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200432
433 /* collision of submodule's node with another submodule's top-level */
434 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
435 list[0].data = "submodule asub {belongs-to a {prefix a;} grouping g;}";
436 list[1].data = "submodule bsub {belongs-to a {prefix a;} container c {grouping g;}}";
437 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
438 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200439 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
440 "Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200441
442 /* collision of module's top-levels */
443 str = "module a {namespace urn:a; prefix a; grouping test; grouping test;}";
444 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200445 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
446 "Duplicate identifier \"test\" of grouping statement - name collision with another top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200447
448 /* collision of submodule's top-levels */
449 submod = "submodule asub {belongs-to a {prefix a;} grouping g; grouping g;}";
450 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}";
451 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
452 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200453 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
454 "Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200455
456 /* collision of module's top-level with submodule's top-levels */
457 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, "submodule b {belongs-to a {prefix a;} grouping x;}");
458 str = "module a {namespace urn:a; prefix a; include b; grouping x;}";
459 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200460 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
461 "Duplicate identifier \"x\" of grouping statement - name collision with another top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200462
463 /* collision of submodule's top-level with another submodule's top-levels */
464 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
465 list[0].data = "submodule asub {belongs-to a {prefix a;} grouping g;}";
466 list[1].data = "submodule bsub {belongs-to a {prefix a;} grouping g;}";
467 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
468 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200469 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
470 "Duplicate identifier \"g\" of grouping statement - name collision with another top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200471
472 /* collision in nested groupings, top-level */
473 str = "module a {namespace urn:a; prefix a; grouping g {grouping g;}}";
474 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200475 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
476 "Duplicate identifier \"g\" of grouping statement - scoped grouping collide with a top-level grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200477
478 /* collision in nested groupings, in node */
479 str = "module a {namespace urn:a; prefix a; container c {grouping g {grouping g;}}}";
480 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Radek Krejci8297b792020-08-16 14:49:05 +0200481 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
482 "Duplicate identifier \"g\" of grouping statement - name collision with another scoped grouping.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200483
484 /* no collision if the same names are in different scope */
485 str = "module a {yang-version 1.1; namespace urn:a; prefix a;"
486 "container c {grouping g;} container d {grouping g;}}";
487 assert_int_equal(LY_SUCCESS, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
488}
489
490void
aPiecek14d07f02021-06-30 09:46:50 +0200491test_collision_identity(void **state)
492{
493 const char *str;
494 char *submod;
aPiecek0b365612021-06-30 13:12:58 +0200495 struct module_clb_list list[3] = {0};
496
497 list[0].name = "asub";
498 list[1].name = "bsub";
aPiecek14d07f02021-06-30 09:46:50 +0200499
500 /* collision of module's top-levels */
501 str = "module a {yang-version 1.1; namespace urn:a; prefix a; identity g; identity g;}";
502 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200503 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
504 "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL);
aPiecek14d07f02021-06-30 09:46:50 +0200505
aPiecek0b365612021-06-30 13:12:58 +0200506 /* collision of submodule's top-levels */
507 submod = "submodule asub {belongs-to a {prefix a;} identity g; identity g;}";
508 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}";
509 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
510 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200511 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
512 "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200513
aPiecek14d07f02021-06-30 09:46:50 +0200514 /* collision of module's top-level with submodule's top-levels */
515 submod = "submodule asub {belongs-to a {prefix a;} identity g;}";
516 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; identity g;}";
517 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
518 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200519 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
520 "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200521
522 /* collision of submodule's top-level with another submodule's top-levels */
523 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
524 list[0].data = "submodule asub {belongs-to a {prefix a;} identity g;}";
525 list[1].data = "submodule bsub {belongs-to a {prefix a;} identity g;}";
526 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
527 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200528 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
529 "Duplicate identifier \"g\" of identity statement - name collision with another top-level identity.", NULL);
aPiecek14d07f02021-06-30 09:46:50 +0200530}
531
532void
533test_collision_feature(void **state)
534{
535 const char *str;
536 char *submod;
aPiecek0b365612021-06-30 13:12:58 +0200537 struct module_clb_list list[3] = {0};
538
539 list[0].name = "asub";
540 list[1].name = "bsub";
aPiecek14d07f02021-06-30 09:46:50 +0200541
542 /* collision of module's top-levels */
543 str = "module a {yang-version 1.1; namespace urn:a; prefix a; feature g; feature g;}";
544 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200545 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
546 "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL);
aPiecek14d07f02021-06-30 09:46:50 +0200547
aPiecek0b365612021-06-30 13:12:58 +0200548 /* collision of submodule's top-levels */
549 submod = "submodule asub {belongs-to a {prefix a;} feature g; feature g;}";
550 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub;}";
551 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
552 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200553 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
554 "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200555
aPiecek14d07f02021-06-30 09:46:50 +0200556 /* collision of module's top-level with submodule's top-levels */
557 submod = "submodule asub {belongs-to a {prefix a;} feature g;}";
558 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; feature g;}";
559 ly_ctx_set_module_imp_clb(UTEST_LYCTX, test_imp_clb, submod);
560 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200561 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
562 "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL);
aPiecek0b365612021-06-30 13:12:58 +0200563
564 /* collision of submodule's top-level with another submodule's top-levels */
565 str = "module a {yang-version 1.1; namespace urn:a; prefix a; include asub; include bsub;}";
566 list[0].data = "submodule asub {belongs-to a {prefix a;} feature g;}";
567 list[1].data = "submodule bsub {belongs-to a {prefix a;} feature g;}";
568 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
569 assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL));
Radek Krejci8297b792020-08-16 14:49:05 +0200570 CHECK_LOG_CTX("Parsing module \"a\" failed.", NULL,
571 "Duplicate identifier \"g\" of feature statement - name collision with another top-level feature.", NULL);
aPiecek14d07f02021-06-30 09:46:50 +0200572}
573
574void
Michal Vasko6b26e742020-07-17 15:02:10 +0200575test_accessible_tree(void **state)
576{
Michal Vasko6b26e742020-07-17 15:02:10 +0200577 const char *str;
578
Michal Vasko6b26e742020-07-17 15:02:10 +0200579 /* config -> config */
Radek Iša56ca9e42020-09-08 18:42:00 +0200580 str = "module a {\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100581 " namespace urn:a;\n"
582 " prefix a;\n"
583 " container cont {\n"
584 " leaf l {\n"
585 " type empty;\n"
586 " }\n"
587 " }\n"
588 " container cont2 {\n"
589 " leaf l2 {\n"
590 " must ../../cont/l;\n"
591 " type leafref {\n"
592 " path /cont/l;\n"
593 " }\n"
594 " }\n"
595 " }\n"
596 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200597 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
598 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200599
600 /* config -> state leafref */
Radek Iša56ca9e42020-09-08 18:42:00 +0200601 str = "module b {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200602 " namespace urn:b;\n"
603 " prefix b;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100604 " container cont {\n"
605 " config false;\n"
606 " leaf l {\n"
607 " type empty;\n"
608 " }\n"
609 " }\n"
610 " container cont2 {\n"
611 " leaf l2 {\n"
612 " type leafref {\n"
613 " path /cont/l;\n"
614 " }\n"
615 " }\n"
616 " }\n"
617 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200618 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
619 CHECK_LOG_CTX("Invalid leafref path \"/cont/l\" - target is supposed to represent configuration data"
Michal Vasko959f8d82022-06-16 07:51:50 +0200620 " (as the leafref does), but it does not.", "Schema location \"/b:cont2/l2\".");
Michal Vasko6b26e742020-07-17 15:02:10 +0200621
622 /* config -> state must */
Radek Iša56ca9e42020-09-08 18:42:00 +0200623 str = "module b {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200624 " namespace urn:b;\n"
625 " prefix b;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100626 " container cont {\n"
627 " config false;\n"
628 " leaf l {\n"
629 " type empty;\n"
630 " }\n"
631 " }\n"
632 " container cont2 {\n"
633 " leaf l2 {\n"
634 " must ../../cont/l;\n"
635 " type empty;\n"
636 " }\n"
637 " }\n"
638 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200639 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
Michal Vaskoa036a6b2021-10-12 16:05:23 +0200640 CHECK_LOG_CTX("Schema node \"cont\" for parent \"<config-root>\" not found; in expr \"../../cont\" "
641 "with context node \"/b:cont2/l2\".", NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200642
643 /* state -> config */
Radek Iša56ca9e42020-09-08 18:42:00 +0200644 str = "module c {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200645 " namespace urn:c;\n"
646 " prefix c;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100647 " container cont {\n"
648 " leaf l {\n"
649 " type empty;\n"
650 " }\n"
651 " }\n"
652 " container cont2 {\n"
653 " config false;\n"
654 " leaf l2 {\n"
655 " must ../../cont/l;\n"
656 " type leafref {\n"
657 " path /cont/l;\n"
658 " }\n"
659 " }\n"
660 " }\n"
661 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200662 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
663 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200664
665 /* notif -> state */
Radek Iša56ca9e42020-09-08 18:42:00 +0200666 str = "module d {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200667 " namespace urn:d;\n"
668 " prefix d;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100669 " container cont {\n"
670 " config false;\n"
671 " leaf l {\n"
672 " type empty;\n"
673 " }\n"
674 " }\n"
675 " notification notif {\n"
676 " leaf l2 {\n"
677 " must ../../cont/l;\n"
678 " type leafref {\n"
679 " path /cont/l;\n"
680 " }\n"
681 " }\n"
682 " }\n"
683 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200684 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
685 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200686
687 /* notif -> notif */
Radek Iša56ca9e42020-09-08 18:42:00 +0200688 str = "module e {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200689 " namespace urn:e;\n"
690 " prefix e;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100691 " notification notif {\n"
692 " leaf l {\n"
693 " type empty;\n"
694 " }\n"
695 " leaf l2 {\n"
696 " must ../../notif/l;\n"
697 " type leafref {\n"
698 " path /notif/l;\n"
699 " }\n"
700 " }\n"
701 " }\n"
702 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200703 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
704 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200705
706 /* rpc input -> state */
Radek Iša56ca9e42020-09-08 18:42:00 +0200707 str = "module f {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200708 " namespace urn:f;\n"
709 " prefix f;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100710 " container cont {\n"
711 " config false;\n"
712 " leaf l {\n"
713 " type empty;\n"
714 " }\n"
715 " }\n"
716 " rpc rp {\n"
717 " input {\n"
718 " leaf l2 {\n"
719 " must ../../cont/l;\n"
720 " type leafref {\n"
721 " path /cont/l;\n"
722 " }\n"
723 " }\n"
724 " }\n"
725 " }\n"
726 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200727 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
728 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200729
730 /* rpc input -> rpc input */
Radek Iša56ca9e42020-09-08 18:42:00 +0200731 str = "module g {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200732 " namespace urn:g;\n"
733 " prefix g;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100734 " rpc rp {\n"
735 " input {\n"
736 " leaf l {\n"
737 " type empty;\n"
738 " }\n"
739 " leaf l2 {\n"
740 " must ../l;\n"
741 " type leafref {\n"
742 " path /rp/l;\n"
743 " }\n"
744 " }\n"
745 " }\n"
746 " }\n"
747 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200748 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
749 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200750
751 /* rpc input -> rpc output leafref */
Radek Iša56ca9e42020-09-08 18:42:00 +0200752 str = "module h {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200753 " namespace urn:h;\n"
754 " prefix h;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100755 " rpc rp {\n"
756 " input {\n"
757 " leaf l2 {\n"
758 " type leafref {\n"
759 " path /rp/l;\n"
760 " }\n"
761 " }\n"
762 " }\n"
763 " output {\n"
764 " leaf l {\n"
765 " type empty;\n"
766 " }\n"
767 " }\n"
768 " }\n"
769 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200770 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Michal Vasko959f8d82022-06-16 07:51:50 +0200771 CHECK_LOG_CTX("Not found node \"l\" in path.", "Schema location \"/h:rp/input/l2\".");
Michal Vasko6b26e742020-07-17 15:02:10 +0200772
773 /* rpc input -> rpc output must */
Radek Iša56ca9e42020-09-08 18:42:00 +0200774 str = "module h {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200775 " namespace urn:h;\n"
776 " prefix h;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100777 " rpc rp {\n"
778 " input {\n"
779 " leaf l2 {\n"
780 " must ../l;\n"
781 " type empty;\n"
782 " }\n"
783 " }\n"
784 " output {\n"
785 " leaf l {\n"
786 " type empty;\n"
787 " }\n"
788 " }\n"
789 " }\n"
790 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200791 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
Michal Vaskoa036a6b2021-10-12 16:05:23 +0200792 CHECK_LOG_CTX("Schema node \"l\" for parent \"/h:rp\" not found; in expr \"../l\" with context node \"/h:rp/input/l2\".", NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200793
794 /* rpc input -> notif leafref */
Radek Iša56ca9e42020-09-08 18:42:00 +0200795 str = "module i {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200796 " namespace urn:i;\n"
797 " prefix i;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100798 " rpc rp {\n"
799 " input {\n"
800 " leaf l2 {\n"
801 " type leafref {\n"
802 " path ../../notif/l;\n"
803 " }\n"
804 " }\n"
805 " }\n"
806 " }\n"
807 " notification notif {\n"
808 " leaf l {\n"
809 " type empty;\n"
810 " }\n"
811 " }\n"
812 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200813 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Michal Vasko959f8d82022-06-16 07:51:50 +0200814 CHECK_LOG_CTX("Not found node \"notif\" in path.", "Schema location \"/i:rp/input/l2\".");
Michal Vasko6b26e742020-07-17 15:02:10 +0200815
816 /* rpc input -> notif must */
Radek Iša56ca9e42020-09-08 18:42:00 +0200817 str = "module i {\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200818 " namespace urn:i;\n"
819 " prefix i;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100820 " rpc rp {\n"
821 " input {\n"
822 " leaf l2 {\n"
823 " must /notif/l;\n"
824 " type empty;\n"
825 " }\n"
826 " }\n"
827 " }\n"
828 " notification notif {\n"
829 " leaf l {\n"
830 " type empty;\n"
831 " }\n"
832 " }\n"
833 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200834 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
Michal Vaskoa036a6b2021-10-12 16:05:23 +0200835 CHECK_LOG_CTX("Schema node \"notif\" for parent \"<root>\" not found; in expr \"/notif\" "
836 "with context node \"/i:rp/input/l2\".", NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200837
838 /* action output -> state */
Radek Iša56ca9e42020-09-08 18:42:00 +0200839 str = "module j {\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100840 " yang-version 1.1;\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200841 " namespace urn:j;\n"
842 " prefix j;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100843 " container cont {\n"
844 " list ll {\n"
845 " key k;\n"
846 " leaf k {\n"
847 " type string;\n"
848 " }\n"
849 " action act {\n"
850 " output {\n"
851 " leaf l2 {\n"
852 " must /cont/l;\n"
853 " type leafref {\n"
854 " path ../../../l;\n"
855 " }\n"
856 " }\n"
857 " }\n"
858 " }\n"
859 " }\n"
860 " leaf l {\n"
861 " config false;\n"
862 " type empty;\n"
863 " }\n"
864 " }\n"
865 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200866 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
867 CHECK_LOG_CTX(NULL, NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200868
869 /* action output -> action input leafref */
Radek Iša56ca9e42020-09-08 18:42:00 +0200870 str = "module k {\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100871 " yang-version 1.1;\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200872 " namespace urn:k;\n"
873 " prefix k;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100874 " container cont {\n"
875 " list ll {\n"
876 " key k;\n"
877 " leaf k {\n"
878 " type string;\n"
879 " }\n"
880 " action act {\n"
881 " input {\n"
882 " leaf l {\n"
883 " type empty;\n"
884 " }\n"
885 " }\n"
886 " output {\n"
887 " leaf l2 {\n"
888 " type leafref {\n"
889 " path ../l;\n"
890 " }\n"
891 " }\n"
892 " }\n"
893 " }\n"
894 " }\n"
895 " }\n"
896 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200897 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Michal Vasko959f8d82022-06-16 07:51:50 +0200898 CHECK_LOG_CTX("Not found node \"l\" in path.", "Schema location \"/k:cont/ll/act/output/l2\".");
Michal Vasko6b26e742020-07-17 15:02:10 +0200899
900 /* action output -> action input must */
Radek Iša56ca9e42020-09-08 18:42:00 +0200901 str = "module k {\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100902 " yang-version 1.1;\n"
Michal Vaskob24145d2022-07-13 18:34:39 +0200903 " namespace urn:k;\n"
904 " prefix k;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100905 " container cont {\n"
906 " list ll {\n"
907 " key k;\n"
908 " leaf k {\n"
909 " type string;\n"
910 " }\n"
911 " action act {\n"
912 " input {\n"
913 " leaf l {\n"
914 " type empty;\n"
915 " }\n"
916 " }\n"
917 " output {\n"
918 " leaf l2 {\n"
919 " must /cont/ll/act/l;\n"
920 " type empty;\n"
921 " }\n"
922 " }\n"
923 " }\n"
924 " }\n"
925 " }\n"
926 "}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200927 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_SUCCESS);
Michal Vaskoa036a6b2021-10-12 16:05:23 +0200928 CHECK_LOG_CTX("Schema node \"l\" for parent \"/k:cont/ll/act\" not found; in expr \"/cont/ll/act/l\" "
929 "with context node \"/k:cont/ll/act/output/l2\".", NULL);
Michal Vasko6b26e742020-07-17 15:02:10 +0200930}
Radek Krejci589c5472021-01-20 10:29:06 +0100931
Radek Krejci589c5472021-01-20 10:29:06 +0100932void
933test_includes(void **state)
934{
Michal Vasko4de7d072021-07-09 09:13:18 +0200935 struct lys_module *mod;
Radek Krejci589c5472021-01-20 10:29:06 +0100936
937 {
938 /* YANG 1.0 - the missing include sub_a_two in main_a will be injected from sub_a_one */
939 struct module_clb_list list[] = {
Radek Krejcidf549132021-01-21 10:32:32 +0100940 {"main_a", "module main_a { namespace urn:test:main_a; prefix ma; include sub_a_one;}"},
941 {"sub_a_one", "submodule sub_a_one { belongs-to main_a { prefix ma; } include sub_a_two;}"},
942 {"sub_a_two", "submodule sub_a_two { belongs-to main_a { prefix ma; } }"},
943 {NULL, NULL}
Radek Krejci589c5472021-01-20 10:29:06 +0100944 };
945 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
946 mod = ly_ctx_load_module(UTEST_LYCTX, "main_a", NULL, NULL);
947 assert_non_null(mod);
948 assert_int_equal(2, LY_ARRAY_COUNT(mod->parsed->includes));
949 assert_true(mod->parsed->includes[1].injected);
950 }
951
952 {
953 /* YANG 1.1 - the missing include sub_b_two in main_b is error */
954 struct module_clb_list list[] = {
Radek Krejcidf549132021-01-21 10:32:32 +0100955 {"main_b", "module main_b { yang-version 1.1; namespace urn:test:main_b; prefix mb; include sub_b_one;}"},
956 {"sub_b_one", "submodule sub_b_one { yang-version 1.1; belongs-to main_b { prefix mb; } include sub_b_two;}"},
957 {"sub_b_two", "submodule sub_b_two { yang-version 1.1; belongs-to main_b { prefix mb; } }"},
958 {NULL, NULL}
Radek Krejci589c5472021-01-20 10:29:06 +0100959 };
960 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
961 mod = ly_ctx_load_module(UTEST_LYCTX, "main_b", NULL, NULL);
962 assert_null(mod);
963 CHECK_LOG_CTX("Loading \"main_b\" module failed.", NULL,
964 "Data model \"main_b\" not found in local searchdirs.", NULL,
Radek Krejci8297b792020-08-16 14:49:05 +0200965 "Parsing module \"main_b\" failed.", NULL,
Radek Krejci589c5472021-01-20 10:29:06 +0100966 "Including \"sub_b_one\" submodule into \"main_b\" failed.", NULL,
967 "Data model \"sub_b_one\" not found in local searchdirs.", NULL,
Radek Krejci8297b792020-08-16 14:49:05 +0200968 "Parsing submodule \"sub_b_one\" failed.", NULL,
Radek Krejci589c5472021-01-20 10:29:06 +0100969 "YANG 1.1 requires all submodules to be included from main module. But submodule \"sub_b_one\" includes "
Radek Krejci8297b792020-08-16 14:49:05 +0200970 "submodule \"sub_b_two\" which is not included by main module \"main_b\".", NULL,
971 "YANG version 1.1 expects all includes in main module, includes in submodules (sub_b_one) are not necessary.", NULL);
Radek Krejci589c5472021-01-20 10:29:06 +0100972 }
973
974 {
975 /* YANG 1.1 - all includes are in main_c, includes in submodules are not necessary, so expect warning */
976 struct module_clb_list list[] = {
Radek Krejcidf549132021-01-21 10:32:32 +0100977 {"main_c", "module main_c { yang-version 1.1; namespace urn:test:main_c; prefix mc; include sub_c_one; include sub_c_two;}"},
978 {"sub_c_one", "submodule sub_c_one { yang-version 1.1; belongs-to main_c { prefix mc; } include sub_c_two;}"},
Michal Vasko8a67eff2021-12-07 14:04:47 +0100979 {"sub_c_two", "submodule sub_c_two { yang-version 1.1; belongs-to main_c { prefix mc; } include sub_c_one;}"},
Radek Krejcidf549132021-01-21 10:32:32 +0100980 {NULL, NULL}
Radek Krejci589c5472021-01-20 10:29:06 +0100981 };
982 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list);
983 mod = ly_ctx_load_module(UTEST_LYCTX, "main_c", NULL, NULL);
984 assert_non_null(mod);
985 assert_int_equal(2, LY_ARRAY_COUNT(mod->parsed->includes));
986 assert_false(mod->parsed->includes[1].injected);
987 /* result is ok, but log includes the warning */
Michal Vasko8a67eff2021-12-07 14:04:47 +0100988 CHECK_LOG_CTX("YANG version 1.1 expects all includes in main module, includes in submodules (sub_c_two) are not necessary.", NULL);
Radek Krejci589c5472021-01-20 10:29:06 +0100989 }
990}
Michal Vaskoac4450e2021-11-09 13:53:40 +0100991
992void
993test_key_order(void **state)
994{
995 struct lys_module *mod;
996 const struct lysc_node *node;
997
998 struct module_clb_list list1[] = {
999 {"a", "module a {"
Michal Vaskof9122a02021-11-09 14:01:04 +01001000 "yang-version 1.1;"
1001 "namespace urn:test:a;"
1002 "prefix a;"
1003 "list l {"
1004 " key \"k1 k2\";"
1005 " leaf k2 {type string;}"
1006 " leaf k1 {type string;}"
1007 "}"
1008 "}"},
Michal Vaskoac4450e2021-11-09 13:53:40 +01001009 {NULL, NULL}
1010 };
Michal Vaskof9122a02021-11-09 14:01:04 +01001011
Michal Vaskoac4450e2021-11-09 13:53:40 +01001012 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list1);
1013 mod = ly_ctx_load_module(UTEST_LYCTX, "a", NULL, NULL);
1014 assert_non_null(mod);
1015
1016 node = lysc_node_child(mod->compiled->data);
1017 assert_string_equal("k1", node->name);
1018 node = node->next;
1019 assert_string_equal("k2", node->name);
1020
1021 struct module_clb_list list2[] = {
1022 {"b", "module b {"
Michal Vaskof9122a02021-11-09 14:01:04 +01001023 "yang-version 1.1;"
1024 "namespace urn:test:b;"
1025 "prefix b;"
1026 "list l {"
1027 " key \"k1 k2 k3 k4\";"
1028 " leaf k4 {type string;}"
1029 " container c {"
1030 " leaf l1 {type string;}"
1031 " }"
1032 " leaf k2 {type string;}"
1033 " leaf l2 {type string;}"
1034 " leaf k1 {type string;}"
1035 " leaf k3 {type string;}"
1036 "}"
1037 "}"},
Michal Vaskoac4450e2021-11-09 13:53:40 +01001038 {NULL, NULL}
1039 };
Michal Vaskof9122a02021-11-09 14:01:04 +01001040
Michal Vaskoac4450e2021-11-09 13:53:40 +01001041 ly_ctx_set_module_imp_clb(UTEST_LYCTX, module_clb, list2);
1042 mod = ly_ctx_load_module(UTEST_LYCTX, "b", NULL, NULL);
1043 assert_non_null(mod);
1044
1045 node = lysc_node_child(mod->compiled->data);
1046 assert_string_equal("k1", node->name);
1047 node = node->next;
1048 assert_string_equal("k2", node->name);
1049 node = node->next;
1050 assert_string_equal("k3", node->name);
1051 node = node->next;
1052 assert_string_equal("k4", node->name);
1053}
Michal Vaskof4fa90d2021-11-11 15:05:19 +01001054
1055void
1056test_disabled_enum(void **state)
1057{
1058 const char *str;
1059
1060 /* no enabled enum */
1061 str = "module a {"
1062 "yang-version 1.1;"
1063 "namespace urn:test:a;"
1064 "prefix a;"
1065 "feature f;"
1066 "leaf l {type enumeration {"
1067 " enum e1 {if-feature f;}"
1068 " enum e2 {if-feature f;}"
1069 "}}"
1070 "}";
1071 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
Michal Vasko959f8d82022-06-16 07:51:50 +02001072 CHECK_LOG_CTX("Enumeration type of node \"l\" without any (or all disabled) valid values.", "Schema location \"/a:l\".");
Michal Vaskof4fa90d2021-11-11 15:05:19 +01001073
1074 /* disabled default value */
1075 str = "module a {"
1076 "yang-version 1.1;"
1077 "namespace urn:test:a;"
1078 "prefix a;"
1079 "feature f;"
1080 "leaf l {"
1081 " type enumeration {"
1082 " enum e1 {if-feature f;}"
1083 " enum e2;"
1084 " }"
1085 " default e1;"
1086 "}"
1087 "}";
1088 assert_int_equal(lys_parse_mem(UTEST_LYCTX, str, LYS_IN_YANG, NULL), LY_EVALID);
1089 CHECK_LOG_CTX("Invalid default - value does not fit the type (Invalid enumeration value \"e1\".).",
Michal Vasko959f8d82022-06-16 07:51:50 +02001090 "Schema location \"/a:l\".");
Michal Vaskof4fa90d2021-11-11 15:05:19 +01001091}