blob: a662828f9c8f3a9de773a0767c82e76f1943d32b [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 Vaskodbf3e652022-10-21 08:46:25 +020034 " list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;}"
35 " leaf d {type string;}"
36 " container cont {leaf e {type boolean;}}"
37 " }"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010038 " leaf foo { type string;}\n"
39 " container c {\n"
40 " leaf x {type string;}\n"
41 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }\n"
42 " notification n1 { leaf nl {type string;}}}\n"
43 " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
44 " anydata any {config false;}\n"
45 " leaf foo2 { type string; default \"default-val\"; }\n"
46 " leaf foo3 { type uint32; }\n"
47 " notification n2;}";
Radek Krejci509e2592019-05-15 16:30:48 +020048
Radek Iša56ca9e42020-09-08 18:42:00 +020049 UTEST_SETUP;
Radek Krejci509e2592019-05-15 16:30:48 +020050
Radek Iša56ca9e42020-09-08 18:42:00 +020051 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
52 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci509e2592019-05-15 16:30:48 +020053
54 return 0;
55}
56
Radek Iša56ca9e42020-09-08 18:42:00 +020057#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
58 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci509e2592019-05-15 16:30:48 +020059
Radek Iša56ca9e42020-09-08 18:42:00 +020060#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
61 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
62 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
63 assert_null(MODEL)
Radek Krejci509e2592019-05-15 16:30:48 +020064
Radek Iša56ca9e42020-09-08 18:42:00 +020065#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
66 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, PRINT_OPTION)
Radek Krejci509e2592019-05-15 16:30:48 +020067
Radek Krejci509e2592019-05-15 16:30:48 +020068static void
69test_leaf(void **state)
70{
Radek Krejci509e2592019-05-15 16:30:48 +020071 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
72 struct lyd_node *tree;
73 struct lyd_node_term *leaf;
74
Radek Iša56ca9e42020-09-08 18:42:00 +020075 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020076
Radek Iša56ca9e42020-09-08 18:42:00 +020077 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
78 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
79 leaf = (struct lyd_node_term *)tree;
80 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
81
82 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
83 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010084 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020085 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010086 assert_true(leaf->flags & LYD_DEFAULT);
Radek Krejci509e2592019-05-15 16:30:48 +020087 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +010088
89 /* make foo2 explicit */
90 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Radek Iša56ca9e42020-09-08 18:42:00 +020091 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +010092 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010093 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020094 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
95 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010096 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020097 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010098 assert_false(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +010099 lyd_free_all(tree);
100
Radek Krejci1798aae2020-07-14 13:26:06 +0200101 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200102 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" "
103 "wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
104 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100105 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100106 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200107 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
108 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100109 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200110 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100111 assert_true(leaf->flags & LYD_DEFAULT);
Michal Vasko8d544252020-03-02 10:19:52 +0100112 lyd_free_all(tree);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200113
114 /* invalid value */
115 data = "<l1 xmlns=\"urn:tests:a\"><a>val-a</a><b>val-b</b><c>1</c><cont><e>0</e></cont></l1>";
116 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
117 "Invalid boolean value \"0\".",
118 "Data location \"/a:l1[a='val-a'][b='val-b'][c='1']/cont/e\", line number 1.");
Radek Krejci509e2592019-05-15 16:30:48 +0200119}
120
Radek Krejciee4cab22019-07-17 17:07:47 +0200121static void
122test_anydata(void **state)
123{
Michal Vasko52927e22020-03-16 17:26:14 +0100124 const char *data;
Radek Krejciee4cab22019-07-17 17:07:47 +0200125 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200126
Radek Iša56ca9e42020-09-08 18:42:00 +0200127 data = "<any xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100128 " <element1>\n"
129 " <x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>\n"
130 " </element1>\n"
131 " <element1a/>\n"
132 "</any>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200133 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200134 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100135 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200136 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_SET_CONFIG, 1, "any",
137 1, LYS_ANYDATA, 0, 0, NULL, 0);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200138
Radek Iša56ca9e42020-09-08 18:42:00 +0200139 const char *data_expected =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100140 "<any xmlns=\"urn:tests:a\">\n"
141 " <element1>\n"
142 " <element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>\n"
143 " </element1>\n"
144 " <element1a/>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200145 "</any>\n";
146
147 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Radek Krejciee4cab22019-07-17 17:07:47 +0200148 lyd_free_all(tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200149}
150
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200151static void
152test_list(void **state)
153{
Radek Iša56ca9e42020-09-08 18:42:00 +0200154 const char *data;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200155 struct lyd_node *tree, *iter;
156 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200157 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200158
Radek Krejci710226d2019-07-24 17:24:59 +0200159 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200160 data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
161 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
162 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
163 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100164 list = (struct lyd_node_inner *)tree;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200165 LY_LIST_FOR(list->child, iter) {
166 assert_int_not_equal(0, iter->hash);
167 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200168 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200169
Michal Vasko9f96a052020-03-10 09:41:45 +0100170 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200171 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 +0200172 "List instance is missing its key \"a\".", "Data location \"/a:l1[b='b'][c='1']\", line number 1.");
Michal Vasko62af3692023-02-09 14:00:09 +0100173 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Michal Vasko9f96a052020-03-10 09:41:45 +0100174
Radek Iša56ca9e42020-09-08 18:42:00 +0200175 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 +0200176 "List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100177
Radek Iša56ca9e42020-09-08 18:42:00 +0200178 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 +0200179 "List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1.");
Michal Vasko62af3692023-02-09 14:00:09 +0100180 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
Michal Vasko9f96a052020-03-10 09:41:45 +0100181
182 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200183 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 +0200184 "Duplicate instance of \"c\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200185 "Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
Michal Vasko62af3692023-02-09 14:00:09 +0100186 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
187 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Michal Vasko9f96a052020-03-10 09:41:45 +0100188
Radek Krejci710226d2019-07-24 17:24:59 +0200189 /* keys order */
Radek Iša56ca9e42020-09-08 18:42:00 +0200190 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);
191 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
192 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100193 list = (struct lyd_node_inner *)tree;
194 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200195 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 +0100196 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200197 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 +0100198 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200199 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 +0100200 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Michal Vaskodbf3e652022-10-21 08:46:25 +0200201 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 +0200202 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200203 lyd_free_all(tree);
204
Michal Vasko44685da2020-03-17 15:38:06 +0100205 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200206 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
207 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 +0100208 list = (struct lyd_node_inner *)tree;
209 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200210 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 +0100211 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200212 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 +0100213 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200214 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
215 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
Michal Vasko62af3692023-02-09 14:00:09 +0100216 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200217 lyd_free_all(tree);
218
Radek Iša56ca9e42020-09-08 18:42:00 +0200219 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vaskodbf3e652022-10-21 08:46:25 +0200220 "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 +0200221}
222
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200223static void
224test_container(void **state)
225{
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200226 struct lyd_node *tree;
227 struct lyd_node_inner *cont;
228
Radek Iša56ca9e42020-09-08 18:42:00 +0200229 CHECK_PARSE_LYD("<c xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
230 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 +0100231 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200232 assert_true(cont->flags & LYD_DEFAULT);
233 lyd_free_all(tree);
234
Radek Iša56ca9e42020-09-08 18:42:00 +0200235 CHECK_PARSE_LYD("<cp xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200236 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100237 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100238 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 +0200239 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100240 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200241 assert_false(cont->flags & LYD_DEFAULT);
242 lyd_free_all(tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200243}
244
Michal Vasko44685da2020-03-17 15:38:06 +0100245static void
246test_opaq(void **state)
247{
Michal Vasko44685da2020-03-17 15:38:06 +0100248 const char *data;
Michal Vasko44685da2020-03-17 15:38:06 +0100249 struct lyd_node *tree;
250
251 /* invalid value, no flags */
252 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200253 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200254 "Invalid type uint32 empty value.", "Schema location \"/a:foo3\", line number 1.");
Michal Vasko44685da2020-03-17 15:38:06 +0100255
256 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200257 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200258 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 +0200259 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
Michal Vasko44685da2020-03-17 15:38:06 +0100260 lyd_free_all(tree);
261
Michal Vaskoda8fbbf2021-06-16 11:44:44 +0200262 /* list, opaq flag */
263 data = "<l1 xmlns=\"urn:tests:a\"/>";
264 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
265 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
266 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n");
267 lyd_free_all(tree);
268
Michal Vasko44685da2020-03-17 15:38:06 +0100269 /* missing key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200270 data = "<l1 xmlns=\"urn:tests:a\">\n"
271 " <a>val_a</a>\n"
272 " <b>val_b</b>\n"
273 " <d>val_d</d>\n"
274 "</l1>\n";
275 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200276 "List instance is missing its key \"c\".",
Michal Vaskodbf3e652022-10-21 08:46:25 +0200277 "Data location \"/a:l1[a='val_a'][b='val_b']\", line number 5.");
Michal Vasko44685da2020-03-17 15:38:06 +0100278
279 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200280 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200281 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 +0200282 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100283 lyd_free_all(tree);
284
285 /* invalid key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200286 data = "<l1 xmlns=\"urn:tests:a\">\n"
287 " <a>val_a</a>\n"
288 " <b>val_b</b>\n"
289 " <c>val_c</c>\n"
290 "</l1>\n";
291 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200292 "Invalid type int16 value \"val_c\".",
Michal Vaskoa4dfb3c2022-10-25 14:59:31 +0200293 "Data location \"/a:l1[a='val_a'][b='val_b']/c\", line number 4.");
Michal Vasko44685da2020-03-17 15:38:06 +0100294
295 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200297 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 +0200298 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100299 lyd_free_all(tree);
300
Michal Vasko413c7f22020-05-05 12:34:06 +0200301 /* opaq flag and fail */
Radek Iša56ca9e42020-09-08 18:42:00 +0200302 assert_int_equal(LY_EVALID, lyd_parse_data_mem(UTEST_LYCTX,
303 "<a xmlns=\"ns\">\n"
304 " <b>x</b>\n"
Michal Vaskoe137fc42021-07-22 11:53:13 +0200305 " <c xmld:id=\"D\">1</c>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 "</a>\n",
307 LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskoe137fc42021-07-22 11:53:13 +0200308 CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Line number 3.");
Michal Vasko44685da2020-03-17 15:38:06 +0100309}
310
Michal Vaskob36053d2020-03-26 15:49:30 +0100311static void
312test_rpc(void **state)
313{
Michal Vaskob36053d2020-03-26 15:49:30 +0100314 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200315 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100316 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100317 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200318 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
319 "configuration to the specified target configuration.";
320 const char *ref = "RFC 6241, Section 7.2";
321 const char *feats[] = {"writable-running", NULL};
Michal Vaskob36053d2020-03-26 15:49:30 +0100322
Radek Iša56ca9e42020-09-08 18:42:00 +0200323 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100324
Michal Vasko2552ea32020-12-08 15:32:34 +0100325 data = "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
326 " <target>\n"
327 " <running/>\n"
328 " </target>\n"
329 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
330 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
331 " <a>val_a</a>\n"
332 " <b>val_b</b>\n"
333 " <c>val_c</c>\n"
334 " </l1>\n"
335 " <cp xmlns=\"urn:tests:a\">\n"
336 " <z nc:operation=\"delete\"/>\n"
337 " </cp>\n"
338 " </config>\n"
339 "</edit-config>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200340 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100341 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 +0200342 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100343
344 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200345
Radek Krejci2a9fc652021-01-22 17:44:34 +0100346 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200347 1, 0, 0, 1, "edit-config", LYS_RPC,
348 0, 0, 0, 0, 0, ref, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100349
Michal Vaskob36053d2020-03-26 15:49:30 +0100350 assert_non_null(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200351
Michal Vasko2552ea32020-12-08 15:32:34 +0100352 node = tree;
Radek Krejci2a9fc652021-01-22 17:44:34 +0100353 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200354 1, 0, 0, 1, "edit-config", LYS_RPC,
355 0, 0, 0, 0, 0, ref, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200356 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200357 dsc = "Inline Config content.";
Michal Vaskod1e53b92021-01-28 13:11:06 +0100358 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 +0200359
Michal Vasko1bf09392020-03-27 12:38:10 +0100360 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100361 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 +0200362 1, LYS_CONTAINER, 0, 0, NULL, 0);
363
Radek Krejcia1c1e542020-09-29 16:06:52 +0200364 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100365 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200366 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 +0200367 node = node->parent->next;
368 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200369 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 +0100370
Radek Iša56ca9e42020-09-08 18:42:00 +0200371 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100372 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
373 " <target>\n"
374 " <running/>\n"
375 " </target>\n"
376 " <config>\n"
377 " <cp xmlns=\"urn:tests:a\">\n"
378 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
379 " </cp>\n"
380 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
381 " <a>val_a</a>\n"
382 " <b>val_b</b>\n"
383 " <c>val_c</c>\n"
384 " </l1>\n"
385 " </config>\n"
386 "</edit-config>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200387
Michal Vaskob36053d2020-03-26 15:49:30 +0100388 lyd_free_all(tree);
389
390 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100391 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100392}
393
394static void
395test_action(void **state)
396{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100397 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200398 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100399 struct lyd_node *tree, *op;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100400
Michal Vasko2552ea32020-12-08 15:32:34 +0100401 data = "<c xmlns=\"urn:tests:a\">\n"
402 " <act>\n"
403 " <al>value</al>\n"
404 " </act>\n"
405 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200406 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100407 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 +0200408 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100409
410 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100411 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200412 1, 0, 0, 1, "act", LYS_ACTION,
413 1, 0, 0, 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100414
Radek Iša56ca9e42020-09-08 18:42:00 +0200415 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100416 "<c xmlns=\"urn:tests:a\">\n"
417 " <act>\n"
418 " <al>value</al>\n"
419 " </act>\n"
420 "</c>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200421
Michal Vaskoa8edff02020-03-27 14:47:01 +0100422 lyd_free_all(tree);
423
424 /* wrong namespace, element name, whatever... */
425 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100426}
427
428static void
429test_notification(void **state)
430{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100431 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200432 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100433 struct lyd_node *tree, *ntf;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100434
Michal Vasko2552ea32020-12-08 15:32:34 +0100435 data = "<c xmlns=\"urn:tests:a\">\n"
436 " <n1>\n"
437 " <nl>value</nl>\n"
438 " </n1>\n"
439 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200440 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100441 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 +0200442 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100443
444 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100445 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 +0100446
Michal Vasko2552ea32020-12-08 15:32:34 +0100447 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 +0100448
Radek Iša56ca9e42020-09-08 18:42:00 +0200449 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100450 lyd_free_all(tree);
451
452 /* top-level notif without envelope */
Radek Iša56ca9e42020-09-08 18:42:00 +0200453 data = "<n2 xmlns=\"urn:tests:a\"/>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200454 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100455 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 +0200456 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100457
458 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100459 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 +0100460
461 assert_non_null(tree);
462 assert_ptr_equal(ntf, tree);
463
Radek Iša56ca9e42020-09-08 18:42:00 +0200464 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100465 lyd_free_all(tree);
466
467 /* wrong namespace, element name, whatever... */
468 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100469}
470
Michal Vasko1ce933a2020-03-30 12:38:22 +0200471static void
472test_reply(void **state)
473{
Michal Vasko1ce933a2020-03-30 12:38:22 +0200474 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200475 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +0100476 struct lyd_node *tree, *op;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200477 const struct lyd_node *node;
478
Michal Vasko79135ae2020-12-16 10:08:35 +0100479 data = "<c xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100480 " <act>\n"
Michal Vasko2552ea32020-12-08 15:32:34 +0100481 " <al>25</al>\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100482 " </act>\n"
483 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200484 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100485 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 +0200486 ly_in_free(in, 0);
487
Michal Vasko1ce933a2020-03-30 12:38:22 +0200488 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200489
Radek Krejci2a9fc652021-01-22 17:44:34 +0100490 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200491 1, 0, 0, 1, "act", LYS_ACTION,
492 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200493 node = lyd_child(op);
Michal Vaskod1e53b92021-01-28 13:11:06 +0100494 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 +0200495
Michal Vasko2552ea32020-12-08 15:32:34 +0100496 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 +0200497
498 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200499 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_WITHSIBLINGS, "<al xmlns=\"urn:tests:a\">25</al>\n");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200500 lyd_free_all(tree);
501
502 /* wrong namespace, element name, whatever... */
503 /* TODO */
Michal Vasko1ce933a2020-03-30 12:38:22 +0200504}
505
Michal Vaskoe0665742021-02-11 11:08:44 +0100506static void
507test_netconf_rpc(void **state)
508{
509 const char *data;
510 struct ly_in *in;
511 struct lyd_node *tree, *op;
512 const struct lyd_node *node;
513 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
514 "configuration to the specified target configuration.";
515 const char *ref = "RFC 6241, Section 7.2";
516 const char *feats[] = {"writable-running", NULL};
517
518 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
519
520 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
521 "<edit-config>\n"
522 " <target>\n"
523 " <running/>\n"
524 " </target>\n"
525 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
526 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
527 " <a>val_a</a>\n"
528 " <b>val_b</b>\n"
529 " <c>val_c</c>\n"
530 " </l1>\n"
531 " <cp xmlns=\"urn:tests:a\">\n"
532 " <z nc:operation=\"delete\"/>\n"
533 " </cp>\n"
534 " </config>\n"
535 "</edit-config>\n"
536 "</rpc>\n";
537 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100538 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 +0100539 ly_in_free(in, 0);
540
541 assert_non_null(op);
542
543 node = tree;
Radek Krejci8df109d2021-04-23 12:19:08 +0200544 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 +0100545
546 assert_non_null(tree);
547
548 node = op;
549 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
550 1, 0, 0, 1, "edit-config", LYS_RPC,
551 0, 0, 0, 0, 0, ref, 0);
552 node = lyd_child(node)->next;
553 dsc = "Inline Config content.";
554 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
555
556 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100557 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Michal Vaskoe0665742021-02-11 11:08:44 +0100558 1, LYS_CONTAINER, 0, 0, NULL, 0);
559
560 node = lyd_child(node);
561 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200562 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 +0100563 node = node->parent->next;
564 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200565 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 +0100566
567 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
568 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n");
569 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
570 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
571 " <target>\n"
572 " <running/>\n"
573 " </target>\n"
574 " <config>\n"
575 " <cp xmlns=\"urn:tests:a\">\n"
576 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
577 " </cp>\n"
578 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
579 " <a>val_a</a>\n"
580 " <b>val_b</b>\n"
581 " <c>val_c</c>\n"
582 " </l1>\n"
583 " </config>\n"
584 "</edit-config>\n");
585
586 lyd_free_all(tree);
587 lyd_free_all(op);
588
589 /* wrong namespace, element name, whatever... */
590 /* TODO */
591}
592
593static void
594test_netconf_action(void **state)
595{
596 const char *data;
597 struct ly_in *in;
598 struct lyd_node *tree, *op;
599
600 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
601 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
602 "<c xmlns=\"urn:tests:a\">\n"
603 " <act>\n"
604 " <al>value</al>\n"
605 " </act>\n"
606 "</c>\n"
607 "</action>\n"
608 "</rpc>\n";
609 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100610 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 +0100611 ly_in_free(in, 0);
612
Radek Krejci8df109d2021-04-23 12:19:08 +0200613 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc", 0, 0, 0, 0, "");
614 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 +0100615
616 assert_non_null(op);
617 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
618 1, 0, 0, 1, "act", LYS_ACTION,
619 1, 0, 0, 1, 0, NULL, 0);
620
621 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
622 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\">\n"
623 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\"/>\n"
624 "</rpc>\n");
625 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
626 "<act xmlns=\"urn:tests:a\">\n"
627 " <al>value</al>\n"
628 "</act>\n");
629
630 lyd_free_all(tree);
631 lyd_free_all(op);
632
633 /* wrong namespace, element name, whatever... */
634 /* TODO */
635}
636
637static void
638test_netconf_reply_or_notification(void **state)
639{
640 const char *data;
641 struct ly_in *in;
642 struct lyd_node *action, *tree, *op, *op2;
643
644 /* parse the action */
645 data = "<c xmlns=\"urn:tests:a\">\n"
646 " <act>\n"
647 " <al>value</al>\n"
648 " </act>\n"
649 "</c>\n";
650 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100651 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 +0100652 ly_in_free(in, 0);
653
654 /* parse notification first */
655 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
656 "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
657 "<c xmlns=\"urn:tests:a\">\n"
658 " <n1>\n"
659 " <nl>value</nl>\n"
660 " </n1>\n"
661 "</c>\n"
662 "</notification>\n";
663 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100664 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 +0100665 ly_in_free(in, 0);
666
Radek Krejci8df109d2021-04-23 12:19:08 +0200667 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 1, LY_VALUE_XML, "notification", 0, 0, 0, 0, "");
668 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 +0100669 "2010-12-06T08:00:01Z");
670
671 assert_non_null(op2);
672 CHECK_LYSC_NOTIF((struct lysc_node_notif *)op2->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
673
674 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
675 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
676 " <eventTime>2010-12-06T08:00:01Z</eventTime>\n"
677 "</notification>\n");
678 CHECK_LYD_STRING(op2, LYD_PRINT_WITHSIBLINGS,
679 "<n1 xmlns=\"urn:tests:a\">\n"
680 " <nl>value</nl>\n"
681 "</n1>\n");
682
683 lyd_free_all(tree);
684 lyd_free_all(op2);
685
686 /* parse a data reply */
687 data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
688 " <al xmlns=\"urn:tests:a\">25</al>\n"
689 "</rpc-reply>\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, op, in, LYD_XML, LYD_TYPE_REPLY_NETCONF, &tree, NULL));
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, 0, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
Michal Vaskoe0665742021-02-11 11:08:44 +0100695
Michal Vaskoe0665742021-02-11 11:08:44 +0100696 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
697 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\"/>\n");
Michal Vaskoe0665742021-02-11 11:08:44 +0100698
699 lyd_free_all(tree);
700 /* it was connected to the action, do not free */
701
702 /* parse an ok reply */
703 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
704 " <ok/>\n"
705 "</rpc-reply>\n";
706 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100707 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 +0100708 ly_in_free(in, 0);
709
Radek Krejci8df109d2021-04-23 12:19:08 +0200710 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
711 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 +0100712
Michal Vaskoe0665742021-02-11 11:08:44 +0100713 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
714
715 lyd_free_all(tree);
716
717 /* parse an error reply */
718 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
719 " <rpc-error>\n"
720 " <error-type>rpc</error-type>\n"
721 " <error-tag>missing-attribute</error-tag>\n"
722 " <error-severity>error</error-severity>\n"
723 " <error-info>\n"
724 " <bad-attribute>message-id</bad-attribute>\n"
725 " <bad-element>rpc</bad-element>\n"
726 " </error-info>\n"
727 " </rpc-error>\n"
728 "</rpc-reply>\n";
729 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100730 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 +0100731 ly_in_free(in, 0);
732
Radek Krejci8df109d2021-04-23 12:19:08 +0200733 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
734 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 +0100735
Michal Vaskoe0665742021-02-11 11:08:44 +0100736 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
737
738 lyd_free_all(tree);
739
740 lyd_free_all(action);
741
742 /* wrong namespace, element name, whatever... */
743 /* TODO */
744}
745
aPiecek9cdb9e62021-05-18 09:46:20 +0200746static void
Michal Vasko45791ad2021-06-17 08:45:03 +0200747test_filter_attributes(void **state)
748{
749 const char *data;
750 struct ly_in *in;
751 struct lyd_node *tree;
752 const struct lyd_node *node;
753 const char *dsc;
754 const char *ref = "RFC 6241, Section 7.7";
755 const char *feats[] = {"writable-running", NULL};
756
757 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100758 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "notifications", "2008-07-14", NULL)));
Michal Vasko45791ad2021-06-17 08:45:03 +0200759
760 data = "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
761 " <filter type=\"xpath\" select=\"/*\"/>\n"
762 "</get>\n";
763 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
764 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
765 ly_in_free(in, 0);
766 assert_non_null(tree);
767
768 node = tree;
769 dsc = "Retrieve running configuration and device state information.";
770 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
771 1, 0, 0, 1, "get", LYS_RPC,
772 1, 0, 0, 0, 0, ref, 0);
773 node = lyd_child(node);
774 dsc = "This parameter specifies the portion of the system\nconfiguration and state data to retrieve.";
775 CHECK_LYSC_NODE(node->schema, dsc, 1, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "filter", 0, LYS_ANYXML, 1, 0, NULL, 0);
776
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100777 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
778 lyd_free_all(tree);
Michal Vasko45791ad2021-06-17 08:45:03 +0200779
Michal Vasko1b2a3f42022-12-20 09:38:28 +0100780 data = "<create-subscription xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
781 " <filter type=\"subtree\">\n"
782 " <inner-node xmlns=\"my:urn\"/>\n"
783 " </filter>\n"
784 "</create-subscription>\n";
785 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
786 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
787 ly_in_free(in, 0);
788 assert_non_null(tree);
789
790 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko45791ad2021-06-17 08:45:03 +0200791 lyd_free_all(tree);
792}
793
794static void
aPiecek9cdb9e62021-05-18 09:46:20 +0200795test_data_skip(void **state)
796{
797 const char *data;
798 struct lyd_node *tree;
799 struct lyd_node_term *leaf;
800
801 /* add invalid data to a module that is not implemented */
802 data = "<foo xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\"><u/></foo>";
803 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
804 assert_null(tree);
805
806 /* add invalid data to a module that is implemented */
807 data = "<fooX xmlns=\"urn:tests:a\"><u/><list><value/></list></fooX>";
808 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
809 assert_null(tree);
810
811 /* first invalid, next valid */
812 data = "<fooX xmlns=\"urn:tests:a\"><u/></fooX> <foo xmlns=\"urn:tests:a\">foo value</foo>";
813 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
814 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
815 leaf = (struct lyd_node_term *)tree;
816 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
817 lyd_free_all(tree);
818}
819
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100820int
821main(void)
Radek Krejci509e2592019-05-15 16:30:48 +0200822{
823 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200824 UTEST(test_leaf, setup),
825 UTEST(test_anydata, setup),
826 UTEST(test_list, setup),
827 UTEST(test_container, setup),
828 UTEST(test_opaq, setup),
829 UTEST(test_rpc, setup),
830 UTEST(test_action, setup),
831 UTEST(test_notification, setup),
832 UTEST(test_reply, setup),
Michal Vaskoe0665742021-02-11 11:08:44 +0100833 UTEST(test_netconf_rpc, setup),
834 UTEST(test_netconf_action, setup),
835 UTEST(test_netconf_reply_or_notification, setup),
Michal Vasko45791ad2021-06-17 08:45:03 +0200836 UTEST(test_filter_attributes, setup),
aPiecek9cdb9e62021-05-18 09:46:20 +0200837 UTEST(test_data_skip, setup),
Radek Krejci509e2592019-05-15 16:30:48 +0200838 };
839
840 return cmocka_run_group_tests(tests, NULL, NULL);
841}