blob: 77c86771cd0c3e8dac3d6e87315ac5259af76fe1 [file] [log] [blame]
Radek Krejci1798aae2020-07-14 13:26:06 +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 *
6 * Copyright (c) 2019 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
15#include "utests.h"
Radek Krejci1798aae2020-07-14 13:26:06 +020016
Radek Krejci1798aae2020-07-14 13:26:06 +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 Krejci1798aae2020-07-14 13:26:06 +020021#include "printer_data.h"
22#include "tests/config.h"
23#include "tree_data_internal.h"
24#include "tree_schema.h"
Radek Krejci1798aae2020-07-14 13:26:06 +020025
26static int
27setup(void **state)
28{
Radek Iša56ca9e42020-09-08 18:42:00 +020029 const char *schema = "module a {namespace urn:tests:a;prefix a;yang-version 1.1; import ietf-yang-metadata {prefix md;}"
Radek Krejci1798aae2020-07-14 13:26:06 +020030 "md:annotation hint { type int8;}"
31 "list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;} leaf d {type string;}}"
32 "leaf foo { type string;}"
33 "container c {"
Radek Krejcib4ac5a92020-11-23 17:54:33 +010034 " leaf x {type string;}"
35 " action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
36 " notification n1 { leaf nl {type string;} }"
Radek Krejci1798aae2020-07-14 13:26:06 +020037 "}"
38 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
39 "anydata any {config false;}"
40 "leaf-list ll1 { type uint8; }"
41 "leaf foo2 { type string; default \"default-val\"; }"
42 "leaf foo3 { type uint32; }"
43 "notification n2;}";
Radek Krejci1798aae2020-07-14 13:26:06 +020044
Radek Iša56ca9e42020-09-08 18:42:00 +020045 UTEST_SETUP;
Radek Krejci1798aae2020-07-14 13:26:06 +020046
Radek Iša56ca9e42020-09-08 18:42:00 +020047 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
48 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci1798aae2020-07-14 13:26:06 +020049
50 return 0;
51}
52
Radek Iša56ca9e42020-09-08 18:42:00 +020053#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
54 CHECK_PARSE_LYD_PARAM(INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci1798aae2020-07-14 13:26:06 +020055
Radek Iša56ca9e42020-09-08 18:42:00 +020056#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
57 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
58 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
59 assert_null(MODEL)
Radek Krejci1798aae2020-07-14 13:26:06 +020060
Radek Iša56ca9e42020-09-08 18:42:00 +020061#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
62 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_JSON, PRINT_OPTION)
Radek Krejci1798aae2020-07-14 13:26:06 +020063
64static void
65test_leaf(void **state)
66{
Radek Krejci1798aae2020-07-14 13:26:06 +020067 struct lyd_node *tree;
68 struct lyd_node_term *leaf;
Radek Iša56ca9e42020-09-08 18:42:00 +020069 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +020070
Radek Iša56ca9e42020-09-08 18:42:00 +020071 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejcib4ac5a92020-11-23 17:54:33 +010072
Radek Iša56ca9e42020-09-08 18:42:00 +020073 data = "{\"a:foo\":\"foo value\"}";
74 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
75 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010076 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020077 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
Radek Krejci1798aae2020-07-14 13:26:06 +020078
Radek Iša56ca9e42020-09-08 18:42:00 +020079 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
80 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010081 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020082
83 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Radek Krejci1798aae2020-07-14 13:26:06 +020084 assert_true(leaf->flags & LYD_DEFAULT);
85
Radek Iša56ca9e42020-09-08 18:42:00 +020086 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +020087 lyd_free_all(tree);
88
89 /* make foo2 explicit */
90 data = "{\"a:foo2\":\"default-val\"}";
Radek Iša56ca9e42020-09-08 18:42:00 +020091 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +020092 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");
Radek Krejci1798aae2020-07-14 13:26:06 +020098 assert_false(leaf->flags & LYD_DEFAULT);
99
Radek Iša56ca9e42020-09-08 18:42:00 +0200100 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200101 lyd_free_all(tree);
102
103 /* parse foo2 but make it implicit */
Radek Krejci5536d282020-08-04 23:27:44 +0200104 data = "{\"a:foo2\":\"default-val\",\"@a:foo2\":{\"ietf-netconf-with-defaults:default\":true}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200105 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200106 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100107 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200108 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
109 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100110 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200111 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Radek Krejci1798aae2020-07-14 13:26:06 +0200112 assert_true(leaf->flags & LYD_DEFAULT);
113
Radek Krejci5536d282020-08-04 23:27:44 +0200114 /* TODO default values
Radek Krejci52f65552020-09-01 17:03:35 +0200115 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200116 assert_string_equal(printed, data);
117 ly_out_reset(out);
118 */
Radek Krejci1798aae2020-07-14 13:26:06 +0200119 lyd_free_all(tree);
120
121 /* multiple meatadata hint and unknown metadata xxx supposed to be skipped since it is from missing schema */
Radek Krejci5536d282020-08-04 23:27:44 +0200122 data = "{\"@a:foo\":{\"a:hint\":1,\"a:hint\":2,\"x:xxx\":{\"value\":\"/x:no/x:yes\"}},\"a:foo\":\"xxx\"}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200123 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
124 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
125 CHECK_LYD_META(tree->meta, 1, "hint", 1, 1, INT8, "1", 1);
126 CHECK_LYD_META(tree->meta->next, 1, "hint", 0, 1, INT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200127 assert_null(tree->meta->next->next);
128
Radek Iša56ca9e42020-09-08 18:42:00 +0200129 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
130 "{\"a:foo\":\"xxx\",\"@a:foo\":{\"a:hint\":1,\"a:hint\":2}}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200131 lyd_free_all(tree);
132
Radek Iša56ca9e42020-09-08 18:42:00 +0200133 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
134 "Unknown (or not implemented) YANG module \"x\" for metadata \"x:xxx\".", "/a:foo");
Radek Krejci1798aae2020-07-14 13:26:06 +0200135
136 /* missing referenced metadata node */
Radek Iša56ca9e42020-09-08 18:42:00 +0200137 PARSER_CHECK_ERROR("{\"@a:foo\" : { \"a:hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
138 "Missing JSON data instance to be coupled with @a:foo metadata.", "/");
Radek Krejci1798aae2020-07-14 13:26:06 +0200139
140 /* missing namespace for meatadata*/
Radek Iša56ca9e42020-09-08 18:42:00 +0200141 PARSER_CHECK_ERROR("{\"a:foo\" : \"value\", \"@a:foo\" : { \"hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
142 "Metadata in JSON must be namespace-qualified, missing prefix for \"hint\".", "/a:foo");
Radek Krejci1798aae2020-07-14 13:26:06 +0200143}
144
145static void
146test_leaflist(void **state)
147{
Radek Iša56ca9e42020-09-08 18:42:00 +0200148 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200149 struct lyd_node *tree;
150 struct lyd_node_term *ll;
151
Radek Iša56ca9e42020-09-08 18:42:00 +0200152 data = "{\"a:ll1\":[10,11]}";
153 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200154 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100155 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200156 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
157 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100158 ll = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200159 CHECK_LYD_VALUE(ll->value, UINT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200160
161 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200162 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
163 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100164 ll = (struct lyd_node_term *)tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200165 CHECK_LYD_VALUE(ll->value, UINT8, "11", 11);
Radek Krejci1798aae2020-07-14 13:26:06 +0200166
Radek Iša56ca9e42020-09-08 18:42:00 +0200167 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200168 lyd_free_all(tree);
169
170 /* simple metadata */
Radek Krejci5536d282020-08-04 23:27:44 +0200171 data = "{\"a:ll1\":[10,11],\"@a:ll1\":[null,{\"a:hint\":2}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200172 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200173 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100174 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200175 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
176 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100177 ll = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200178 CHECK_LYD_VALUE(ll->value, UINT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200179 assert_null(ll->meta);
180
181 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200182 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
183 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100184 ll = (struct lyd_node_term *)tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200185 CHECK_LYD_VALUE(ll->value, UINT8, "11", 11);
186 CHECK_LYD_META(ll->meta, 1, "hint", 0, 1, INT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200187 assert_null(ll->meta->next);
188
Radek Iša56ca9e42020-09-08 18:42:00 +0200189 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200190 lyd_free_all(tree);
191
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100192 /* multiple meatadata hint and unknown metadata xxx supposed to be skipped since it is from missing schema */
Radek Iša56ca9e42020-09-08 18:42:00 +0200193 data = "{\"@a:ll1\" : [{\"a:hint\" : 1, \"x:xxx\" : { \"value\" : \"/x:no/x:yes\" }, "
194 "\"a:hint\" : 10},null,{\"a:hint\" : 3}], \"a:ll1\" : [1,2,3]}";
195 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200196 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100197 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200198 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
199 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100200 ll = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200201 CHECK_LYD_VALUE(ll->value, UINT8, "1", 1);
202 CHECK_LYD_META(ll->meta, 1, "hint", 1, 1, INT8, "1", 1);
203 CHECK_LYD_META(ll->meta->next, 1, "hint", 0, 1, INT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200204
205 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200206 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
207 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100208 ll = (struct lyd_node_term *)tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200209 CHECK_LYD_VALUE(ll->value, UINT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200210 assert_null(ll->meta);
211
212 assert_non_null(tree->next->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200213 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
214 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100215 ll = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200216 CHECK_LYD_VALUE(ll->value, UINT8, "3", 3);
217 CHECK_LYD_META(ll->meta, 1, "hint", 0, 1, INT8, "3", 3);
Radek Krejci1798aae2020-07-14 13:26:06 +0200218 assert_null(ll->meta->next);
219
Radek Iša56ca9e42020-09-08 18:42:00 +0200220 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
221 "{\"a:ll1\":[1,2,3],\"@a:ll1\":[{\"a:hint\":1,\"a:hint\":10},null,{\"a:hint\":3}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200222 lyd_free_all(tree);
223
224 /* missing referenced metadata node */
Radek Iša56ca9e42020-09-08 18:42:00 +0200225 PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
226 "Missing JSON data instance to be coupled with @a:ll1 metadata.", "/");
Radek Krejci1798aae2020-07-14 13:26:06 +0200227
Radek Iša56ca9e42020-09-08 18:42:00 +0200228 PARSER_CHECK_ERROR("{\"a:ll1\":[1],\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
229 "Missing JSON data instance no. 2 of a:ll1 to be coupled with metadata.", "/");
Radek Krejci1798aae2020-07-14 13:26:06 +0200230
Radek Iša56ca9e42020-09-08 18:42:00 +0200231 PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2},{\"a:hint\":3}],\"a:ll1\" : [1, 2]}", 0, LYD_VALIDATE_PRESENT,
232 tree, LY_EVALID, "Missing 3rd JSON data instance to be coupled with @a:ll1 metadata.", "/");
Radek Krejci1798aae2020-07-14 13:26:06 +0200233}
234
235static void
236test_anydata(void **state)
237{
Radek Krejci1798aae2020-07-14 13:26:06 +0200238 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200239 struct lyd_node *tree;
240
Radek Krejci1798aae2020-07-14 13:26:06 +0200241 data = "{\"a:any\":{\"x:element1\":{\"element2\":\"/a:some/a:path\",\"list\":[{},{\"key\":\"a\"}]}}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200242 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200243 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100244 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200245 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_SET_ENUM | LYS_CONFIG_R | LYS_YIN_ARGUMENT, 1, "any",
246 1, LYS_ANYDATA, 0, 0, NULL, 0);
247 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200248 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200249}
250
251static void
252test_list(void **state)
253{
Radek Iša56ca9e42020-09-08 18:42:00 +0200254 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200255 struct lyd_node *tree, *iter;
256 struct lyd_node_inner *list;
257 struct lyd_node_term *leaf;
258
259 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200260 data = "{\"a:l1\":[{\"a\":\"one\",\"b\":\"one\",\"c\":1}]}";
261 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
262 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
263 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100264 list = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200265 LY_LIST_FOR(list->child, iter) {
266 assert_int_not_equal(0, iter->hash);
267 }
Radek Krejci5536d282020-08-04 23:27:44 +0200268
Radek Iša56ca9e42020-09-08 18:42:00 +0200269 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200270 lyd_free_all(tree);
271
272 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200273 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
274 "List instance is missing its key \"a\".", "/a:l1[b='b'][c='1']");
Radek Krejci1798aae2020-07-14 13:26:06 +0200275
Radek Iša56ca9e42020-09-08 18:42:00 +0200276 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
277 "List instance is missing its key \"b\".", "/a:l1[a='a']");
Radek Krejci1798aae2020-07-14 13:26:06 +0200278
Radek Iša56ca9e42020-09-08 18:42:00 +0200279 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"b\" : \"b\", \"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
280 "List instance is missing its key \"c\".", "/a:l1[a='a'][b='b']");
Radek Krejci1798aae2020-07-14 13:26:06 +0200281
282 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200283 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\", \"a\" : \"a\", \"c\" : 1}]}", 0, LYD_VALIDATE_PRESENT,
284 tree, LY_EVALID, "Duplicate instance of \"c\".", "/a:l1[a='a'][b='b'][c='1'][c='1']/c");
Radek Krejci1798aae2020-07-14 13:26:06 +0200285
286 /* keys order, in contrast to XML, JSON accepts keys in any order even in strict mode */
Radek Iša56ca9e42020-09-08 18:42:00 +0200287 CHECK_PARSE_LYD("{ \"a:l1\": [ {\"d\" : \"d\", \"a\" : \"a\", \"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree);
288 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
289 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100290 list = (struct lyd_node_inner *)tree;
291 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200292 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 +0100293 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200294 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 +0100295 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200296 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 +0100297 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200298 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 0, LYS_LEAF, 1, 0, NULL, 0);
299 CHECK_LOG_CTX(NULL, NULL);
Radek Krejci5536d282020-08-04 23:27:44 +0200300
Radek Iša56ca9e42020-09-08 18:42:00 +0200301 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
302 "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1,\"d\":\"d\"}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200303 lyd_free_all(tree);
304
305 /* */
Radek Iša56ca9e42020-09-08 18:42:00 +0200306 CHECK_PARSE_LYD("{\"a:l1\":[{\"c\":1,\"b\":\"b\",\"a\":\"a\"}]}", LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree);
307 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
308 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100309 list = (struct lyd_node_inner *)tree;
310 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200311 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a",
312 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100313 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200314 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b",
315 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100316 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200317 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c",
318 1, LYS_LEAF, 1, 0, NULL, 0);
319 CHECK_LOG_CTX(NULL, NULL);
Radek Krejci5536d282020-08-04 23:27:44 +0200320
Radek Iša56ca9e42020-09-08 18:42:00 +0200321 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
322 "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200323 lyd_free_all(tree);
324
Radek Krejci5536d282020-08-04 23:27:44 +0200325 data = "{\"a:cp\":{\"@\":{\"a:hint\":1}}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200326 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200327 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100328 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200329 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
330 1, LYS_CONTAINER, 0, 0, NULL, 0);
331 CHECK_LYD_META(tree->meta, 1, "hint", 0, 1, INT8, "1", 1);
Radek Krejci1798aae2020-07-14 13:26:06 +0200332 assert_null(tree->meta->next);
Radek Krejci5536d282020-08-04 23:27:44 +0200333
Radek Iša56ca9e42020-09-08 18:42:00 +0200334 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200335 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200336}
337
338static void
339test_container(void **state)
340{
Radek Iša56ca9e42020-09-08 18:42:00 +0200341 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200342 struct lyd_node *tree;
343 struct lyd_node_inner *cont;
344
Radek Iša56ca9e42020-09-08 18:42:00 +0200345 CHECK_PARSE_LYD("{\"a:c\":{}}", 0, LYD_VALIDATE_PRESENT, tree);
346 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c",
347 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100348 cont = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200349 assert_true(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200350
Radek Iša56ca9e42020-09-08 18:42:00 +0200351 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200352 lyd_free_all(tree);
353
Radek Krejci5536d282020-08-04 23:27:44 +0200354 data = "{\"a:cp\":{}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200355 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200356 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100357 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200358 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
359 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100360 cont = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200361 assert_false(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200362
Radek Iša56ca9e42020-09-08 18:42:00 +0200363 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200364 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200365}
366
367static void
368test_opaq(void **state)
369{
Radek Krejci1798aae2020-07-14 13:26:06 +0200370 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200371 struct lyd_node *tree;
372
Radek Krejci1798aae2020-07-14 13:26:06 +0200373 /* invalid value, no flags */
374 data = "{\"a:foo3\":[null]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200375 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
376 "Invalid non-number-encoded uint32 value \"\".", "/a:foo3");
Radek Krejci1798aae2020-07-14 13:26:06 +0200377
378 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200379 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, LYD_VALIDATE_PRESENT, tree);
380 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_PREF_JSON, "foo3", 0, 0, NULL, 0, "");
381 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200382 lyd_free_all(tree);
383
384 /* missing key, no flags */
385 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"d\":\"val_d\"}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200386 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
387 "List instance is missing its key \"c\".", "/a:l1[a='val_a'][b='val_b']");
Radek Krejci1798aae2020-07-14 13:26:06 +0200388
389 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200390 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, LYD_VALIDATE_PRESENT, tree);
391 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "l1", 0, 0, NULL, 0, "");
392 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200393 lyd_free_all(tree);
394
395 /* invalid key, no flags */
396 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200397 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
398 "Invalid non-number-encoded int16 value \"val_c\".", "/a:l1/c");
Radek Krejci1798aae2020-07-14 13:26:06 +0200399
400 /* opaq flag */
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, LYD_VALIDATE_PRESENT, tree);
402 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "l1", 0, 0, NULL, 0, "");
403 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200404 lyd_free_all(tree);
405
406 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":{\"val\":\"val_c\"}}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200407 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, LYD_VALIDATE_PRESENT, tree);
408 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "l1", 0, 0, NULL, 0, "");
409 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200410 lyd_free_all(tree);
411
412 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\"}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200413 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, LYD_VALIDATE_PRESENT, tree);
414 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "l1", 0, 0, NULL, 0, "");
415 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200416 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200417}
418
419static void
420test_rpc(void **state)
421{
Radek Krejci1798aae2020-07-14 13:26:06 +0200422 const char *data;
423 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200424 struct lyd_node *tree, *op;
425 const struct lyd_node *node;
Radek Iša56ca9e42020-09-08 18:42:00 +0200426 const char *dsc = "The <edit-config> operation loads all or part of a specified\n"
427 "configuration to the specified target configuration.";
428 const char *ref = "RFC 6241, Section 7.2";
429 const char *feats[] = {"writable-running", NULL};
Radek Krejci1798aae2020-07-14 13:26:06 +0200430
Radek Iša56ca9e42020-09-08 18:42:00 +0200431 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf", "2011-06-01", feats)));
Radek Krejci1798aae2020-07-14 13:26:06 +0200432
433 data = "{\"ietf-netconf:rpc\":{\"edit-config\":{"
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100434 "\"target\":{\"running\":[null]},"
435 "\"config\":{\"a:cp\":{\"z\":[null],\"@z\":{\"ietf-netconf:operation\":\"replace\"}},"
436 "\"a:l1\":[{\"@\":{\"ietf-netconf:operation\":\"replace\"},\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}"
Radek Krejci1798aae2020-07-14 13:26:06 +0200437 "}}}";
438 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200439 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_JSON, &tree, &op));
Radek Krejci1798aae2020-07-14 13:26:06 +0200440 ly_in_free(in, 0);
441
442 assert_non_null(op);
Radek Krejci1798aae2020-07-14 13:26:06 +0200443
Radek Iša56ca9e42020-09-08 18:42:00 +0200444 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
445 1, 0, 0, 1, "edit-config", LYS_RPC,
446 0, 0, 0, 0, 0, ref, 0);
447
448 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "rpc", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200449 /* TODO support generic attributes in JSON ?
450 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
451 */
Radek Iša56ca9e42020-09-08 18:42:00 +0200452
Radek Krejcia1c1e542020-09-29 16:06:52 +0200453 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200454 CHECK_LYSC_ACTION((struct lysc_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
455 1, 0, 0, 1, "edit-config", LYS_RPC,
456 0, 0, 0, 0, 0, ref, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200457 node = lyd_child(node)->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200458 CHECK_LYSC_NODE(node->schema, "Inline Config content.", 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "config",
459 0, LYS_ANYXML, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200460
461 node = ((struct lyd_node_any *)node)->value.tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200462 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_PRESENCE, 1, "cp",
463 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200464 node = lyd_child(node);
Radek Krejci1798aae2020-07-14 13:26:06 +0200465 /* z has no value */
Radek Iša56ca9e42020-09-08 18:42:00 +0200466 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_PREF_JSON, "z", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200467 node = node->parent->next;
468 /* l1 key c has invalid value so it is at the end */
Radek Iša56ca9e42020-09-08 18:42:00 +0200469 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_PREF_JSON, "l1", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200470
Radek Iša56ca9e42020-09-08 18:42:00 +0200471 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200472 lyd_free_all(tree);
473
474 /* wrong namespace, element name, whatever... */
475 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200476}
477
478static void
479test_action(void **state)
480{
Radek Krejci1798aae2020-07-14 13:26:06 +0200481 const char *data;
482 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200483 struct lyd_node *tree, *op;
484 const struct lyd_node *node;
485
Radek Krejci1798aae2020-07-14 13:26:06 +0200486 data = "{\"ietf-netconf:rpc\":{\"yang:action\":{\"a:c\":{\"act\":{\"al\":\"value\"}}}}}";
487 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200488 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_JSON, &tree, &op));
Radek Krejci1798aae2020-07-14 13:26:06 +0200489 ly_in_free(in, 0);
490
491 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200492 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
493 1, 0, 0, 1, "act", LYS_ACTION,
494 1, 0, 0, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200495
Radek Iša56ca9e42020-09-08 18:42:00 +0200496 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "rpc", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200497 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200498 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0, 0x1, LY_PREF_JSON, "action", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200499
Radek Iša56ca9e42020-09-08 18:42:00 +0200500 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200501 lyd_free_all(tree);
502
503 /* wrong namespace, element name, whatever... */
504 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200505}
506
507static void
508test_notification(void **state)
509{
Radek Krejci1798aae2020-07-14 13:26:06 +0200510 const char *data;
511 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200512 struct lyd_node *tree, *ntf;
513 const struct lyd_node *node;
514
Radek Krejci1798aae2020-07-14 13:26:06 +0200515 data = "{\"ietf-restconf:notification\":{\"eventTime\":\"2037-07-08T00:01:00Z\",\"a:c\":{\"n1\":{\"nl\":\"value\"}}}}";
516 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200517 assert_int_equal(LY_SUCCESS, lyd_parse_notif(UTEST_LYCTX, in, LYD_JSON, &tree, &ntf));
Radek Krejci1798aae2020-07-14 13:26:06 +0200518 ly_in_free(in, 0);
519
520 assert_non_null(ntf);
Radek Iša56ca9e42020-09-08 18:42:00 +0200521 CHECK_LYSC_NOTIF((struct lysc_notif *)ntf->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200522
Radek Iša56ca9e42020-09-08 18:42:00 +0200523 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "notification", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200524 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200525 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0, 0, LY_PREF_JSON, "eventTime", 0, 0, NULL, 0, "2037-07-08T00:01:00Z");
Radek Krejci1798aae2020-07-14 13:26:06 +0200526 node = node->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200527 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200528
Radek Iša56ca9e42020-09-08 18:42:00 +0200529 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200530 lyd_free_all(tree);
531
532 /* top-level notif without envelope */
533 data = "{\"a:n2\":{}}";
534 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200535 assert_int_equal(LY_SUCCESS, lyd_parse_notif(UTEST_LYCTX, in, LYD_JSON, &tree, &ntf));
Radek Krejci1798aae2020-07-14 13:26:06 +0200536 ly_in_free(in, 0);
537
538 assert_non_null(ntf);
Radek Iša56ca9e42020-09-08 18:42:00 +0200539 CHECK_LYSC_NOTIF((struct lysc_notif *)ntf->schema, 0, NULL, 0, 0x4, 1, 0, "n2", 0, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200540
541 assert_non_null(tree);
542 assert_ptr_equal(ntf, tree);
543
Radek Iša56ca9e42020-09-08 18:42:00 +0200544 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200545 lyd_free_all(tree);
546
547 /* wrong namespace, element name, whatever... */
548 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200549}
550
551static void
552test_reply(void **state)
553{
Radek Krejci1798aae2020-07-14 13:26:06 +0200554 const char *data;
555 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200556 struct lyd_node *request, *tree, *op;
557 const struct lyd_node *node;
558
Radek Krejci1798aae2020-07-14 13:26:06 +0200559 data = "{\"a:c\":{\"act\":{\"al\":\"value\"}}}";
560 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Radek Iša56ca9e42020-09-08 18:42:00 +0200561 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(UTEST_LYCTX, in, LYD_JSON, &request, NULL));
Radek Krejci1798aae2020-07-14 13:26:06 +0200562 ly_in_free(in, 0);
563
564 data = "{\"ietf-netconf:rpc-reply\":{\"a:al\":25}}";
565 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
566 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_JSON, &tree, &op));
567 ly_in_free(in, 0);
568 lyd_free_all(request);
569
570 assert_non_null(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200571 CHECK_LYSC_ACTION((struct lysc_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
572 1, 0, 0, 1, "act", LYS_ACTION,
573 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200574 node = lyd_child(op);
Radek Iša56ca9e42020-09-08 18:42:00 +0200575 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_R | LYS_STATUS_CURR, 1, "al", 0, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200576
Radek Iša56ca9e42020-09-08 18:42:00 +0200577 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_PREF_JSON, "rpc-reply", 0, 0, NULL, 0, "");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200578 node = lyd_child(tree);
Radek Iša56ca9e42020-09-08 18:42:00 +0200579 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200580
581 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200582 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:al\":25}");
583 CHECK_LYD_STRING(lyd_child(tree), LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:c\":{\"act\":{\"al\":25}}}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200584 lyd_free_all(tree);
585
586 /* wrong namespace, element name, whatever... */
587 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200588}
589
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100590int
591main(void)
Radek Krejci1798aae2020-07-14 13:26:06 +0200592{
593 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200594 UTEST(test_leaf, setup),
595 UTEST(test_leaflist, setup),
596 UTEST(test_anydata, setup),
597 UTEST(test_list, setup),
598 UTEST(test_container, setup),
599 UTEST(test_opaq, setup),
600 UTEST(test_rpc, setup),
601 UTEST(test_action, setup),
602 UTEST(test_notification, setup),
603 UTEST(test_reply, setup),
Radek Krejci1798aae2020-07-14 13:26:06 +0200604 };
605
606 return cmocka_run_group_tests(tests, NULL, NULL);
607}