blob: 271cc4be5b1fe7f8df6a01c3aec39c40d33031ec [file] [log] [blame]
Radek Krejci509e2592019-05-15 16:30:48 +02001/*
2 * @file test_parser_xml.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from parser_xml.c
5 *
Radek Iša56ca9e42020-09-08 18:42:00 +02006 * Copyright (c) 2019-2020 CESNET, z.s.p.o.
Radek Krejci509e2592019-05-15 16:30:48 +02007 *
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#define _UTEST_MAIN_
15#include "utests.h"
Radek Krejci509e2592019-05-15 16:30:48 +020016
Radek Krejci70593c12020-06-13 20:48:09 +020017#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020018#include "in.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020019#include "out.h"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010020#include "parser_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020021#include "printer_data.h"
Radek Krejci70593c12020-06-13 20:48:09 +020022#include "tree_data_internal.h"
23#include "tree_schema.h"
Radek Krejci509e2592019-05-15 16:30:48 +020024
25static int
26setup(void **state)
27{
Radek Iša56ca9e42020-09-08 18:42:00 +020028 const char *schema =
Radek Krejcib4ac5a92020-11-23 17:54:33 +010029 "module a {\n"
30 " namespace urn:tests:a;\n"
31 " prefix a;\n"
32 " yang-version 1.1;\n"
Michal Vaskodbf3e652022-10-21 08:46:25 +020033 " list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;}"
34 " leaf d {type string;}"
35 " container cont {leaf e {type boolean;}}"
36 " }"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010037 " leaf foo { type string;}\n"
38 " container c {\n"
39 " leaf x {type string;}\n"
40 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }\n"
41 " notification n1 { leaf nl {type string;}}}\n"
42 " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
43 " anydata any {config false;}\n"
44 " leaf foo2 { type string; default \"default-val\"; }\n"
45 " leaf foo3 { type uint32; }\n"
46 " notification n2;}";
Radek Krejci509e2592019-05-15 16:30:48 +020047
Radek Iša56ca9e42020-09-08 18:42:00 +020048 UTEST_SETUP;
Radek Krejci509e2592019-05-15 16:30:48 +020049
Radek Iša56ca9e42020-09-08 18:42:00 +020050 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
51 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci509e2592019-05-15 16:30:48 +020052
53 return 0;
54}
55
Radek Iša56ca9e42020-09-08 18:42:00 +020056#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
57 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci509e2592019-05-15 16:30:48 +020058
Radek Iša56ca9e42020-09-08 18:42:00 +020059#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
60 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
61 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
62 assert_null(MODEL)
Radek Krejci509e2592019-05-15 16:30:48 +020063
Radek Iša56ca9e42020-09-08 18:42:00 +020064#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
65 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, PRINT_OPTION)
Radek Krejci509e2592019-05-15 16:30:48 +020066
Radek Krejci509e2592019-05-15 16:30:48 +020067static void
68test_leaf(void **state)
69{
Radek Krejci509e2592019-05-15 16:30:48 +020070 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
71 struct lyd_node *tree;
72 struct lyd_node_term *leaf;
73
Radek Iša56ca9e42020-09-08 18:42:00 +020074 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020075
Radek Iša56ca9e42020-09-08 18:42:00 +020076 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
77 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
78 leaf = (struct lyd_node_term *)tree;
79 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
80
81 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
82 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010083 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020084 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010085 assert_true(leaf->flags & LYD_DEFAULT);
Radek Krejci509e2592019-05-15 16:30:48 +020086 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +010087
88 /* make foo2 explicit */
89 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Radek Iša56ca9e42020-09-08 18:42:00 +020090 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +010091 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010092 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020093 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
94 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010095 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020096 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010097 assert_false(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +010098 lyd_free_all(tree);
99
Radek Krejci1798aae2020-07-14 13:26:06 +0200100 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200101 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" "
102 "wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
103 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100104 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100105 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200106 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
107 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100108 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200109 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100110 assert_true(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +0100111 lyd_free_all(tree);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200112
113 /* invalid value */
114 data = "<l1 xmlns=\"urn:tests:a\"><a>val-a</a><b>val-b</b><c>1</c><cont><e>0</e></cont></l1>";
115 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
116 "Invalid boolean value \"0\".",
117 "Data location \"/a:l1[a='val-a'][b='val-b'][c='1']/cont/e\", line number 1.");
Radek Krejci509e2592019-05-15 16:30:48 +0200118}
119
Radek Krejciee4cab22019-07-17 17:07:47 +0200120static void
121test_anydata(void **state)
122{
Michal Vasko52927e22020-03-16 17:26:14 +0100123 const char *data;
Radek Krejciee4cab22019-07-17 17:07:47 +0200124 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200125
Radek Iša56ca9e42020-09-08 18:42:00 +0200126 data = "<any xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100127 " <element1>\n"
128 " <x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>\n"
129 " </element1>\n"
130 " <element1a/>\n"
131 "</any>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200132 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200133 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100134 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200135 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_SET_CONFIG, 1, "any",
136 1, LYS_ANYDATA, 0, 0, NULL, 0);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200137
Radek Iša56ca9e42020-09-08 18:42:00 +0200138 const char *data_expected =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100139 "<any xmlns=\"urn:tests:a\">\n"
140 " <element1>\n"
141 " <element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>\n"
142 " </element1>\n"
143 " <element1a/>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200144 "</any>\n";
145
146 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Radek Krejciee4cab22019-07-17 17:07:47 +0200147 lyd_free_all(tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200148}
149
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200150static void
151test_list(void **state)
152{
Radek Iša56ca9e42020-09-08 18:42:00 +0200153 const char *data;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200154 struct lyd_node *tree, *iter;
155 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200156 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200157
Radek Krejci710226d2019-07-24 17:24:59 +0200158 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200159 data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
160 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
161 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
162 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100163 list = (struct lyd_node_inner *)tree;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200164 LY_LIST_FOR(list->child, iter) {
165 assert_int_not_equal(0, iter->hash);
166 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200167 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200168
Michal Vasko9f96a052020-03-10 09:41:45 +0100169 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200170 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vaskodbf3e652022-10-21 08:46:25 +0200171 "List instance is missing its key \"a\".", "Data location \"/a:l1[b='b'][c='1']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100172
Radek Iša56ca9e42020-09-08 18:42:00 +0200173 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vaskodbf3e652022-10-21 08:46:25 +0200174 "List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100175
Radek Iša56ca9e42020-09-08 18:42:00 +0200176 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vaskodbf3e652022-10-21 08:46:25 +0200177 "List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100178
179 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200180 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 Vasko959f8d82022-06-16 07:51:50 +0200181 "Duplicate instance of \"c\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200182 "Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100183
Radek Krejci710226d2019-07-24 17:24:59 +0200184 /* keys order */
Radek Iša56ca9e42020-09-08 18:42:00 +0200185 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);
186 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
187 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100188 list = (struct lyd_node_inner *)tree;
189 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200190 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 +0100191 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200192 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 +0100193 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200194 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 +0100195 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200196 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Iša56ca9e42020-09-08 18:42:00 +0200197 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200198 lyd_free_all(tree);
199
Michal Vasko44685da2020-03-17 15:38:06 +0100200 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200201 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
202 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 +0100203 list = (struct lyd_node_inner *)tree;
204 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200205 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 +0100206 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200207 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 +0100208 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200209 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
210 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200211 lyd_free_all(tree);
212
Radek Iša56ca9e42020-09-08 18:42:00 +0200213 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vaskodbf3e652022-10-21 08:46:25 +0200214 "Invalid position of the key \"b\" in a list.", "Data location \"/a:l1[c='1']/b\", line number 1.");
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200215}
216
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200217static void
218test_container(void **state)
219{
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200220 struct lyd_node *tree;
221 struct lyd_node_inner *cont;
222
Radek Iša56ca9e42020-09-08 18:42:00 +0200223 CHECK_PARSE_LYD("<c xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
224 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 +0100225 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200226 assert_true(cont->flags & LYD_DEFAULT);
227 lyd_free_all(tree);
228
Radek Iša56ca9e42020-09-08 18:42:00 +0200229 CHECK_PARSE_LYD("<cp xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200230 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100231 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100232 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 +0200233 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100234 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200235 assert_false(cont->flags & LYD_DEFAULT);
236 lyd_free_all(tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200237}
238
Michal Vasko44685da2020-03-17 15:38:06 +0100239static void
240test_opaq(void **state)
241{
Michal Vasko44685da2020-03-17 15:38:06 +0100242 const char *data;
Michal Vasko44685da2020-03-17 15:38:06 +0100243 struct lyd_node *tree;
244
245 /* invalid value, no flags */
246 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200247 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200248 "Invalid type uint32 empty value.", "Schema location \"/a:foo3\", line number 1.");
Michal Vasko44685da2020-03-17 15:38:06 +0100249
250 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200251 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200252 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "foo3", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200253 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
Michal Vasko44685da2020-03-17 15:38:06 +0100254 lyd_free_all(tree);
255
Michal Vaskoda8fbbf2021-06-16 11:44:44 +0200256 /* list, opaq flag */
257 data = "<l1 xmlns=\"urn:tests:a\"/>";
258 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
259 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
260 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n");
261 lyd_free_all(tree);
262
Michal Vasko44685da2020-03-17 15:38:06 +0100263 /* missing key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200264 data = "<l1 xmlns=\"urn:tests:a\">\n"
265 " <a>val_a</a>\n"
266 " <b>val_b</b>\n"
267 " <d>val_d</d>\n"
268 "</l1>\n";
269 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200270 "List instance is missing its key \"c\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200271 "Data location \"/a:l1[a='val_a'][b='val_b']\", line number 5.");
Michal Vasko44685da2020-03-17 15:38:06 +0100272
273 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200274 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200275 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200276 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100277 lyd_free_all(tree);
278
279 /* invalid key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200280 data = "<l1 xmlns=\"urn:tests:a\">\n"
281 " <a>val_a</a>\n"
282 " <b>val_b</b>\n"
283 " <c>val_c</c>\n"
284 "</l1>\n";
285 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200286 "Invalid type int16 value \"val_c\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200287 "Data location \"/a:l1[a='val_a'][b='val_b']\", line number 4.");
Michal Vasko44685da2020-03-17 15:38:06 +0100288
289 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200290 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200291 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200292 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100293 lyd_free_all(tree);
294
Michal Vasko413c7f22020-05-05 12:34:06 +0200295 /* opaq flag and fail */
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 assert_int_equal(LY_EVALID, lyd_parse_data_mem(UTEST_LYCTX,
297 "<a xmlns=\"ns\">\n"
298 " <b>x</b>\n"
Michal Vaskoe137fc42021-07-22 11:53:13 +0200299 " <c xmld:id=\"D\">1</c>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200300 "</a>\n",
301 LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskoe137fc42021-07-22 11:53:13 +0200302 CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Line number 3.");
Michal Vasko44685da2020-03-17 15:38:06 +0100303}
304
Michal Vaskob36053d2020-03-26 15:49:30 +0100305static void
306test_rpc(void **state)
307{
Michal Vaskob36053d2020-03-26 15:49:30 +0100308 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200309 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100310 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100311 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200312 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
313 "configuration to the specified target configuration.";
314 const char *ref = "RFC 6241, Section 7.2";
315 const char *feats[] = {"writable-running", NULL};
Michal Vaskob36053d2020-03-26 15:49:30 +0100316
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100318
Michal Vasko2552ea32020-12-08 15:32:34 +0100319 data = "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
320 " <target>\n"
321 " <running/>\n"
322 " </target>\n"
323 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
324 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
325 " <a>val_a</a>\n"
326 " <b>val_b</b>\n"
327 " <c>val_c</c>\n"
328 " </l1>\n"
329 " <cp xmlns=\"urn:tests:a\">\n"
330 " <z nc:operation=\"delete\"/>\n"
331 " </cp>\n"
332 " </config>\n"
333 "</edit-config>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200334 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100335 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 +0200336 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100337
338 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200339
Radek Krejci2a9fc652021-01-22 17:44:34 +0100340 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200341 1, 0, 0, 1, "edit-config", LYS_RPC,
342 0, 0, 0, 0, 0, ref, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100343
Michal Vaskob36053d2020-03-26 15:49:30 +0100344 assert_non_null(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200345
Michal Vasko2552ea32020-12-08 15:32:34 +0100346 node = tree;
Radek Krejci2a9fc652021-01-22 17:44:34 +0100347 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200348 1, 0, 0, 1, "edit-config", LYS_RPC,
349 0, 0, 0, 0, 0, ref, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200350 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200351 dsc = "Inline Config content.";
Michal Vaskod1e53b92021-01-28 13:11:06 +0100352 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 +0200353
Michal Vasko1bf09392020-03-27 12:38:10 +0100354 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100355 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 +0200356 1, LYS_CONTAINER, 0, 0, NULL, 0);
357
Radek Krejcia1c1e542020-09-29 16:06:52 +0200358 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100359 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200360 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, "");
Michal Vaskob104f112020-07-17 09:54:54 +0200361 node = node->parent->next;
362 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200363 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
Michal Vaskob36053d2020-03-26 15:49:30 +0100364
Radek Iša56ca9e42020-09-08 18:42:00 +0200365 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100366 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
367 " <target>\n"
368 " <running/>\n"
369 " </target>\n"
370 " <config>\n"
371 " <cp xmlns=\"urn:tests:a\">\n"
372 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
373 " </cp>\n"
374 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
375 " <a>val_a</a>\n"
376 " <b>val_b</b>\n"
377 " <c>val_c</c>\n"
378 " </l1>\n"
379 " </config>\n"
380 "</edit-config>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200381
Michal Vaskob36053d2020-03-26 15:49:30 +0100382 lyd_free_all(tree);
383
384 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100385 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100386}
387
388static void
389test_action(void **state)
390{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100391 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200392 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100393 struct lyd_node *tree, *op;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100394
Michal Vasko2552ea32020-12-08 15:32:34 +0100395 data = "<c xmlns=\"urn:tests:a\">\n"
396 " <act>\n"
397 " <al>value</al>\n"
398 " </act>\n"
399 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200400 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100401 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 +0200402 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100403
404 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100405 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200406 1, 0, 0, 1, "act", LYS_ACTION,
407 1, 0, 0, 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100408
Radek Iša56ca9e42020-09-08 18:42:00 +0200409 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100410 "<c xmlns=\"urn:tests:a\">\n"
411 " <act>\n"
412 " <al>value</al>\n"
413 " </act>\n"
414 "</c>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200415
Michal Vaskoa8edff02020-03-27 14:47:01 +0100416 lyd_free_all(tree);
417
418 /* wrong namespace, element name, whatever... */
419 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100420}
421
422static void
423test_notification(void **state)
424{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100425 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200426 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100427 struct lyd_node *tree, *ntf;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100428
Michal Vasko2552ea32020-12-08 15:32:34 +0100429 data = "<c xmlns=\"urn:tests:a\">\n"
430 " <n1>\n"
431 " <nl>value</nl>\n"
432 " </n1>\n"
433 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200434 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100435 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 +0200436 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100437
438 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100439 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 +0100440
Michal Vasko2552ea32020-12-08 15:32:34 +0100441 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 +0100442
Radek Iša56ca9e42020-09-08 18:42:00 +0200443 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100444 lyd_free_all(tree);
445
446 /* top-level notif without envelope */
Radek Iša56ca9e42020-09-08 18:42:00 +0200447 data = "<n2 xmlns=\"urn:tests:a\"/>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200448 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100449 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 +0200450 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100451
452 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100453 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 +0100454
455 assert_non_null(tree);
456 assert_ptr_equal(ntf, tree);
457
Radek Iša56ca9e42020-09-08 18:42:00 +0200458 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100459 lyd_free_all(tree);
460
461 /* wrong namespace, element name, whatever... */
462 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100463}
464
Michal Vasko1ce933a2020-03-30 12:38:22 +0200465static void
466test_reply(void **state)
467{
Michal Vasko1ce933a2020-03-30 12:38:22 +0200468 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200469 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +0100470 struct lyd_node *tree, *op;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200471 const struct lyd_node *node;
472
Michal Vasko79135ae2020-12-16 10:08:35 +0100473 data = "<c xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100474 " <act>\n"
Michal Vasko2552ea32020-12-08 15:32:34 +0100475 " <al>25</al>\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100476 " </act>\n"
477 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200478 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100479 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 +0200480 ly_in_free(in, 0);
481
Michal Vasko1ce933a2020-03-30 12:38:22 +0200482 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200483
Radek Krejci2a9fc652021-01-22 17:44:34 +0100484 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200485 1, 0, 0, 1, "act", LYS_ACTION,
486 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200487 node = lyd_child(op);
Michal Vaskod1e53b92021-01-28 13:11:06 +0100488 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 +0200489
Michal Vasko2552ea32020-12-08 15:32:34 +0100490 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 +0200491
492 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200493 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_WITHSIBLINGS, "<al xmlns=\"urn:tests:a\">25</al>\n");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200494 lyd_free_all(tree);
495
496 /* wrong namespace, element name, whatever... */
497 /* TODO */
Michal Vasko1ce933a2020-03-30 12:38:22 +0200498}
499
Michal Vaskoe0665742021-02-11 11:08:44 +0100500static void
501test_netconf_rpc(void **state)
502{
503 const char *data;
504 struct ly_in *in;
505 struct lyd_node *tree, *op;
506 const struct lyd_node *node;
507 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
508 "configuration to the specified target configuration.";
509 const char *ref = "RFC 6241, Section 7.2";
510 const char *feats[] = {"writable-running", NULL};
511
512 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
513
514 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
515 "<edit-config>\n"
516 " <target>\n"
517 " <running/>\n"
518 " </target>\n"
519 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
520 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
521 " <a>val_a</a>\n"
522 " <b>val_b</b>\n"
523 " <c>val_c</c>\n"
524 " </l1>\n"
525 " <cp xmlns=\"urn:tests:a\">\n"
526 " <z nc:operation=\"delete\"/>\n"
527 " </cp>\n"
528 " </config>\n"
529 "</edit-config>\n"
530 "</rpc>\n";
531 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100532 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 +0100533 ly_in_free(in, 0);
534
535 assert_non_null(op);
536
537 node = tree;
Radek Krejci8df109d2021-04-23 12:19:08 +0200538 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 +0100539
540 assert_non_null(tree);
541
542 node = op;
543 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
544 1, 0, 0, 1, "edit-config", LYS_RPC,
545 0, 0, 0, 0, 0, ref, 0);
546 node = lyd_child(node)->next;
547 dsc = "Inline Config content.";
548 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
549
550 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100551 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Michal Vaskoe0665742021-02-11 11:08:44 +0100552 1, LYS_CONTAINER, 0, 0, NULL, 0);
553
554 node = lyd_child(node);
555 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200556 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_XML, "z", 0, 0, NULL, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100557 node = node->parent->next;
558 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200559 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100560
561 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
562 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n");
563 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
564 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
565 " <target>\n"
566 " <running/>\n"
567 " </target>\n"
568 " <config>\n"
569 " <cp xmlns=\"urn:tests:a\">\n"
570 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
571 " </cp>\n"
572 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
573 " <a>val_a</a>\n"
574 " <b>val_b</b>\n"
575 " <c>val_c</c>\n"
576 " </l1>\n"
577 " </config>\n"
578 "</edit-config>\n");
579
580 lyd_free_all(tree);
581 lyd_free_all(op);
582
583 /* wrong namespace, element name, whatever... */
584 /* TODO */
585}
586
587static void
588test_netconf_action(void **state)
589{
590 const char *data;
591 struct ly_in *in;
592 struct lyd_node *tree, *op;
593
594 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
595 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
596 "<c xmlns=\"urn:tests:a\">\n"
597 " <act>\n"
598 " <al>value</al>\n"
599 " </act>\n"
600 "</c>\n"
601 "</action>\n"
602 "</rpc>\n";
603 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100604 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 +0100605 ly_in_free(in, 0);
606
Radek Krejci8df109d2021-04-23 12:19:08 +0200607 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc", 0, 0, 0, 0, "");
608 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 +0100609
610 assert_non_null(op);
611 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
612 1, 0, 0, 1, "act", LYS_ACTION,
613 1, 0, 0, 1, 0, NULL, 0);
614
615 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
616 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\">\n"
617 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\"/>\n"
618 "</rpc>\n");
619 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
620 "<act xmlns=\"urn:tests:a\">\n"
621 " <al>value</al>\n"
622 "</act>\n");
623
624 lyd_free_all(tree);
625 lyd_free_all(op);
626
627 /* wrong namespace, element name, whatever... */
628 /* TODO */
629}
630
631static void
632test_netconf_reply_or_notification(void **state)
633{
634 const char *data;
635 struct ly_in *in;
636 struct lyd_node *action, *tree, *op, *op2;
637
638 /* parse the action */
639 data = "<c xmlns=\"urn:tests:a\">\n"
640 " <act>\n"
641 " <al>value</al>\n"
642 " </act>\n"
643 "</c>\n";
644 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100645 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 +0100646 ly_in_free(in, 0);
647
648 /* parse notification first */
649 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
650 "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
651 "<c xmlns=\"urn:tests:a\">\n"
652 " <n1>\n"
653 " <nl>value</nl>\n"
654 " </n1>\n"
655 "</c>\n"
656 "</notification>\n";
657 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100658 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 +0100659 ly_in_free(in, 0);
660
Radek Krejci8df109d2021-04-23 12:19:08 +0200661 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 1, LY_VALUE_XML, "notification", 0, 0, 0, 0, "");
662 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 +0100663 "2010-12-06T08:00:01Z");
664
665 assert_non_null(op2);
666 CHECK_LYSC_NOTIF((struct lysc_node_notif *)op2->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
667
668 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
669 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
670 " <eventTime>2010-12-06T08:00:01Z</eventTime>\n"
671 "</notification>\n");
672 CHECK_LYD_STRING(op2, LYD_PRINT_WITHSIBLINGS,
673 "<n1 xmlns=\"urn:tests:a\">\n"
674 " <nl>value</nl>\n"
675 "</n1>\n");
676
677 lyd_free_all(tree);
678 lyd_free_all(op2);
679
680 /* parse a data reply */
681 data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
682 " <al xmlns=\"urn:tests:a\">25</al>\n"
683 "</rpc-reply>\n";
684 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100685 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 +0100686 ly_in_free(in, 0);
687
Radek Krejci8df109d2021-04-23 12:19:08 +0200688 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 +0100689
Michal Vaskoe0665742021-02-11 11:08:44 +0100690 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
691 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\"/>\n");
Michal Vaskoe0665742021-02-11 11:08:44 +0100692
693 lyd_free_all(tree);
694 /* it was connected to the action, do not free */
695
696 /* parse an ok reply */
697 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
698 " <ok/>\n"
699 "</rpc-reply>\n";
700 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100701 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 +0100702 ly_in_free(in, 0);
703
Radek Krejci8df109d2021-04-23 12:19:08 +0200704 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
705 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 +0100706
Michal Vaskoe0665742021-02-11 11:08:44 +0100707 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
708
709 lyd_free_all(tree);
710
711 /* parse an error reply */
712 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
713 " <rpc-error>\n"
714 " <error-type>rpc</error-type>\n"
715 " <error-tag>missing-attribute</error-tag>\n"
716 " <error-severity>error</error-severity>\n"
717 " <error-info>\n"
718 " <bad-attribute>message-id</bad-attribute>\n"
719 " <bad-element>rpc</bad-element>\n"
720 " </error-info>\n"
721 " </rpc-error>\n"
722 "</rpc-reply>\n";
723 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100724 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 +0100725 ly_in_free(in, 0);
726
Radek Krejci8df109d2021-04-23 12:19:08 +0200727 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
728 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 +0100729
Michal Vaskoe0665742021-02-11 11:08:44 +0100730 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
731
732 lyd_free_all(tree);
733
734 lyd_free_all(action);
735
736 /* wrong namespace, element name, whatever... */
737 /* TODO */
738}
739
aPiecek9cdb9e62021-05-18 09:46:20 +0200740static void
Michal Vasko45791ad2021-06-17 08:45:03 +0200741test_filter_attributes(void **state)
742{
743 const char *data;
744 struct ly_in *in;
745 struct lyd_node *tree;
746 const struct lyd_node *node;
747 const char *dsc;
748 const char *ref = "RFC 6241, Section 7.7";
749 const char *feats[] = {"writable-running", NULL};
750
751 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
752
753 data = "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
754 " <filter type=\"xpath\" select=\"/*\"/>\n"
755 "</get>\n";
756 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
757 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
758 ly_in_free(in, 0);
759 assert_non_null(tree);
760
761 node = tree;
762 dsc = "Retrieve running configuration and device state information.";
763 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
764 1, 0, 0, 1, "get", LYS_RPC,
765 1, 0, 0, 0, 0, ref, 0);
766 node = lyd_child(node);
767 dsc = "This parameter specifies the portion of the system\nconfiguration and state data to retrieve.";
768 CHECK_LYSC_NODE(node->schema, dsc, 1, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "filter", 0, LYS_ANYXML, 1, 0, NULL, 0);
769
770 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
771 "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
772 " <filter type=\"xpath\" select=\"/*\"/>\n"
773 "</get>\n");
774
775 lyd_free_all(tree);
776}
777
778static void
aPiecek9cdb9e62021-05-18 09:46:20 +0200779test_data_skip(void **state)
780{
781 const char *data;
782 struct lyd_node *tree;
783 struct lyd_node_term *leaf;
784
785 /* add invalid data to a module that is not implemented */
786 data = "<foo xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\"><u/></foo>";
787 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
788 assert_null(tree);
789
790 /* add invalid data to a module that is implemented */
791 data = "<fooX xmlns=\"urn:tests:a\"><u/><list><value/></list></fooX>";
792 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
793 assert_null(tree);
794
795 /* first invalid, next valid */
796 data = "<fooX xmlns=\"urn:tests:a\"><u/></fooX> <foo xmlns=\"urn:tests:a\">foo value</foo>";
797 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
798 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
799 leaf = (struct lyd_node_term *)tree;
800 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
801 lyd_free_all(tree);
802}
803
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100804int
805main(void)
Radek Krejci509e2592019-05-15 16:30:48 +0200806{
807 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200808 UTEST(test_leaf, setup),
809 UTEST(test_anydata, setup),
810 UTEST(test_list, setup),
811 UTEST(test_container, setup),
812 UTEST(test_opaq, setup),
813 UTEST(test_rpc, setup),
814 UTEST(test_action, setup),
815 UTEST(test_notification, setup),
816 UTEST(test_reply, setup),
Michal Vaskoe0665742021-02-11 11:08:44 +0100817 UTEST(test_netconf_rpc, setup),
818 UTEST(test_netconf_action, setup),
819 UTEST(test_netconf_reply_or_notification, setup),
Michal Vasko45791ad2021-06-17 08:45:03 +0200820 UTEST(test_filter_attributes, setup),
aPiecek9cdb9e62021-05-18 09:46:20 +0200821 UTEST(test_data_skip, setup),
Radek Krejci509e2592019-05-15 16:30:48 +0200822 };
823
824 return cmocka_run_group_tests(tests, NULL, NULL);
825}