blob: 4e5cc2ef88fbfca8fc4d77a325aef5dae57bc7f8 [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"
33 " list l1 {\n"
34 " key \"a b c\";\n"
35 " leaf a {type string;}\n"
36 " leaf b {type string;}\n"
37 " leaf c {type int16;}\n"
38 " leaf d {type string;}}\n"
39 " leaf foo { type string;}\n"
40 " container c {\n"
41 " leaf x {type string;}\n"
42 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }\n"
43 " notification n1 { leaf nl {type string;}}}\n"
44 " container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}\n"
45 " anydata any {config false;}\n"
46 " leaf foo2 { type string; default \"default-val\"; }\n"
47 " leaf foo3 { type uint32; }\n"
48 " notification n2;}";
Radek Krejci509e2592019-05-15 16:30:48 +020049
Radek Iša56ca9e42020-09-08 18:42:00 +020050 UTEST_SETUP;
Radek Krejci509e2592019-05-15 16:30:48 +020051
Radek Iša56ca9e42020-09-08 18:42:00 +020052 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
53 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci509e2592019-05-15 16:30:48 +020054
55 return 0;
56}
57
Radek Iša56ca9e42020-09-08 18:42:00 +020058#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
59 CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci509e2592019-05-15 16:30:48 +020060
Radek Iša56ca9e42020-09-08 18:42:00 +020061#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
62 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
63 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
64 assert_null(MODEL)
Radek Krejci509e2592019-05-15 16:30:48 +020065
Radek Iša56ca9e42020-09-08 18:42:00 +020066#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
67 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_XML, PRINT_OPTION)
Radek Krejci509e2592019-05-15 16:30:48 +020068
Radek Krejci509e2592019-05-15 16:30:48 +020069static void
70test_leaf(void **state)
71{
Radek Krejci509e2592019-05-15 16:30:48 +020072 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
73 struct lyd_node *tree;
74 struct lyd_node_term *leaf;
75
Radek Iša56ca9e42020-09-08 18:42:00 +020076 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci509e2592019-05-15 16:30:48 +020077
Radek Iša56ca9e42020-09-08 18:42:00 +020078 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
79 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
80 leaf = (struct lyd_node_term *)tree;
81 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
82
83 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
84 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010085 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020086 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +010087 assert_true(leaf->flags & LYD_DEFAULT);
88
Radek Krejci509e2592019-05-15 16:30:48 +020089 lyd_free_all(tree);
Michal Vasko8d544252020-03-02 10:19:52 +010090
91 /* make foo2 explicit */
92 data = "<foo2 xmlns=\"urn:tests:a\">default-val</foo2>";
Radek Iša56ca9e42020-09-08 18:42:00 +020093 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +010094 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010095 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020096 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
97 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010098 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020099 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100100 assert_false(leaf->flags & LYD_DEFAULT);
101
102 lyd_free_all(tree);
103
Radek Krejci1798aae2020-07-14 13:26:06 +0200104 /* parse foo2 but make it implicit, skip metadata xxx from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200105 data = "<foo2 xmlns=\"urn:tests:a\" xmlns:wd=\"urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults\" "
106 "wd:default=\"true\" xmlns:x=\"urn:x\" x:xxx=\"false\">default-val</foo2>";
107 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Michal Vasko8d544252020-03-02 10:19:52 +0100108 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100109 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200110 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
111 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100112 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200113 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Michal Vasko8d544252020-03-02 10:19:52 +0100114 assert_true(leaf->flags & LYD_DEFAULT);
115
116 lyd_free_all(tree);
Radek Krejci509e2592019-05-15 16:30:48 +0200117}
118
Radek Krejciee4cab22019-07-17 17:07:47 +0200119static void
120test_anydata(void **state)
121{
Michal Vasko52927e22020-03-16 17:26:14 +0100122 const char *data;
Radek Krejciee4cab22019-07-17 17:07:47 +0200123 struct lyd_node *tree;
Radek Krejciee4cab22019-07-17 17:07:47 +0200124
Radek Iša56ca9e42020-09-08 18:42:00 +0200125 data = "<any xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100126 " <element1>\n"
127 " <x:element2 x:attr2=\"test\" xmlns:a=\"urn:tests:a\" xmlns:x=\"urn:x\">a:data</x:element2>\n"
128 " </element1>\n"
129 " <element1a/>\n"
130 "</any>\n";
Radek Iša56ca9e42020-09-08 18:42:00 +0200131 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200132 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100133 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200134 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR | LYS_SET_CONFIG, 1, "any",
135 1, LYS_ANYDATA, 0, 0, NULL, 0);
136 const char *data_expected =
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100137 "<any xmlns=\"urn:tests:a\">\n"
138 " <element1>\n"
139 " <element2 xmlns=\"urn:x\" xmlns:x=\"urn:x\" x:attr2=\"test\" xmlns:a=\"urn:tests:a\">a:data</element2>\n"
140 " </element1>\n"
141 " <element1a/>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200142 "</any>\n";
143
144 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data_expected);
Radek Krejciee4cab22019-07-17 17:07:47 +0200145
146 lyd_free_all(tree);
Radek Krejciee4cab22019-07-17 17:07:47 +0200147}
148
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200149static void
150test_list(void **state)
151{
Radek Iša56ca9e42020-09-08 18:42:00 +0200152 const char *data;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200153 struct lyd_node *tree, *iter;
154 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200155 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200156
Radek Krejci710226d2019-07-24 17:24:59 +0200157 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>1</c></l1>";
159 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
160 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
161 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100162 list = (struct lyd_node_inner *)tree;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200163 LY_LIST_FOR(list->child, iter) {
164 assert_int_not_equal(0, iter->hash);
165 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200166 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200167
Michal Vasko9f96a052020-03-10 09:41:45 +0100168 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200169 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200170 "List instance is missing its key \"a\".", "Schema location \"/a:l1\", data location \"/a:l1[b='b'][c='1']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100171
Radek Iša56ca9e42020-09-08 18:42:00 +0200172 PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200173 "List instance is missing its key \"b\".", "Schema location \"/a:l1\", data location \"/a:l1[a='a']\", line number 1.");
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\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200176 "List instance is missing its key \"c\".", "Schema location \"/a:l1\", data location \"/a:l1[a='a'][b='b']\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100177
178 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 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 +0200180 "Duplicate instance of \"c\".",
181 "Schema location \"/a:l1/c\", data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
Michal Vasko9f96a052020-03-10 09:41:45 +0100182
Radek Krejci710226d2019-07-24 17:24:59 +0200183 /* keys order */
Radek Iša56ca9e42020-09-08 18:42:00 +0200184 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);
185 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
186 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100187 list = (struct lyd_node_inner *)tree;
188 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200189 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 +0100190 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200191 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 +0100192 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 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 +0100194 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200195 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 0, LYS_LEAF, 1, 0, NULL, 0);
196 CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200197 lyd_free_all(tree);
198
Michal Vasko44685da2020-03-17 15:38:06 +0100199 data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200200 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
201 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 +0100202 list = (struct lyd_node_inner *)tree;
203 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200204 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 +0100205 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200206 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 +0100207 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200208 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
209 CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
Radek Krejci710226d2019-07-24 17:24:59 +0200210 lyd_free_all(tree);
211
Radek Iša56ca9e42020-09-08 18:42:00 +0200212 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200213 "Invalid position of the key \"b\" in a list.", "Schema location \"/a:l1/b\", data location \"/a:b\", line number 1.");
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200214}
215
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200216static void
217test_container(void **state)
218{
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200219 struct lyd_node *tree;
220 struct lyd_node_inner *cont;
221
Radek Iša56ca9e42020-09-08 18:42:00 +0200222 CHECK_PARSE_LYD("<c xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
223 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 +0100224 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200225 assert_true(cont->flags & LYD_DEFAULT);
226 lyd_free_all(tree);
227
Radek Iša56ca9e42020-09-08 18:42:00 +0200228 CHECK_PARSE_LYD("<cp xmlns=\"urn:tests:a\"/>", 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200229 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100230 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100231 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 +0200232 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100233 cont = (struct lyd_node_inner *)tree;
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200234 assert_false(cont->flags & LYD_DEFAULT);
235 lyd_free_all(tree);
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200236}
237
Michal Vasko44685da2020-03-17 15:38:06 +0100238static void
239test_opaq(void **state)
240{
Michal Vasko44685da2020-03-17 15:38:06 +0100241 const char *data;
Michal Vasko44685da2020-03-17 15:38:06 +0100242 struct lyd_node *tree;
243
244 /* invalid value, no flags */
245 data = "<foo3 xmlns=\"urn:tests:a\"/>";
Radek Iša56ca9e42020-09-08 18:42:00 +0200246 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200247 "Invalid type uint32 empty value.", "Schema location \"/a:foo3\", line number 1.");
Michal Vasko44685da2020-03-17 15:38:06 +0100248
249 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200250 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200251 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 +0200252 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<foo3 xmlns=\"urn:tests:a\"/>\n");
Michal Vasko44685da2020-03-17 15:38:06 +0100253 lyd_free_all(tree);
254
Michal Vaskoda8fbbf2021-06-16 11:44:44 +0200255 /* list, opaq flag */
256 data = "<l1 xmlns=\"urn:tests:a\"/>";
257 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
258 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_XML, "l1", 0, 0, NULL, 0, "");
259 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, "<l1 xmlns=\"urn:tests:a\"/>\n");
260 lyd_free_all(tree);
261
Michal Vasko44685da2020-03-17 15:38:06 +0100262 /* missing key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200263 data = "<l1 xmlns=\"urn:tests:a\">\n"
264 " <a>val_a</a>\n"
265 " <b>val_b</b>\n"
266 " <d>val_d</d>\n"
267 "</l1>\n";
268 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200269 "List instance is missing its key \"c\".",
270 "Schema location \"/a:l1\", data location \"/a:l1[a='val_a'][b='val_b']\", line number 5.");
Michal Vasko44685da2020-03-17 15:38:06 +0100271
272 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200273 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200274 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 +0200275 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100276 lyd_free_all(tree);
277
278 /* invalid key, no flags */
Radek Iša56ca9e42020-09-08 18:42:00 +0200279 data = "<l1 xmlns=\"urn:tests:a\">\n"
280 " <a>val_a</a>\n"
281 " <b>val_b</b>\n"
282 " <c>val_c</c>\n"
283 "</l1>\n";
284 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko959f8d82022-06-16 07:51:50 +0200285 "Invalid type int16 value \"val_c\".",
286 "Schema location \"/a:l1/c\", data location \"/a:l1[a='val_a'][b='val_b']\", line number 4.");
Michal Vasko44685da2020-03-17 15:38:06 +0100287
288 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200289 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200290 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 +0200291 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vasko44685da2020-03-17 15:38:06 +0100292 lyd_free_all(tree);
293
Michal Vasko413c7f22020-05-05 12:34:06 +0200294 /* opaq flag and fail */
Radek Iša56ca9e42020-09-08 18:42:00 +0200295 assert_int_equal(LY_EVALID, lyd_parse_data_mem(UTEST_LYCTX,
296 "<a xmlns=\"ns\">\n"
297 " <b>x</b>\n"
Michal Vaskoe137fc42021-07-22 11:53:13 +0200298 " <c xmld:id=\"D\">1</c>\n"
Radek Iša56ca9e42020-09-08 18:42:00 +0200299 "</a>\n",
300 LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskoe137fc42021-07-22 11:53:13 +0200301 CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Line number 3.");
Michal Vasko44685da2020-03-17 15:38:06 +0100302}
303
Michal Vaskob36053d2020-03-26 15:49:30 +0100304static void
305test_rpc(void **state)
306{
Michal Vaskob36053d2020-03-26 15:49:30 +0100307 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200308 struct ly_in *in;
Michal Vaskob36053d2020-03-26 15:49:30 +0100309 struct lyd_node *tree, *op;
Michal Vasko1bf09392020-03-27 12:38:10 +0100310 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200311 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
312 "configuration to the specified target configuration.";
313 const char *ref = "RFC 6241, Section 7.2";
314 const char *feats[] = {"writable-running", NULL};
Michal Vaskob36053d2020-03-26 15:49:30 +0100315
Radek Iša56ca9e42020-09-08 18:42:00 +0200316 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100317
Michal Vasko2552ea32020-12-08 15:32:34 +0100318 data = "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
319 " <target>\n"
320 " <running/>\n"
321 " </target>\n"
322 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
323 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
324 " <a>val_a</a>\n"
325 " <b>val_b</b>\n"
326 " <c>val_c</c>\n"
327 " </l1>\n"
328 " <cp xmlns=\"urn:tests:a\">\n"
329 " <z nc:operation=\"delete\"/>\n"
330 " </cp>\n"
331 " </config>\n"
332 "</edit-config>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200333 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100334 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 +0200335 ly_in_free(in, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100336
337 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200338
Radek Krejci2a9fc652021-01-22 17:44:34 +0100339 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200340 1, 0, 0, 1, "edit-config", LYS_RPC,
341 0, 0, 0, 0, 0, ref, 0);
Michal Vasko1bf09392020-03-27 12:38:10 +0100342
Michal Vaskob36053d2020-03-26 15:49:30 +0100343 assert_non_null(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200344
Michal Vasko2552ea32020-12-08 15:32:34 +0100345 node = tree;
Radek Krejci2a9fc652021-01-22 17:44:34 +0100346 CHECK_LYSC_ACTION((struct lysc_node_action *)node->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);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200349 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200350 dsc = "Inline Config content.";
Michal Vaskod1e53b92021-01-28 13:11:06 +0100351 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 +0200352
Michal Vasko1bf09392020-03-27 12:38:10 +0100353 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100354 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 +0200355 1, LYS_CONTAINER, 0, 0, NULL, 0);
356
Radek Krejcia1c1e542020-09-29 16:06:52 +0200357 node = lyd_child(node);
Michal Vasko1bf09392020-03-27 12:38:10 +0100358 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200359 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 +0200360 node = node->parent->next;
361 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200362 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 +0100363
Radek Iša56ca9e42020-09-08 18:42:00 +0200364 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100365 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
366 " <target>\n"
367 " <running/>\n"
368 " </target>\n"
369 " <config>\n"
370 " <cp xmlns=\"urn:tests:a\">\n"
371 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
372 " </cp>\n"
373 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
374 " <a>val_a</a>\n"
375 " <b>val_b</b>\n"
376 " <c>val_c</c>\n"
377 " </l1>\n"
378 " </config>\n"
379 "</edit-config>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200380
Michal Vaskob36053d2020-03-26 15:49:30 +0100381 lyd_free_all(tree);
382
383 /* wrong namespace, element name, whatever... */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100384 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100385}
386
387static void
388test_action(void **state)
389{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100390 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200391 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100392 struct lyd_node *tree, *op;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100393
Michal Vasko2552ea32020-12-08 15:32:34 +0100394 data = "<c xmlns=\"urn:tests:a\">\n"
395 " <act>\n"
396 " <al>value</al>\n"
397 " </act>\n"
398 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200399 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100400 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 +0200401 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100402
403 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100404 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200405 1, 0, 0, 1, "act", LYS_ACTION,
406 1, 0, 0, 1, 0, NULL, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100407
Radek Iša56ca9e42020-09-08 18:42:00 +0200408 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
Michal Vasko2552ea32020-12-08 15:32:34 +0100409 "<c xmlns=\"urn:tests:a\">\n"
410 " <act>\n"
411 " <al>value</al>\n"
412 " </act>\n"
413 "</c>\n");
Radek Iša56ca9e42020-09-08 18:42:00 +0200414
Michal Vaskoa8edff02020-03-27 14:47:01 +0100415 lyd_free_all(tree);
416
417 /* wrong namespace, element name, whatever... */
418 /* TODO */
Michal Vaskoa8edff02020-03-27 14:47:01 +0100419}
420
421static void
422test_notification(void **state)
423{
Michal Vaskoa8edff02020-03-27 14:47:01 +0100424 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200425 struct ly_in *in;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100426 struct lyd_node *tree, *ntf;
Michal Vaskoa8edff02020-03-27 14:47:01 +0100427
Michal Vasko2552ea32020-12-08 15:32:34 +0100428 data = "<c xmlns=\"urn:tests:a\">\n"
429 " <n1>\n"
430 " <nl>value</nl>\n"
431 " </n1>\n"
432 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200433 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100434 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 +0200435 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100436
437 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100438 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 +0100439
Michal Vasko2552ea32020-12-08 15:32:34 +0100440 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 +0100441
Radek Iša56ca9e42020-09-08 18:42:00 +0200442 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100443 lyd_free_all(tree);
444
445 /* top-level notif without envelope */
Radek Iša56ca9e42020-09-08 18:42:00 +0200446 data = "<n2 xmlns=\"urn:tests:a\"/>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200447 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100448 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 +0200449 ly_in_free(in, 0);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100450
451 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100452 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 +0100453
454 assert_non_null(tree);
455 assert_ptr_equal(ntf, tree);
456
Radek Iša56ca9e42020-09-08 18:42:00 +0200457 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
Michal Vaskoa8edff02020-03-27 14:47:01 +0100458 lyd_free_all(tree);
459
460 /* wrong namespace, element name, whatever... */
461 /* TODO */
Michal Vaskob36053d2020-03-26 15:49:30 +0100462}
463
Michal Vasko1ce933a2020-03-30 12:38:22 +0200464static void
465test_reply(void **state)
466{
Michal Vasko1ce933a2020-03-30 12:38:22 +0200467 const char *data;
Michal Vasko63f3d842020-07-08 10:10:14 +0200468 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +0100469 struct lyd_node *tree, *op;
Michal Vasko1ce933a2020-03-30 12:38:22 +0200470 const struct lyd_node *node;
471
Michal Vasko79135ae2020-12-16 10:08:35 +0100472 data = "<c xmlns=\"urn:tests:a\">\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100473 " <act>\n"
Michal Vasko2552ea32020-12-08 15:32:34 +0100474 " <al>25</al>\n"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100475 " </act>\n"
476 "</c>\n";
Michal Vasko63f3d842020-07-08 10:10:14 +0200477 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100478 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 +0200479 ly_in_free(in, 0);
480
Michal Vasko1ce933a2020-03-30 12:38:22 +0200481 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200482
Radek Krejci2a9fc652021-01-22 17:44:34 +0100483 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200484 1, 0, 0, 1, "act", LYS_ACTION,
485 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200486 node = lyd_child(op);
Michal Vaskod1e53b92021-01-28 13:11:06 +0100487 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 +0200488
Michal Vasko2552ea32020-12-08 15:32:34 +0100489 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 +0200490
491 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200492 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_WITHSIBLINGS, "<al xmlns=\"urn:tests:a\">25</al>\n");
Michal Vasko1ce933a2020-03-30 12:38:22 +0200493 lyd_free_all(tree);
494
495 /* wrong namespace, element name, whatever... */
496 /* TODO */
Michal Vasko1ce933a2020-03-30 12:38:22 +0200497}
498
Michal Vaskoe0665742021-02-11 11:08:44 +0100499static void
500test_netconf_rpc(void **state)
501{
502 const char *data;
503 struct ly_in *in;
504 struct lyd_node *tree, *op;
505 const struct lyd_node *node;
506 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
507 "configuration to the specified target configuration.";
508 const char *ref = "RFC 6241, Section 7.2";
509 const char *feats[] = {"writable-running", NULL};
510
511 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
512
513 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
514 "<edit-config>\n"
515 " <target>\n"
516 " <running/>\n"
517 " </target>\n"
518 " <config xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
519 " <l1 xmlns=\"urn:tests:a\" nc:operation=\"replace\">\n"
520 " <a>val_a</a>\n"
521 " <b>val_b</b>\n"
522 " <c>val_c</c>\n"
523 " </l1>\n"
524 " <cp xmlns=\"urn:tests:a\">\n"
525 " <z nc:operation=\"delete\"/>\n"
526 " </cp>\n"
527 " </config>\n"
528 "</edit-config>\n"
529 "</rpc>\n";
530 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100531 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 +0100532 ly_in_free(in, 0);
533
534 assert_non_null(op);
535
536 node = tree;
Radek Krejci8df109d2021-04-23 12:19:08 +0200537 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 +0100538
539 assert_non_null(tree);
540
541 node = op;
542 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
543 1, 0, 0, 1, "edit-config", LYS_RPC,
544 0, 0, 0, 0, 0, ref, 0);
545 node = lyd_child(node)->next;
546 dsc = "Inline Config content.";
547 CHECK_LYSC_NODE(node->schema, dsc, 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config", 0, LYS_ANYXML, 1, 0, NULL, 0);
548
549 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100550 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
Michal Vaskoe0665742021-02-11 11:08:44 +0100551 1, LYS_CONTAINER, 0, 0, NULL, 0);
552
553 node = lyd_child(node);
554 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200555 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 +0100556 node = node->parent->next;
557 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200558 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 +0100559
560 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
561 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\"/>\n");
562 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
563 "<edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
564 " <target>\n"
565 " <running/>\n"
566 " </target>\n"
567 " <config>\n"
568 " <cp xmlns=\"urn:tests:a\">\n"
569 " <z xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"delete\"/>\n"
570 " </cp>\n"
571 " <l1 xmlns=\"urn:tests:a\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" nc:operation=\"replace\">\n"
572 " <a>val_a</a>\n"
573 " <b>val_b</b>\n"
574 " <c>val_c</c>\n"
575 " </l1>\n"
576 " </config>\n"
577 "</edit-config>\n");
578
579 lyd_free_all(tree);
580 lyd_free_all(op);
581
582 /* wrong namespace, element name, whatever... */
583 /* TODO */
584}
585
586static void
587test_netconf_action(void **state)
588{
589 const char *data;
590 struct ly_in *in;
591 struct lyd_node *tree, *op;
592
593 data = "<rpc message-id=\"25\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
594 "<action xmlns=\"urn:ietf:params:xml:ns:yang:1\">"
595 "<c xmlns=\"urn:tests:a\">\n"
596 " <act>\n"
597 " <al>value</al>\n"
598 " </act>\n"
599 "</c>\n"
600 "</action>\n"
601 "</rpc>\n";
602 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100603 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 +0100604 ly_in_free(in, 0);
605
Radek Krejci8df109d2021-04-23 12:19:08 +0200606 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc", 0, 0, 0, 0, "");
607 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 +0100608
609 assert_non_null(op);
610 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
611 1, 0, 0, 1, "act", LYS_ACTION,
612 1, 0, 0, 1, 0, NULL, 0);
613
614 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
615 "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"25\">\n"
616 " <action xmlns=\"urn:ietf:params:xml:ns:yang:1\"/>\n"
617 "</rpc>\n");
618 CHECK_LYD_STRING(op, LYD_PRINT_WITHSIBLINGS,
619 "<act xmlns=\"urn:tests:a\">\n"
620 " <al>value</al>\n"
621 "</act>\n");
622
623 lyd_free_all(tree);
624 lyd_free_all(op);
625
626 /* wrong namespace, element name, whatever... */
627 /* TODO */
628}
629
630static void
631test_netconf_reply_or_notification(void **state)
632{
633 const char *data;
634 struct ly_in *in;
635 struct lyd_node *action, *tree, *op, *op2;
636
637 /* parse the action */
638 data = "<c xmlns=\"urn:tests:a\">\n"
639 " <act>\n"
640 " <al>value</al>\n"
641 " </act>\n"
642 "</c>\n";
643 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100644 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 +0100645 ly_in_free(in, 0);
646
647 /* parse notification first */
648 data = "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
649 "<eventTime>2010-12-06T08:00:01Z</eventTime>\n"
650 "<c xmlns=\"urn:tests:a\">\n"
651 " <n1>\n"
652 " <nl>value</nl>\n"
653 " </n1>\n"
654 "</c>\n"
655 "</notification>\n";
656 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100657 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 +0100658 ly_in_free(in, 0);
659
Radek Krejci8df109d2021-04-23 12:19:08 +0200660 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 1, LY_VALUE_XML, "notification", 0, 0, 0, 0, "");
661 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 +0100662 "2010-12-06T08:00:01Z");
663
664 assert_non_null(op2);
665 CHECK_LYSC_NOTIF((struct lysc_node_notif *)op2->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
666
667 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
668 "<notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\">\n"
669 " <eventTime>2010-12-06T08:00:01Z</eventTime>\n"
670 "</notification>\n");
671 CHECK_LYD_STRING(op2, LYD_PRINT_WITHSIBLINGS,
672 "<n1 xmlns=\"urn:tests:a\">\n"
673 " <nl>value</nl>\n"
674 "</n1>\n");
675
676 lyd_free_all(tree);
677 lyd_free_all(op2);
678
679 /* parse a data reply */
680 data = "<rpc-reply message-id=\"55\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
681 " <al xmlns=\"urn:tests:a\">25</al>\n"
682 "</rpc-reply>\n";
683 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100684 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 +0100685 ly_in_free(in, 0);
686
Radek Krejci8df109d2021-04-23 12:19:08 +0200687 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 +0100688
Michal Vaskoe0665742021-02-11 11:08:44 +0100689 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
690 "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\"/>\n");
Michal Vaskoe0665742021-02-11 11:08:44 +0100691
692 lyd_free_all(tree);
693 /* it was connected to the action, do not free */
694
695 /* parse an ok reply */
696 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
697 " <ok/>\n"
698 "</rpc-reply>\n";
699 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100700 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 +0100701 ly_in_free(in, 0);
702
Radek Krejci8df109d2021-04-23 12:19:08 +0200703 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
704 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 +0100705
Michal Vaskoe0665742021-02-11 11:08:44 +0100706 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
707
708 lyd_free_all(tree);
709
710 /* parse an error reply */
711 data = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"55\">\n"
712 " <rpc-error>\n"
713 " <error-type>rpc</error-type>\n"
714 " <error-tag>missing-attribute</error-tag>\n"
715 " <error-severity>error</error-severity>\n"
716 " <error-info>\n"
717 " <bad-attribute>message-id</bad-attribute>\n"
718 " <bad-element>rpc</bad-element>\n"
719 " </error-info>\n"
720 " </rpc-error>\n"
721 "</rpc-reply>\n";
722 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100723 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 +0100724 ly_in_free(in, 0);
725
Radek Krejci8df109d2021-04-23 12:19:08 +0200726 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 1, 1, LY_VALUE_XML, "rpc-reply", 0, 0, 0, 0, "");
727 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 +0100728
Michal Vaskoe0665742021-02-11 11:08:44 +0100729 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
730
731 lyd_free_all(tree);
732
733 lyd_free_all(action);
734
735 /* wrong namespace, element name, whatever... */
736 /* TODO */
737}
738
aPiecek9cdb9e62021-05-18 09:46:20 +0200739static void
Michal Vasko45791ad2021-06-17 08:45:03 +0200740test_filter_attributes(void **state)
741{
742 const char *data;
743 struct ly_in *in;
744 struct lyd_node *tree;
745 const struct lyd_node *node;
746 const char *dsc;
747 const char *ref = "RFC 6241, Section 7.7";
748 const char *feats[] = {"writable-running", NULL};
749
750 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
751
752 data = "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
753 " <filter type=\"xpath\" select=\"/*\"/>\n"
754 "</get>\n";
755 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
756 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
757 ly_in_free(in, 0);
758 assert_non_null(tree);
759
760 node = tree;
761 dsc = "Retrieve running configuration and device state information.";
762 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
763 1, 0, 0, 1, "get", LYS_RPC,
764 1, 0, 0, 0, 0, ref, 0);
765 node = lyd_child(node);
766 dsc = "This parameter specifies the portion of the system\nconfiguration and state data to retrieve.";
767 CHECK_LYSC_NODE(node->schema, dsc, 1, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "filter", 0, LYS_ANYXML, 1, 0, NULL, 0);
768
769 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS,
770 "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
771 " <filter type=\"xpath\" select=\"/*\"/>\n"
772 "</get>\n");
773
774 lyd_free_all(tree);
775}
776
777static void
aPiecek9cdb9e62021-05-18 09:46:20 +0200778test_data_skip(void **state)
779{
780 const char *data;
781 struct lyd_node *tree;
782 struct lyd_node_term *leaf;
783
784 /* add invalid data to a module that is not implemented */
785 data = "<foo xmlns=\"urn:ietf:params:xml:ns:yang:ietf-yang-metadata\"><u/></foo>";
786 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
787 assert_null(tree);
788
789 /* add invalid data to a module that is implemented */
790 data = "<fooX xmlns=\"urn:tests:a\"><u/><list><value/></list></fooX>";
791 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
792 assert_null(tree);
793
794 /* first invalid, next valid */
795 data = "<fooX xmlns=\"urn:tests:a\"><u/></fooX> <foo xmlns=\"urn:tests:a\">foo value</foo>";
796 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
797 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
798 leaf = (struct lyd_node_term *)tree;
799 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
800 lyd_free_all(tree);
801}
802
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100803int
804main(void)
Radek Krejci509e2592019-05-15 16:30:48 +0200805{
806 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200807 UTEST(test_leaf, setup),
808 UTEST(test_anydata, setup),
809 UTEST(test_list, setup),
810 UTEST(test_container, setup),
811 UTEST(test_opaq, setup),
812 UTEST(test_rpc, setup),
813 UTEST(test_action, setup),
814 UTEST(test_notification, setup),
815 UTEST(test_reply, setup),
Michal Vaskoe0665742021-02-11 11:08:44 +0100816 UTEST(test_netconf_rpc, setup),
817 UTEST(test_netconf_action, setup),
818 UTEST(test_netconf_reply_or_notification, setup),
Michal Vasko45791ad2021-06-17 08:45:03 +0200819 UTEST(test_filter_attributes, setup),
aPiecek9cdb9e62021-05-18 09:46:20 +0200820 UTEST(test_data_skip, setup),
Radek Krejci509e2592019-05-15 16:30:48 +0200821 };
822
823 return cmocka_run_group_tests(tests, NULL, NULL);
824}