blob: d7203fa89b0e476369da2c4cc2a643d8fc2768ba [file] [log] [blame]
Michal Vasko1b2a3f42022-12-20 09:38:28 +01001/**
Radek Krejci509e2592019-05-15 16:30:48 +02002 * @file test_parser_xml.c
Michal Vasko1b2a3f42022-12-20 09:38:28 +01003 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @author Michal Vasko <mvasko@cesnet.cz>
Radek Krejci509e2592019-05-15 16:30:48 +02005 * @brief unit tests for functions from parser_xml.c
6 *
Michal Vasko1b2a3f42022-12-20 09:38:28 +01007 * Copyright (c) 2019 - 2022 CESNET, z.s.p.o.
Radek Krejci509e2592019-05-15 16:30:48 +02008 *
9 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * https://opensource.org/licenses/BSD-3-Clause
14 */
Radek Iša56ca9e42020-09-08 18:42:00 +020015#define _UTEST_MAIN_
16#include "utests.h"
Radek Krejci509e2592019-05-15 16:30:48 +020017
Radek Krejci70593c12020-06-13 20:48:09 +020018#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020019#include "in.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020020#include "out.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010021#include "parser_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020022#include "printer_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020023#include "tree_data_internal.h"
24#include "tree_schema.h"
Radek Krejci509e2592019-05-15 16:30:48 +020025
26static int
27setup(void **state)
28{
Radek Iša56ca9e42020-09-08 18:42:00 +020029 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010030 "module a {\n"
31 " namespace urn:tests:a;\n"
32 " prefix a;\n"
33 " yang-version 1.1;\n"
Michal Vaskodd03ff12023-09-11 10:30:48 +020034 " import ietf-yang-metadata {prefix md;}"
Michal Vaskodbf3e652022-10-21 08:46:25 +020035 " list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;}"
36 " leaf d {type string;}"
37 " container cont {leaf e {type boolean;}}"
38 " }"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010039 " leaf foo { type string;}\n"
40 " container c {\n"
41 " leaf x {type string;}\n"
42 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }\n"
43 " notification n1 { leaf nl {type string;}}}\n"
44 " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
45 " anydata any {config false;}\n"
Michal Vasko5b414dd2023-04-13 10:29:58 +020046 " anyxml anyx;\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010047 " leaf foo2 { type string; default \"default-val\"; }\n"
48 " leaf foo3 { type uint32; }\n"
Michal Vaskodd03ff12023-09-11 10:30:48 +020049 " notification n2;"
50 " md:annotation attr {type enumeration {enum val;}}"
51 "}";
Radek Krejci509e2592019-05-15 16:30:48 +020052
Radek Iša56ca9e42020-09-08 18:42:00 +020053 UTEST_SETUP;
Radek Krejci509e2592019-05-15 16:30:48 +020054
Radek Iša56ca9e42020-09-08 18:42:00 +020055 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
56 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci509e2592019-05-15 16:30:48 +020057
58 return 0;
59}
60
Radek Iša56ca9e42020-09-08 18:42:00 +020061#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
62 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci509e2592019-05-15 16:30:48 +020063
Michal Vasko7a266772024-01-23 11:02:38 +010064#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH, ERR_LINE) \
Radek Iša56ca9e42020-09-08 18:42:00 +020065 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
Michal Vasko7a266772024-01-23 11:02:38 +010066 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH, ERR_LINE);\
Radek Iša56ca9e42020-09-08 18:42:00 +020067 assert_null(MODEL)
Radek Krejci509e2592019-05-15 16:30:48 +020068
Radek Iša56ca9e42020-09-08 18:42:00 +020069#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
70 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, PRINT_OPTION)
Radek Krejci509e2592019-05-15 16:30:48 +020071
Radek Krejci509e2592019-05-15 16:30:48 +020072static void
73test_leaf(void **state)
74{
Radek Krejci509e2592019-05-15 16:30:48 +020075 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
76 struct lyd_node *tree;
77 struct lyd_node_term *leaf;
78
Radek Iša56ca9e42020-09-08 18:42:00 +020079 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020080
Radek Iša56ca9e42020-09-08 18:42:00 +020081 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
82 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
83 leaf = (struct lyd_node_term *)tree;
84 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
85
86 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
87 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010088 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020089 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010090 assert_true(leaf->flags & LYD_DEFAULT);
Radek Krejci509e2592019-05-15 16:30:48 +020091 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +010092
93 /* make foo2 explicit */
94 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Radek Iša56ca9e42020-09-08 18:42:00 +020095 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +010096 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010097 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020098 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
99 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100100 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200101 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100102 assert_false(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +0100103 lyd_free_all(tree);
104
Radek Krejci1798aae2020-07-14 13:26:06 +0200105 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200106 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" "
107 "wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
108 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100109 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100110 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200111 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
112 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100113 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200114 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100115 assert_true(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +0100116 lyd_free_all(tree);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200117
118 /* invalid value */
119 data = "<l1 xmlns=\"urn:tests:a\"><a>val-a</a><b>val-b</b><c>1</c><cont><e>0</e></cont></l1>";
120 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100121 "Invalid boolean value \"0\".", "/a:l1[a='val-a'][b='val-b'][c='1']/cont/e", 1);
Radek Krejci509e2592019-05-15 16:30:48 +0200122}
123
Radek Krejciee4cab22019-07-17 17:07:47 +0200124static void
125test_anydata(void **state)
126{
Michal Vasko52927e22020-03-16 17:26:14 +0100127 const char *data;
Michal Vasko5b414dd2023-04-13 10:29:58 +0200128 char *str;
Radek Krejciee4cab22019-07-17 17:07:47 +0200129 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200130
Radek Iša56ca9e42020-09-08 18:42:00 +0200131 data = "<any xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100132 " <element1>\n"
133 " <x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>\n"
134 " </element1>\n"
135 " <element1a/>\n"
136 "</any>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200137 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200138 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100139 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200140 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_SET_CONFIG, 1, "any",
141 1, LYS_ANYDATA, 0, 0, NULL, 0);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200142
Radek Iša56ca9e42020-09-08 18:42:00 +0200143 const char *data_expected =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100144 "<any xmlns=\"urn:tests:a\">\n"
145 " <element1>\n"
146 " <element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>\n"
147 " </element1>\n"
148 " <element1a/>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200149 "</any>\n";
150
151 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Michal Vasko5b414dd2023-04-13 10:29:58 +0200152
153 assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str));
154 lyd_free_all(tree);
155
156 assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:any", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL));
157 free(str);
158 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
159 lyd_free_all(tree);
160}
161
162static void
163test_anyxml(void **state)
164{
165 const char *data;
166 char *str;
167 struct lyd_node *tree;
168
169 data = "<anyx xmlns=\"urn:tests:a\">\n"
170 " <element1>\n"
171 " <element2 x:attr2=\"test\" xmlns:x=\"urn:x\">data</element2>\n"
172 " </element1>\n"
173 " <element1a/>\n"
174 "</anyx>\n";
175 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
176 assert_non_null(tree);
177 tree = tree->next;
178
179 const char *data_expected =
180 "<anyx xmlns=\"urn:tests:a\">\n"
181 " <element1>\n"
182 " <element2 xmlns:x=\"urn:x\" x:attr2=\"test\">data</element2>\n"
183 " </element1>\n"
184 " <element1a/>\n"
185 "</anyx>\n";
186
187 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
188
189 assert_int_equal(LY_SUCCESS, lyd_any_value_str(tree, &str));
190 lyd_free_all(tree);
191
192 assert_int_equal(LY_SUCCESS, lyd_new_path2(NULL, UTEST_LYCTX, "/a:anyx", str, strlen(str), LYD_ANYDATA_XML, 0, &tree, NULL));
193 free(str);
194 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Radek Krejciee4cab22019-07-17 17:07:47 +0200195 lyd_free_all(tree);
Jan Kundrát863b18b2024-07-06 20:55:23 +0200196
197 data = "<anyx xmlns=\"urn:tests:a\"><x>1</x><x>0</x><x>-1</x><x>4294967295</x><x>4294967296</x><x>-2147483648</x><x>-2147483649</x></anyx>";
198 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
199 assert_non_null(tree);
200 tree = tree->next;
201 assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, tree, LYD_XML, LYD_PRINT_SHRINK));
202 CHECK_STRING(str, data);
203 free(str);
204 assert_int_equal(LY_SUCCESS, lyd_print_mem(&str, tree, LYD_JSON, LYD_PRINT_SHRINK));
205 CHECK_STRING(str, "{\"a:anyx\":{\"x\":[1,0,-1,4294967295,\"4294967296\",-2147483648,\"-2147483649\"]}}");
206 free(str);
207 lyd_free_all(tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200208}
209
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200210static void
211test_list(void **state)
212{
Radek Iša56ca9e42020-09-08 18:42:00 +0200213 const char *data;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200214 struct lyd_node *tree, *iter;
215 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200216 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200217
Radek Krejci710226d2019-07-24 17:24:59 +0200218 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200219 data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
220 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
221 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
222 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100223 list = (struct lyd_node_inner *)tree;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200224 LY_LIST_FOR(list->child, iter) {
225 assert_int_not_equal(0, iter->hash);
226 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200227 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200228
Michal Vasko9f96a052020-03-10 09:41:45 +0100229 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200230 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100231 "List instance is missing its key \"a\".", "/a:l1[b='b'][c='1']", 1);
232 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
Michal Vasko9f96a052020-03-10 09:41:45 +0100233
Radek Iša56ca9e42020-09-08 18:42:00 +0200234 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100235 "List instance is missing its key \"b\".", "/a:l1[a='a']", 1);
Michal Vasko9f96a052020-03-10 09:41:45 +0100236
Radek Iša56ca9e42020-09-08 18:42:00 +0200237 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100238 "List instance is missing its key \"c\".", "/a:l1[a='a'][b='b']", 1);
239 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
Michal Vasko9f96a052020-03-10 09:41:45 +0100240
241 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200242 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100243 "Duplicate instance of \"c\".", "/a:l1[a='a'][b='b'][c='1'][c='1']/c", 1);
244 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
245 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
Michal Vasko9f96a052020-03-10 09:41:45 +0100246
Radek Krejci710226d2019-07-24 17:24:59 +0200247 /* keys order */
Radek Iša56ca9e42020-09-08 18:42:00 +0200248 CHECK_PARSE_LYD("<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree);
249 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
250 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100251 list = (struct lyd_node_inner *)tree;
252 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200253 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100254 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200255 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100256 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200257 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100258 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200259 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 1, LYS_LEAF, 1, 0, NULL, 0);
Michal Vasko7a266772024-01-23 11:02:38 +0100260 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
Radek Krejci710226d2019-07-24 17:24:59 +0200261 lyd_free_all(tree);
262
Michal Vasko44685da2020-03-17 15:38:06 +0100263 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200264 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
265 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1", 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100266 list = (struct lyd_node_inner *)tree;
267 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200268 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100269 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100271 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200272 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
Michal Vasko7a266772024-01-23 11:02:38 +0100273 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
274 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
Radek Krejci710226d2019-07-24 17:24:59 +0200275 lyd_free_all(tree);
276
Radek Iša56ca9e42020-09-08 18:42:00 +0200277 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100278 "Invalid position of the key \"b\" in a list.", "/a:l1[c='1']/b", 1);
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200279}
280
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200281static void
282test_container(void **state)
283{
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200284 struct lyd_node *tree;
285 struct lyd_node_inner *cont;
286
Radek Iša56ca9e42020-09-08 18:42:00 +0200287 CHECK_PARSE_LYD("<c xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
288 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100289 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200290 assert_true(cont->flags & LYD_DEFAULT);
291 lyd_free_all(tree);
292
Radek Iša56ca9e42020-09-08 18:42:00 +0200293 CHECK_PARSE_LYD("<cp xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200294 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100295 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100296 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Radek Iša56ca9e42020-09-08 18:42:00 +0200297 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100298 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200299 assert_false(cont->flags & LYD_DEFAULT);
300 lyd_free_all(tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200301}
302
Michal Vasko44685da2020-03-17 15:38:06 +0100303static void
304test_opaq(void **state)
305{
Michal Vasko44685da2020-03-17 15:38:06 +0100306 const char *data;
Michal Vasko44685da2020-03-17 15:38:06 +0100307 struct lyd_node *tree;
308
309 /* invalid value, no flags */
310 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200311 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100312 "Invalid type uint32 empty value.", "/a:foo3", 1);
Michal Vasko44685da2020-03-17 15:38:06 +0100313
314 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200315 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Michal Vasko535d21c2023-08-09 10:41:44 +0200316 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 1, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
Michal Vasko44685da2020-03-17 15:38:06 +0100318 lyd_free_all(tree);
319
Michal Vaskoda8fbbf2021-06-16 11:44:44 +0200320 /* list, opaq flag */
321 data = "<l1 xmlns=\"urn:tests:a\"/>";
322 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Michal Vasko535d21c2023-08-09 10:41:44 +0200323 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
Michal Vaskoda8fbbf2021-06-16 11:44:44 +0200324 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n");
325 lyd_free_all(tree);
326
Michal Vasko44685da2020-03-17 15:38:06 +0100327 /* missing key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200328 data = "<l1 xmlns=\"urn:tests:a\">\n"
329 " <a>val_a</a>\n"
330 " <b>val_b</b>\n"
331 " <d>val_d</d>\n"
332 "</l1>\n";
333 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100334 "List instance is missing its key \"c\".", "/a:l1[a='val_a'][b='val_b']", 5);
Michal Vasko44685da2020-03-17 15:38:06 +0100335
336 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200337 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Michal Vasko535d21c2023-08-09 10:41:44 +0200338 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200339 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100340 lyd_free_all(tree);
341
342 /* invalid key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200343 data = "<l1 xmlns=\"urn:tests:a\">\n"
344 " <a>val_a</a>\n"
345 " <b>val_b</b>\n"
346 " <c>val_c</c>\n"
347 "</l1>\n";
348 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko7a266772024-01-23 11:02:38 +0100349 "Invalid type int16 value \"val_c\".", "/a:l1[a='val_a'][b='val_b']/c", 4);
Michal Vasko44685da2020-03-17 15:38:06 +0100350
351 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200352 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Michal Vasko535d21c2023-08-09 10:41:44 +0200353 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200354 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100355 lyd_free_all(tree);
356
Michal Vasko413c7f22020-05-05 12:34:06 +0200357 /* opaq flag and fail */
Radek Iša56ca9e42020-09-08 18:42:00 +0200358 assert_int_equal(LY_EVALID, lyd_parse_data_mem(UTEST_LYCTX,
359 "<a xmlns=\"ns\">\n"
360 " <b>x</b>\n"
Michal Vaskoe137fc42021-07-22 11:53:13 +0200361 " <c xmld:id=\"D\">1</c>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200362 "</a>\n",
363 LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
aPiecek77a4f502024-07-03 08:34:48 +0200364 CHECK_LOG_CTX("Unknown XML prefix \"xmld\" at attribute \"id\".", "/a", 3);
Michal Vasko44685da2020-03-17 15:38:06 +0100365}
366
Michal Vaskob36053d2020-03-26 15:49:30 +0100367static void
368test_rpc(void **state)
369{
Michal Vaskob36053d2020-03-26 15:49:30 +0100370 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200371 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100372 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100373 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200374 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
375 "configuration to the specified target configuration.";
376 const char *ref = "RFC 6241, Section 7.2";
377 const char *feats[] = {"writable-running", NULL};
Michal Vaskob36053d2020-03-26 15:49:30 +0100378
Radek Iša56ca9e42020-09-08 18:42:00 +0200379 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100380
Michal Vasko2552ea32020-12-08 15:32:34 +0100381 data = "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
382 " <target>\n"
383 " <running/>\n"
384 " </target>\n"
385 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
386 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
387 " <a>val_a</a>\n"
388 " <b>val_b</b>\n"
389 " <c>val_c</c>\n"
390 " </l1>\n"
391 " <cp xmlns=\"urn:tests:a\">\n"
392 " <z nc:operation=\"delete\"/>\n"
393 " </cp>\n"
394 " </config>\n"
395 "</edit-config>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200396 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100397 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, &op));
Michal Vasko63f3d842020-07-08 10:10:14 +0200398 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100399
400 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200401
Radek Krejci2a9fc652021-01-22 17:44:34 +0100402 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200403 1, 0, 0, 1, "edit-config", LYS_RPC,
404 0, 0, 0, 0, 0, ref, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100405
Michal Vaskob36053d2020-03-26 15:49:30 +0100406 assert_non_null(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200407
Michal Vasko2552ea32020-12-08 15:32:34 +0100408 node = tree;
Radek Krejci2a9fc652021-01-22 17:44:34 +0100409 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200410 1, 0, 0, 1, "edit-config", LYS_RPC,
411 0, 0, 0, 0, 0, ref, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200412 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200413 dsc = "Inline Config content.";
Michal Vaskod1e53b92021-01-28 13:11:06 +0100414 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
Michal Vaskob104f112020-07-17 09:54:54 +0200415
Michal Vasko1bf09392020-03-27 12:38:10 +0100416 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100417 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Radek Iša56ca9e42020-09-08 18:42:00 +0200418 1, LYS_CONTAINER, 0, 0, NULL, 0);
419
Radek Krejcia1c1e542020-09-29 16:06:52 +0200420 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100421 /* z has no value */
Michal Vasko535d21c2023-08-09 10:41:44 +0200422 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, "");
Michal Vaskob104f112020-07-17 09:54:54 +0200423 node = node->parent->next;
424 /* l1 key c has invalid value so it is at the end */
Michal Vasko535d21c2023-08-09 10:41:44 +0200425 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
Michal Vaskob36053d2020-03-26 15:49:30 +0100426
Radek Iša56ca9e42020-09-08 18:42:00 +0200427 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100428 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
429 " <target>\n"
430 " <running/>\n"
431 " </target>\n"
432 " <config>\n"
433 " <cp xmlns=\"urn:tests:a\">\n"
434 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
435 " </cp>\n"
436 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
437 " <a>val_a</a>\n"
438 " <b>val_b</b>\n"
439 " <c>val_c</c>\n"
440 " </l1>\n"
441 " </config>\n"
442 "</edit-config>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200443
Michal Vaskob36053d2020-03-26 15:49:30 +0100444 lyd_free_all(tree);
445
446 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100447 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100448}
449
450static void
451test_action(void **state)
452{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100453 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200454 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100455 struct lyd_node *tree, *op;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100456
Michal Vasko2552ea32020-12-08 15:32:34 +0100457 data = "<c xmlns=\"urn:tests:a\">\n"
458 " <act>\n"
459 " <al>value</al>\n"
460 " </act>\n"
461 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200462 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100463 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, &op));
Michal Vasko63f3d842020-07-08 10:10:14 +0200464 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100465
466 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100467 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200468 1, 0, 0, 1, "act", LYS_ACTION,
469 1, 0, 0, 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100470
Radek Iša56ca9e42020-09-08 18:42:00 +0200471 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100472 "<c xmlns=\"urn:tests:a\">\n"
473 " <act>\n"
474 " <al>value</al>\n"
475 " </act>\n"
476 "</c>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200477
Michal Vaskoa8edff02020-03-27 14:47:01 +0100478 lyd_free_all(tree);
479
480 /* wrong namespace, element name, whatever... */
481 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100482}
483
484static void
485test_notification(void **state)
486{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100487 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200488 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100489 struct lyd_node *tree, *ntf;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100490
Michal Vasko2552ea32020-12-08 15:32:34 +0100491 data = "<c xmlns=\"urn:tests:a\">\n"
492 " <n1>\n"
493 " <nl>value</nl>\n"
494 " </n1>\n"
495 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200496 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100497 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_YANG, &tree, &ntf));
Michal Vasko63f3d842020-07-08 10:10:14 +0200498 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100499
500 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100501 CHECK_LYSC_NOTIF((struct lysc_node_notif *)ntf->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100502
Michal Vasko2552ea32020-12-08 15:32:34 +0100503 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100504
Radek Iša56ca9e42020-09-08 18:42:00 +0200505 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100506 lyd_free_all(tree);
507
508 /* top-level notif without envelope */
Radek Iša56ca9e42020-09-08 18:42:00 +0200509 data = "<n2 xmlns=\"urn:tests:a\"/>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200510 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100511 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_YANG, &tree, &ntf));
Michal Vasko63f3d842020-07-08 10:10:14 +0200512 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100513
514 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100515 CHECK_LYSC_NOTIF((struct lysc_node_notif *)ntf->schema, 0, NULL, 0, 0x4, 1, 0, "n2", 0, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100516
517 assert_non_null(tree);
518 assert_ptr_equal(ntf, tree);
519
Radek Iša56ca9e42020-09-08 18:42:00 +0200520 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100521 lyd_free_all(tree);
522
523 /* wrong namespace, element name, whatever... */
524 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100525}
526
Michal Vasko1ce933a2020-03-30 12:38:22 +0200527static void
528test_reply(void **state)
529{
Michal Vasko1ce933a2020-03-30 12:38:22 +0200530 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200531 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +0100532 struct lyd_node *tree, *op;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200533 const struct lyd_node *node;
534
Michal Vasko79135ae2020-12-16 10:08:35 +0100535 data = "<c xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100536 " <act>\n"
Michal Vasko2552ea32020-12-08 15:32:34 +0100537 " <al>25</al>\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100538 " </act>\n"
539 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200540 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100541 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_REPLY_YANG, &tree, &op));
Michal Vasko63f3d842020-07-08 10:10:14 +0200542 ly_in_free(in, 0);
543
Michal Vasko1ce933a2020-03-30 12:38:22 +0200544 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200545
Radek Krejci2a9fc652021-01-22 17:44:34 +0100546 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200547 1, 0, 0, 1, "act", LYS_ACTION,
548 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200549 node = lyd_child(op);
Michal Vaskod1e53b92021-01-28 13:11:06 +0100550 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_STATUS_CURR | LYS_IS_OUTPUT, 1, "al", 0, LYS_LEAF, 1, 0, NULL, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200551
Michal Vasko2552ea32020-12-08 15:32:34 +0100552 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Michal Vasko1ce933a2020-03-30 12:38:22 +0200553
554 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200555 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_WITHSIBLINGS, "<al xmlns=\"urn:tests:a\">25</al>\n");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200556 lyd_free_all(tree);
557
558 /* wrong namespace, element name, whatever... */
559 /* TODO */
Michal Vasko1ce933a2020-03-30 12:38:22 +0200560}
561
Michal Vaskoe0665742021-02-11 11:08:44 +0100562static void
563test_netconf_rpc(void **state)
564{
565 const char *data;
566 struct ly_in *in;
567 struct lyd_node *tree, *op;
568 const struct lyd_node *node;
569 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
570 "configuration to the specified target configuration.";
571 const char *ref = "RFC 6241, Section 7.2";
572 const char *feats[] = {"writable-running", NULL};
573
574 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
575
576 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
577 "<edit-config>\n"
578 " <target>\n"
579 " <running/>\n"
580 " </target>\n"
581 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
582 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
583 " <a>val_a</a>\n"
584 " <b>val_b</b>\n"
585 " <c>val_c</c>\n"
586 " </l1>\n"
587 " <cp xmlns=\"urn:tests:a\">\n"
588 " <z nc:operation=\"delete\"/>\n"
589 " </cp>\n"
590 " </config>\n"
591 "</edit-config>\n"
592 "</rpc>\n";
593 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100594 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
Michal Vaskoe0665742021-02-11 11:08:44 +0100595 ly_in_free(in, 0);
596
597 assert_non_null(op);
598
599 node = tree;
Radek Krejci8df109d2021-04-23 12:19:08 +0200600 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 1, 0, LY_VALUE_XML, "rpc", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100601
602 assert_non_null(tree);
603
604 node = op;
605 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
606 1, 0, 0, 1, "edit-config", LYS_RPC,
607 0, 0, 0, 0, 0, ref, 0);
608 node = lyd_child(node)->next;
609 dsc = "Inline Config content.";
610 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
611
612 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100613 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Michal Vaskoe0665742021-02-11 11:08:44 +0100614 1, LYS_CONTAINER, 0, 0, NULL, 0);
615
616 node = lyd_child(node);
617 /* z has no value */
Michal Vasko535d21c2023-08-09 10:41:44 +0200618 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 1, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100619 node = node->parent->next;
620 /* l1 key c has invalid value so it is at the end */
Michal Vasko535d21c2023-08-09 10:41:44 +0200621 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 1, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100622
623 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
624 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n");
625 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
626 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
627 " <target>\n"
628 " <running/>\n"
629 " </target>\n"
630 " <config>\n"
631 " <cp xmlns=\"urn:tests:a\">\n"
632 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
633 " </cp>\n"
634 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
635 " <a>val_a</a>\n"
636 " <b>val_b</b>\n"
637 " <c>val_c</c>\n"
638 " </l1>\n"
639 " </config>\n"
640 "</edit-config>\n");
641
642 lyd_free_all(tree);
643 lyd_free_all(op);
644
Michal Vasko85be65e2023-06-13 09:44:17 +0200645 /* invalid anyxml nested metadata value */
646 data = "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\" pid=\"4114692032\">\n"
647 " <copy-config>\n"
648 " <target>\n"
649 " <running/>\n"
650 " </target>\n"
651 " <source>\n"
652 " <config>\n"
653 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
654 " <a>val_a</a>\n"
655 " <b>val_b</b>\n"
656 " <c>5</c>\n"
657 " <cont nc:operation=\"merge\">\n"
658 " <e nc:operation=\"merge2\">false</e>\n"
659 " </cont>\n"
660 " </l1>\n"
661 " </config>\n"
662 " </source>\n"
663 " </copy-config>\n"
664 "</rpc>\n";
665 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
666 assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
667 ly_in_free(in, 0);
668 CHECK_LOG_CTX("Invalid enumeration value \"merge2\".",
Michal Vasko7a266772024-01-23 11:02:38 +0100669 "/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e/@ietf-netconf:operation", 13);
Michal Vasko85be65e2023-06-13 09:44:17 +0200670 lyd_free_all(tree);
671 assert_null(op);
Michal Vaskoe0665742021-02-11 11:08:44 +0100672}
673
674static void
675test_netconf_action(void **state)
676{
677 const char *data;
678 struct ly_in *in;
679 struct lyd_node *tree, *op;
680
681 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
682 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
683 "<c xmlns=\"urn:tests:a\">\n"
684 " <act>\n"
685 " <al>value</al>\n"
686 " </act>\n"
687 "</c>\n"
688 "</action>\n"
689 "</rpc>\n";
690 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100691 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
Michal Vaskoe0665742021-02-11 11:08:44 +0100692 ly_in_free(in, 0);
693
Radek Krejci8df109d2021-04-23 12:19:08 +0200694 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc", 0, 0, 0, 0, "");
695 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)lyd_child(tree), 0, 0, LY_VALUE_XML, "action", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100696
697 assert_non_null(op);
698 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
699 1, 0, 0, 1, "act", LYS_ACTION,
700 1, 0, 0, 1, 0, NULL, 0);
701
702 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
703 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\">\n"
704 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\"/>\n"
705 "</rpc>\n");
706 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
707 "<act xmlns=\"urn:tests:a\">\n"
708 " <al>value</al>\n"
709 "</act>\n");
710
711 lyd_free_all(tree);
712 lyd_free_all(op);
713
714 /* wrong namespace, element name, whatever... */
715 /* TODO */
716}
717
718static void
719test_netconf_reply_or_notification(void **state)
720{
721 const char *data;
722 struct ly_in *in;
723 struct lyd_node *action, *tree, *op, *op2;
724
725 /* parse the action */
726 data = "<c xmlns=\"urn:tests:a\">\n"
727 " <act>\n"
728 " <al>value</al>\n"
729 " </act>\n"
730 "</c>\n";
731 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100732 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &action, &op));
Michal Vaskoe0665742021-02-11 11:08:44 +0100733 ly_in_free(in, 0);
734
735 /* parse notification first */
736 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
737 "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
738 "<c xmlns=\"urn:tests:a\">\n"
739 " <n1>\n"
740 " <nl>value</nl>\n"
741 " </n1>\n"
742 "</c>\n"
743 "</notification>\n";
744 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100745 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_NETCONF, &tree, &op2));
Michal Vaskoe0665742021-02-11 11:08:44 +0100746 ly_in_free(in, 0);
747
Radek Krejci8df109d2021-04-23 12:19:08 +0200748 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 1, LY_VALUE_XML, "notification", 0, 0, 0, 0, "");
749 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)lyd_child(tree), 0, 0, LY_VALUE_XML, "eventTime", 0, 0, 0, 0,
Michal Vaskoe0665742021-02-11 11:08:44 +0100750 "2010-12-06T08:00:01Z");
751
752 assert_non_null(op2);
753 CHECK_LYSC_NOTIF((struct lysc_node_notif *)op2->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
754
755 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
756 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
757 " <eventTime>2010-12-06T08:00:01Z</eventTime>\n"
758 "</notification>\n");
759 CHECK_LYD_STRING(op2, LYD_PRINT_WITHSIBLINGS,
760 "<n1 xmlns=\"urn:tests:a\">\n"
761 " <nl>value</nl>\n"
762 "</n1>\n");
763
764 lyd_free_all(tree);
765 lyd_free_all(op2);
766
Michal Vasko4a1e3e82023-09-05 08:45:01 +0200767 /* notification with a different order */
768 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
769 "<c xmlns=\"urn:tests:a\">\n"
770 " <n1>\n"
771 " <nl>value</nl>\n"
772 " </n1>\n"
773 "</c>\n"
774 "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
775 "</notification>\n";
776 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
777 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_NOTIF_NETCONF, &tree, &op2));
778 ly_in_free(in, 0);
779
780 lyd_free_all(tree);
781 lyd_free_all(op2);
782
Michal Vaskoe0665742021-02-11 11:08:44 +0100783 /* parse a data reply */
784 data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
785 " <al xmlns=\"urn:tests:a\">25</al>\n"
786 "</rpc-reply>\n";
787 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100788 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, op, in, LYD_XML, LYD_TYPE_REPLY_NETCONF, &tree, NULL));
Michal Vaskoe0665742021-02-11 11:08:44 +0100789 ly_in_free(in, 0);
790
Radek Krejci8df109d2021-04-23 12:19:08 +0200791 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 0, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100792
Michal Vaskoe0665742021-02-11 11:08:44 +0100793 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
794 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\"/>\n");
Michal Vaskoe0665742021-02-11 11:08:44 +0100795
796 lyd_free_all(tree);
797 /* it was connected to the action, do not free */
798
799 /* parse an ok reply */
800 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
801 " <ok/>\n"
802 "</rpc-reply>\n";
803 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100804 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, op, in, LYD_XML, LYD_TYPE_REPLY_NETCONF, &tree, NULL));
Michal Vaskoe0665742021-02-11 11:08:44 +0100805 ly_in_free(in, 0);
806
Radek Krejci8df109d2021-04-23 12:19:08 +0200807 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
808 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)lyd_child(tree), 0, 0, LY_VALUE_XML, "ok", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100809
Michal Vaskoe0665742021-02-11 11:08:44 +0100810 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
811
812 lyd_free_all(tree);
813
814 /* parse an error reply */
815 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
816 " <rpc-error>\n"
817 " <error-type>rpc</error-type>\n"
818 " <error-tag>missing-attribute</error-tag>\n"
819 " <error-severity>error</error-severity>\n"
820 " <error-info>\n"
821 " <bad-attribute>message-id</bad-attribute>\n"
822 " <bad-element>rpc</bad-element>\n"
823 " </error-info>\n"
824 " </rpc-error>\n"
825 "</rpc-reply>\n";
826 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100827 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, op, in, LYD_XML, LYD_TYPE_REPLY_NETCONF, &tree, NULL));
Michal Vaskoe0665742021-02-11 11:08:44 +0100828 ly_in_free(in, 0);
829
Radek Krejci8df109d2021-04-23 12:19:08 +0200830 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
831 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)lyd_child(tree), 0, 1, LY_VALUE_XML, "rpc-error", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100832
Michal Vaskoe0665742021-02-11 11:08:44 +0100833 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
834
835 lyd_free_all(tree);
836
837 lyd_free_all(action);
838
839 /* wrong namespace, element name, whatever... */
840 /* TODO */
841}
842
aPiecek9cdb9e62021-05-18 09:46:20 +0200843static void
Michal Vasko820efe82023-05-12 15:47:43 +0200844test_restconf_rpc(void **state)
845{
846 const char *data;
847 struct ly_in *in;
848 struct lyd_node *tree, *envp;
849
850 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-nmda", "2019-01-07", NULL)));
851
852 assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/ietf-netconf-nmda:edit-data", NULL, 0, &tree));
853
854 data = "<input xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">"
855 "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>"
856 "<config>"
857 "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>"
858 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
859 "<a>val_a</a><b>val_b</b><c>val_c</c>"
860 "</l1>"
861 "</config></input>";
862 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
863 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, tree, in, LYD_XML, LYD_TYPE_RPC_RESTCONF, &envp, NULL));
864 ly_in_free(in, 0);
865
866 /* the same just connected to the edit-data RPC */
867 data = "<edit-data xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-nmda\">"
868 "<datastore xmlns:ds=\"urn:ietf:params:xml:ns:yang:ietf-datastores\">ds:running</datastore>"
869 "<config>"
870 "<cp xmlns=\"urn:tests:a\"><z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\"/></cp>"
871 "<l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">"
872 "<a>val_a</a><b>val_b</b><c>val_c</c>"
873 "</l1>"
874 "</config></edit-data>";
875 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
876 lyd_free_all(tree);
877 lyd_free_all(envp);
878}
879
880static void
881test_restconf_reply(void **state)
882{
883 const char *data;
884 struct ly_in *in;
885 struct lyd_node *tree, *envp;
886
887 assert_int_equal(LY_SUCCESS, lyd_new_path(NULL, UTEST_LYCTX, "/a:c/act", NULL, 0, &tree));
888
889 data = "<output xmlns=\"urn:tests:a\"><al>25</al></output>";
890 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
891 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, lyd_child(tree), in, LYD_XML, LYD_TYPE_REPLY_RESTCONF, &envp, NULL));
892 ly_in_free(in, 0);
893
894 /* connected to the RPC with the parent */
895 data = "<c xmlns=\"urn:tests:a\"><act><al>25</al></act></c>";
896 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
897 lyd_free_all(tree);
898 lyd_free_all(envp);
899}
900
901static void
Michal Vasko45791ad2021-06-17 08:45:03 +0200902test_filter_attributes(void **state)
903{
904 const char *data;
905 struct ly_in *in;
906 struct lyd_node *tree;
907 const struct lyd_node *node;
908 const char *dsc;
909 const char *ref = "RFC 6241, Section 7.7";
910 const char *feats[] = {"writable-running", NULL};
911
912 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100913 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "notifications", "2008-07-14", NULL)));
Michal Vasko45791ad2021-06-17 08:45:03 +0200914
915 data = "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
916 " <filter type=\"xpath\" select=\"/*\"/>\n"
917 "</get>\n";
918 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
919 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
920 ly_in_free(in, 0);
921 assert_non_null(tree);
922
923 node = tree;
924 dsc = "Retrieve running configuration and device state information.";
925 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
926 1, 0, 0, 1, "get", LYS_RPC,
927 1, 0, 0, 0, 0, ref, 0);
928 node = lyd_child(node);
929 dsc = "This parameter specifies the portion of the system\nconfiguration and state data to retrieve.";
930 CHECK_LYSC_NODE(node->schema, dsc, 1, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "filter", 0, LYS_ANYXML, 1, 0, NULL, 0);
931
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100932 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
933 lyd_free_all(tree);
Michal Vasko45791ad2021-06-17 08:45:03 +0200934
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100935 data = "<create-subscription xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
936 " <filter type=\"subtree\">\n"
937 " <inner-node xmlns=\"my:urn\"/>\n"
938 " </filter>\n"
939 "</create-subscription>\n";
940 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
941 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
942 ly_in_free(in, 0);
943 assert_non_null(tree);
944
945 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko45791ad2021-06-17 08:45:03 +0200946 lyd_free_all(tree);
947}
948
949static void
aPiecek9cdb9e62021-05-18 09:46:20 +0200950test_data_skip(void **state)
951{
952 const char *data;
953 struct lyd_node *tree;
954 struct lyd_node_term *leaf;
955
956 /* add invalid data to a module that is not implemented */
957 data = "<foo xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\"><u/></foo>";
958 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
959 assert_null(tree);
960
961 /* add invalid data to a module that is implemented */
962 data = "<fooX xmlns=\"urn:tests:a\"><u/><list><value/></list></fooX>";
963 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
964 assert_null(tree);
965
966 /* first invalid, next valid */
967 data = "<fooX xmlns=\"urn:tests:a\"><u/></fooX> <foo xmlns=\"urn:tests:a\">foo value</foo>";
968 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
969 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
970 leaf = (struct lyd_node_term *)tree;
971 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
972 lyd_free_all(tree);
973}
974
Michal Vaskodd03ff12023-09-11 10:30:48 +0200975static void
976test_metadata(void **state)
977{
978 const char *data;
979 struct lyd_node *tree;
980
981 /* invalid metadata value */
982 data = "<c xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\"><x a:attr=\"value\">xval</x></c>";
983 assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
984 assert_null(tree);
Michal Vasko7a266772024-01-23 11:02:38 +0100985 CHECK_LOG_CTX("Invalid enumeration value \"value\".", "/a:c/x/@a:attr", 1);
Michal Vaskodd03ff12023-09-11 10:30:48 +0200986}
987
Michal Vaskoa6139e02023-10-03 14:13:22 +0200988static void
989test_subtree(void **state)
990{
991 const char *data;
992 struct ly_in *in;
993 struct lyd_node *tree;
994
995 /* prepare data with the parent */
996 data = "<l1 xmlns=\"urn:tests:a\">\n"
997 " <a>val_a</a>\n"
998 " <b>val_b</b>\n"
999 " <c>1</c>\n"
1000 "</l1>\n";
1001 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
1002
1003 /* parse a subtree of it */
1004 data = "<cont xmlns=\"urn:tests:a\">\n"
1005 " <e>true</e>\n"
1006 "</cont>\n";
1007 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
1008 assert_int_equal(LY_SUCCESS, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL));
1009 ly_in_free(in, 0);
1010
1011 /* parse another container, fails */
1012 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
1013 assert_int_equal(LY_EVALID, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL));
1014 ly_in_free(in, 0);
Michal Vasko7a266772024-01-23 11:02:38 +01001015 CHECK_LOG_CTX("Duplicate instance of \"cont\".", "/a:l1[a='val_a'][b='val_b'][c='1']/cont", 0);
Michal Vaskoa6139e02023-10-03 14:13:22 +02001016
1017 lyd_free_all(tree);
1018}
1019
Radek Krejcib4ac5a92020-11-23 17:54:33 +01001020int
1021main(void)
Radek Krejci509e2592019-05-15 16:30:48 +02001022{
1023 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +02001024 UTEST(test_leaf, setup),
1025 UTEST(test_anydata, setup),
Michal Vasko5b414dd2023-04-13 10:29:58 +02001026 UTEST(test_anyxml, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +02001027 UTEST(test_list, setup),
1028 UTEST(test_container, setup),
1029 UTEST(test_opaq, setup),
1030 UTEST(test_rpc, setup),
1031 UTEST(test_action, setup),
1032 UTEST(test_notification, setup),
1033 UTEST(test_reply, setup),
Michal Vaskoe0665742021-02-11 11:08:44 +01001034 UTEST(test_netconf_rpc, setup),
1035 UTEST(test_netconf_action, setup),
1036 UTEST(test_netconf_reply_or_notification, setup),
Michal Vasko820efe82023-05-12 15:47:43 +02001037 UTEST(test_restconf_rpc, setup),
1038 UTEST(test_restconf_reply, setup),
Michal Vasko45791ad2021-06-17 08:45:03 +02001039 UTEST(test_filter_attributes, setup),
aPiecek9cdb9e62021-05-18 09:46:20 +02001040 UTEST(test_data_skip, setup),
Michal Vaskodd03ff12023-09-11 10:30:48 +02001041 UTEST(test_metadata, setup),
Michal Vaskoa6139e02023-10-03 14:13:22 +02001042 UTEST(test_subtree, setup),
Radek Krejci509e2592019-05-15 16:30:48 +02001043 };
1044
1045 return cmocka_run_group_tests(tests, NULL, NULL);
1046}