blob: 140486b8a2252782813b206ae42109c5c74ddbe5 [file] [log] [blame]
Radek Krejci1798aae2020-07-14 13:26:06 +02001/*
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_parser_json.c
Radek Krejci1798aae2020-07-14 13:26:06 +02003 * @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"
Radek Krejcief5f7672021-04-01 17:04:12 +020022#include "tests_config.h"
Radek Krejci1798aae2020-07-14 13:26:06 +020023#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;}"
Michal Vasko76096ec2022-02-24 16:06:16 +010040 "anyxml axml;"
Radek Krejci1798aae2020-07-14 13:26:06 +020041 "leaf-list ll1 { type uint8; }"
42 "leaf foo2 { type string; default \"default-val\"; }"
43 "leaf foo3 { type uint32; }"
44 "notification n2;}";
Radek Krejci1798aae2020-07-14 13:26:06 +020045
Radek Iša56ca9e42020-09-08 18:42:00 +020046 UTEST_SETUP;
Radek Krejci1798aae2020-07-14 13:26:06 +020047
Radek Iša56ca9e42020-09-08 18:42:00 +020048 UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
49 assert_int_equal(LY_SUCCESS, ly_ctx_set_searchdir(UTEST_LYCTX, TESTS_DIR_MODULES_YANG));
Radek Krejci1798aae2020-07-14 13:26:06 +020050
51 return 0;
52}
53
Radek Iša56ca9e42020-09-08 18:42:00 +020054#define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
55 CHECK_PARSE_LYD_PARAM(INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
Radek Krejci1798aae2020-07-14 13:26:06 +020056
Radek Iša56ca9e42020-09-08 18:42:00 +020057#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
58 assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
59 CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
60 assert_null(MODEL)
Radek Krejci1798aae2020-07-14 13:26:06 +020061
Radek Iša56ca9e42020-09-08 18:42:00 +020062#define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
63 CHECK_LYD_STRING_PARAM(IN_MODEL, TEXT, LYD_JSON, PRINT_OPTION)
Radek Krejci1798aae2020-07-14 13:26:06 +020064
65static void
66test_leaf(void **state)
67{
Radek Krejci1798aae2020-07-14 13:26:06 +020068 struct lyd_node *tree;
69 struct lyd_node_term *leaf;
Radek Iša56ca9e42020-09-08 18:42:00 +020070 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +020071
Radek Iša56ca9e42020-09-08 18:42:00 +020072 assert_non_null(ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejcib4ac5a92020-11-23 17:54:33 +010073
Radek Iša56ca9e42020-09-08 18:42:00 +020074 data = "{\"a:foo\":\"foo value\"}";
75 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
76 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 +010077 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020078 CHECK_LYD_VALUE(leaf->value, STRING, "foo value");
Radek Krejci1798aae2020-07-14 13:26:06 +020079
Radek Iša56ca9e42020-09-08 18:42:00 +020080 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
81 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010082 leaf = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020083
84 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Radek Krejci1798aae2020-07-14 13:26:06 +020085 assert_true(leaf->flags & LYD_DEFAULT);
86
Radek Iša56ca9e42020-09-08 18:42:00 +020087 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +020088 lyd_free_all(tree);
89
90 /* make foo2 explicit */
91 data = "{\"a:foo2\":\"default-val\"}";
Radek Iša56ca9e42020-09-08 18:42:00 +020092 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +020093 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +010094 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +020095 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
96 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +010097 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +020098 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Radek Krejci1798aae2020-07-14 13:26:06 +020099 assert_false(leaf->flags & LYD_DEFAULT);
100
Radek Iša56ca9e42020-09-08 18:42:00 +0200101 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200102 lyd_free_all(tree);
103
104 /* parse foo2 but make it implicit */
Radek Krejci5536d282020-08-04 23:27:44 +0200105 data = "{\"a:foo2\":\"default-val\",\"@a:foo2\":{\"ietf-netconf-with-defaults:default\":true}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200106 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200107 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100108 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200109 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_SET_DFLT, 1, "foo2",
110 1, LYS_LEAF, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100111 leaf = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200112 CHECK_LYD_VALUE(leaf->value, STRING, "default-val");
Radek Krejci1798aae2020-07-14 13:26:06 +0200113 assert_true(leaf->flags & LYD_DEFAULT);
114
Michal Vaskob68c3b42022-05-20 10:36:40 +0200115 /* print default values */
116 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL_TAG, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200117 lyd_free_all(tree);
118
119 /* multiple meatadata hint and unknown metadata xxx supposed to be skipped since it is from missing schema */
Radek Krejci5536d282020-08-04 23:27:44 +0200120 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 +0200121 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
122 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "foo", 1, LYS_LEAF, 0, 0, NULL, 0);
123 CHECK_LYD_META(tree->meta, 1, "hint", 1, 1, INT8, "1", 1);
124 CHECK_LYD_META(tree->meta->next, 1, "hint", 0, 1, INT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200125 assert_null(tree->meta->next->next);
126
Radek Iša56ca9e42020-09-08 18:42:00 +0200127 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
128 "{\"a:foo\":\"xxx\",\"@a:foo\":{\"a:hint\":1,\"a:hint\":2}}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200129 lyd_free_all(tree);
130
Radek Iša56ca9e42020-09-08 18:42:00 +0200131 PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko4eab5622021-07-22 15:36:45 +0200132 "Unknown (or not implemented) YANG module \"x\" of metadata \"x:xxx\".", "Data location /@a:foo, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200133
134 /* missing referenced metadata node */
Radek Iša56ca9e42020-09-08 18:42:00 +0200135 PARSER_CHECK_ERROR("{\"@a:foo\" : { \"a:hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100136 "Missing JSON data instance to be coupled with @a:foo metadata.", "Data location /@a:foo, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200137
138 /* missing namespace for meatadata*/
Radek Iša56ca9e42020-09-08 18:42:00 +0200139 PARSER_CHECK_ERROR("{\"a:foo\" : \"value\", \"@a:foo\" : { \"hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100140 "Metadata in JSON must be namespace-qualified, missing prefix for \"hint\".", "Schema location /a:foo, line number 1.");
aPiecek49e2a3a2021-05-13 10:36:46 +0200141
142 /* reverse solidus in JSON object member name */
143 data = "{\"@a:foo\":{\"a:hi\\nt\":1},\"a:foo\":\"xxx\"}";
144 assert_int_equal(LY_EINVAL, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
Radek Krejci1798aae2020-07-14 13:26:06 +0200145}
146
147static void
148test_leaflist(void **state)
149{
Radek Iša56ca9e42020-09-08 18:42:00 +0200150 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200151 struct lyd_node *tree;
152 struct lyd_node_term *ll;
153
Radek Iša56ca9e42020-09-08 18:42:00 +0200154 data = "{\"a:ll1\":[10,11]}";
155 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200156 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100157 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200158 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
159 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100160 ll = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200161 CHECK_LYD_VALUE(ll->value, UINT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200162
163 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200164 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
165 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100166 ll = (struct lyd_node_term *)tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200167 CHECK_LYD_VALUE(ll->value, UINT8, "11", 11);
Radek Krejci1798aae2020-07-14 13:26:06 +0200168
Radek Iša56ca9e42020-09-08 18:42:00 +0200169 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200170 lyd_free_all(tree);
171
Michal Vasko4e26adc2022-03-30 11:01:16 +0200172 /* accept empty */
173 data = "{\"a:ll1\":[]}";
174 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
175 assert_null(tree);
176
Radek Krejci1798aae2020-07-14 13:26:06 +0200177 /* simple metadata */
Radek Krejci5536d282020-08-04 23:27:44 +0200178 data = "{\"a:ll1\":[10,11],\"@a:ll1\":[null,{\"a:hint\":2}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200179 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200180 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100181 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200182 CHECK_LYSC_NODE(tree->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;
Radek Iša56ca9e42020-09-08 18:42:00 +0200185 CHECK_LYD_VALUE(ll->value, UINT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200186 assert_null(ll->meta);
187
188 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200189 CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
190 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100191 ll = (struct lyd_node_term *)tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200192 CHECK_LYD_VALUE(ll->value, UINT8, "11", 11);
193 CHECK_LYD_META(ll->meta, 1, "hint", 0, 1, INT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200194 assert_null(ll->meta->next);
195
Radek Iša56ca9e42020-09-08 18:42:00 +0200196 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200197 lyd_free_all(tree);
198
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100199 /* 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 +0200200 data = "{\"@a:ll1\" : [{\"a:hint\" : 1, \"x:xxx\" : { \"value\" : \"/x:no/x:yes\" }, "
201 "\"a:hint\" : 10},null,{\"a:hint\" : 3}], \"a:ll1\" : [1,2,3]}";
202 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200203 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100204 tree = tree->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200205 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
206 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100207 ll = (struct lyd_node_term *)tree;
Radek Iša56ca9e42020-09-08 18:42:00 +0200208 CHECK_LYD_VALUE(ll->value, UINT8, "1", 1);
209 CHECK_LYD_META(ll->meta, 1, "hint", 1, 1, INT8, "1", 1);
210 CHECK_LYD_META(ll->meta->next, 1, "hint", 0, 1, INT8, "10", 10);
Radek Krejci1798aae2020-07-14 13:26:06 +0200211
212 assert_non_null(tree->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200213 CHECK_LYSC_NODE(tree->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;
Radek Iša56ca9e42020-09-08 18:42:00 +0200216 CHECK_LYD_VALUE(ll->value, UINT8, "2", 2);
Radek Krejci1798aae2020-07-14 13:26:06 +0200217 assert_null(ll->meta);
218
219 assert_non_null(tree->next->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200220 CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "ll1",
221 1, LYS_LEAFLIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100222 ll = (struct lyd_node_term *)tree->next->next;
Radek Iša56ca9e42020-09-08 18:42:00 +0200223 CHECK_LYD_VALUE(ll->value, UINT8, "3", 3);
224 CHECK_LYD_META(ll->meta, 1, "hint", 0, 1, INT8, "3", 3);
Radek Krejci1798aae2020-07-14 13:26:06 +0200225 assert_null(ll->meta->next);
226
Radek Iša56ca9e42020-09-08 18:42:00 +0200227 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
228 "{\"a:ll1\":[1,2,3],\"@a:ll1\":[{\"a:hint\":1,\"a:hint\":10},null,{\"a:hint\":3}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200229 lyd_free_all(tree);
230
231 /* missing referenced metadata node */
Radek Iša56ca9e42020-09-08 18:42:00 +0200232 PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100233 "Missing JSON data instance to be coupled with @a:ll1 metadata.", "Data location /@a:ll1, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200234
Radek Iša56ca9e42020-09-08 18:42:00 +0200235 PARSER_CHECK_ERROR("{\"a:ll1\":[1],\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Michal Vasko54ba8912021-07-23 12:46:23 +0200236 "Missing JSON data instance #2 of a:ll1 to be coupled with metadata.", "Schema location /a:ll1, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200237
Radek Iša56ca9e42020-09-08 18:42:00 +0200238 PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2},{\"a:hint\":3}],\"a:ll1\" : [1, 2]}", 0, LYD_VALIDATE_PRESENT,
Michal Vasko54ba8912021-07-23 12:46:23 +0200239 tree, LY_EVALID, "Missing JSON data instance #3 to be coupled with @a:ll1 metadata.", "Data location /@a:ll1, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200240}
241
242static void
243test_anydata(void **state)
244{
Radek Krejci1798aae2020-07-14 13:26:06 +0200245 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200246 struct lyd_node *tree;
247
Radek Krejci1798aae2020-07-14 13:26:06 +0200248 data = "{\"a:any\":{\"x:element1\":{\"element2\":\"/a:some/a:path\",\"list\":[{},{\"key\":\"a\"}]}}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200249 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200250 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100251 tree = tree->next;
Michal Vasko76096ec2022-02-24 16:06:16 +0100252 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_R | LYS_SET_CONFIG, 1, "any",
Radek Iša56ca9e42020-09-08 18:42:00 +0200253 1, LYS_ANYDATA, 0, 0, NULL, 0);
254 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200255 lyd_free_all(tree);
Michal Vaskofbc4a252022-02-03 13:15:58 +0100256
257 data = "{\"a:any\":{}}";
258 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
259 assert_non_null(tree);
260 tree = tree->next;
Michal Vasko76096ec2022-02-24 16:06:16 +0100261 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_R | LYS_SET_CONFIG, 1, "any",
Michal Vaskofbc4a252022-02-03 13:15:58 +0100262 1, LYS_ANYDATA, 0, 0, NULL, 0);
263 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
264 lyd_free_all(tree);
Michal Vasko76096ec2022-02-24 16:06:16 +0100265
266 data = "{\"a:any\":[null]}";
267 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
268 assert_non_null(tree);
269 tree = tree->next;
270 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_R | LYS_SET_CONFIG, 1, "any",
271 1, LYS_ANYDATA, 0, 0, NULL, 0);
272 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
273 lyd_free_all(tree);
274}
275
276static void
277test_anyxml(void **state)
278{
279 const char *data;
280 struct lyd_node *tree;
281
282 data = "{\"a:axml\":\"some-value in string\"}";
283 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
284 assert_non_null(tree);
285 tree = tree->next;
286 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
287 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
288 lyd_free_all(tree);
289
290 data = "{\"a:axml\":\"\"}";
291 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
292 assert_non_null(tree);
293 tree = tree->next;
294 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
295 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
296 lyd_free_all(tree);
297
298 data = "{\"a:axml\":55}";
299 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
300 assert_non_null(tree);
301 tree = tree->next;
302 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
303 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
304 lyd_free_all(tree);
305
306 data = "{\"a:axml\":false}";
307 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
308 assert_non_null(tree);
309 tree = tree->next;
310 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
311 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
312 lyd_free_all(tree);
313
314 data = "{\"a:axml\":null}";
315 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
316 assert_non_null(tree);
317 tree = tree->next;
318 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
319 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
320 lyd_free_all(tree);
321
322 data = "{\"a:axml\":[null,true,false]}";
323 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
324 assert_non_null(tree);
325 tree = tree->next;
326 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
327 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
328 lyd_free_all(tree);
329
330 data = "{\"a:axml\":[null,true,{\"name\":[25,40, false]}]}";
331 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
332 assert_non_null(tree);
333 tree = tree->next;
334 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
335 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
336 lyd_free_all(tree);
337
338 /* same as anydata tests */
339 data = "{\"a:axml\":{\"x:element1\":{\"element2\":\"/a:some/a:path\",\"list\":[{},{\"key\":\"a\"}]}}}";
340 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
341 assert_non_null(tree);
342 tree = tree->next;
343 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
344 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
345 lyd_free_all(tree);
346
347 data = "{\"a:axml\":{}}";
348 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
349 assert_non_null(tree);
350 tree = tree->next;
351 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_STATUS_CURR | LYS_CONFIG_W, 1, "axml", 1, LYS_ANYXML, 0, 0, NULL, 0);
352 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
353 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200354}
355
356static void
357test_list(void **state)
358{
Radek Iša56ca9e42020-09-08 18:42:00 +0200359 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200360 struct lyd_node *tree, *iter;
361 struct lyd_node_inner *list;
362 struct lyd_node_term *leaf;
363
364 /* check hashes */
Radek Iša56ca9e42020-09-08 18:42:00 +0200365 data = "{\"a:l1\":[{\"a\":\"one\",\"b\":\"one\",\"c\":1}]}";
366 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
367 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
368 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100369 list = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200370 LY_LIST_FOR(list->child, iter) {
371 assert_int_not_equal(0, iter->hash);
372 }
Radek Iša56ca9e42020-09-08 18:42:00 +0200373 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200374 lyd_free_all(tree);
375
Michal Vasko4e26adc2022-03-30 11:01:16 +0200376 /* accept empty */
377 data = "{\"a:l1\":[]}";
378 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
379 assert_null(tree);
380
Radek Krejci1798aae2020-07-14 13:26:06 +0200381 /* missing keys */
Radek Iša56ca9e42020-09-08 18:42:00 +0200382 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100383 "List instance is missing its key \"a\".", "Schema location /a:l1, data location /a:l1[b='b'][c='1'], line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200384
Radek Iša56ca9e42020-09-08 18:42:00 +0200385 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100386 "List instance is missing its key \"b\".", "Schema location /a:l1, data location /a:l1[a='a'], line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200387
Radek Iša56ca9e42020-09-08 18:42:00 +0200388 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"b\" : \"b\", \"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100389 "List instance is missing its key \"c\".", "Schema location /a:l1, data location /a:l1[a='a'][b='b'], line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200390
391 /* key duplicate */
Radek Iša56ca9e42020-09-08 18:42:00 +0200392 PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\", \"a\" : \"a\", \"c\" : 1}]}", 0, LYD_VALIDATE_PRESENT,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100393 tree, LY_EVALID, "Duplicate instance of \"c\".", "Schema location /a:l1/c, data location /a:l1[a='a'][b='b'][c='1'][c='1']/c, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200394
395 /* keys order, in contrast to XML, JSON accepts keys in any order even in strict mode */
Radek Iša56ca9e42020-09-08 18:42:00 +0200396 CHECK_PARSE_LYD("{ \"a:l1\": [ {\"d\" : \"d\", \"a\" : \"a\", \"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree);
397 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
398 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100399 list = (struct lyd_node_inner *)tree;
400 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200401 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 +0100402 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200403 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 +0100404 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200405 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 +0100406 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200407 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 0, LYS_LEAF, 1, 0, NULL, 0);
408 CHECK_LOG_CTX(NULL, NULL);
Radek Krejci5536d282020-08-04 23:27:44 +0200409
Radek Iša56ca9e42020-09-08 18:42:00 +0200410 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
411 "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1,\"d\":\"d\"}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200412 lyd_free_all(tree);
413
414 /* */
Radek Iša56ca9e42020-09-08 18:42:00 +0200415 CHECK_PARSE_LYD("{\"a:l1\":[{\"c\":1,\"b\":\"b\",\"a\":\"a\"}]}", LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree);
416 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_ORDBY_SYSTEM, 1, "l1",
417 1, LYS_LIST, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100418 list = (struct lyd_node_inner *)tree;
419 assert_non_null(leaf = (struct lyd_node_term *)list->child);
Radek Iša56ca9e42020-09-08 18:42:00 +0200420 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "a",
421 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100422 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200423 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b",
424 1, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100425 assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
Radek Iša56ca9e42020-09-08 18:42:00 +0200426 CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c",
427 1, LYS_LEAF, 1, 0, NULL, 0);
428 CHECK_LOG_CTX(NULL, NULL);
Radek Krejci5536d282020-08-04 23:27:44 +0200429
Radek Iša56ca9e42020-09-08 18:42:00 +0200430 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
431 "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1}]}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200432 lyd_free_all(tree);
433
Radek Krejci5536d282020-08-04 23:27:44 +0200434 data = "{\"a:cp\":{\"@\":{\"a:hint\":1}}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200435 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200436 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100437 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100438 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 +0200439 1, LYS_CONTAINER, 0, 0, NULL, 0);
440 CHECK_LYD_META(tree->meta, 1, "hint", 0, 1, INT8, "1", 1);
Radek Krejci1798aae2020-07-14 13:26:06 +0200441 assert_null(tree->meta->next);
Radek Krejci5536d282020-08-04 23:27:44 +0200442
Radek Iša56ca9e42020-09-08 18:42:00 +0200443 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200444 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200445}
446
447static void
448test_container(void **state)
449{
Radek Iša56ca9e42020-09-08 18:42:00 +0200450 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200451 struct lyd_node *tree;
452 struct lyd_node_inner *cont;
453
Radek Iša56ca9e42020-09-08 18:42:00 +0200454 CHECK_PARSE_LYD("{\"a:c\":{}}", 0, LYD_VALIDATE_PRESENT, tree);
455 CHECK_LYSC_NODE(tree->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c",
456 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100457 cont = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200458 assert_true(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200459
Radek Iša56ca9e42020-09-08 18:42:00 +0200460 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200461 lyd_free_all(tree);
462
Radek Krejci5536d282020-08-04 23:27:44 +0200463 data = "{\"a:cp\":{}}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200464 CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200465 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100466 tree = tree->next;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100467 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 +0200468 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100469 cont = (struct lyd_node_inner *)tree;
Radek Krejci1798aae2020-07-14 13:26:06 +0200470 assert_false(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200471
Radek Iša56ca9e42020-09-08 18:42:00 +0200472 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200473 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200474}
475
476static void
477test_opaq(void **state)
478{
Radek Krejci1798aae2020-07-14 13:26:06 +0200479 const char *data;
Radek Krejci1798aae2020-07-14 13:26:06 +0200480 struct lyd_node *tree;
481
Radek Krejci1798aae2020-07-14 13:26:06 +0200482 /* invalid value, no flags */
483 data = "{\"a:foo3\":[null]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200484 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100485 "Invalid non-number-encoded uint32 value \"\".", "Schema location /a:foo3, line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200486
487 /* opaq flag */
Michal Vasko1a85d332021-08-27 10:35:28 +0200488 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200489 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0, LY_VALUE_JSON, "foo3", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200490 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200491 lyd_free_all(tree);
492
493 /* missing key, no flags */
494 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"d\":\"val_d\"}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200495 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100496 "List instance is missing its key \"c\".", "Schema location /a:l1, data location /a:l1[a='val_a'][b='val_b'], line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200497
498 /* opaq flag */
Michal Vasko1a85d332021-08-27 10:35:28 +0200499 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200500 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_JSON, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200501 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200502 lyd_free_all(tree);
503
504 /* invalid key, no flags */
505 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}";
Radek Iša56ca9e42020-09-08 18:42:00 +0200506 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
Radek Krejci2efc45b2020-12-22 16:25:44 +0100507 "Invalid non-number-encoded int16 value \"val_c\".", "Schema location /a:l1/c, data location /a:l1[a='val_a'][b='val_b'], line number 1.");
Radek Krejci1798aae2020-07-14 13:26:06 +0200508
509 /* opaq flag */
Michal Vasko1a85d332021-08-27 10:35:28 +0200510 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200511 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_JSON, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200512 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200513 lyd_free_all(tree);
514
515 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":{\"val\":\"val_c\"}}]}";
Michal Vasko1a85d332021-08-27 10:35:28 +0200516 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200517 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_JSON, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200518 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200519 lyd_free_all(tree);
520
521 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\"}]}";
Michal Vasko1a85d332021-08-27 10:35:28 +0200522 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
Radek Krejci8df109d2021-04-23 12:19:08 +0200523 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)tree, 0, 0x1, LY_VALUE_JSON, "l1", 0, 0, NULL, 0, "");
Radek Iša56ca9e42020-09-08 18:42:00 +0200524 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200525 lyd_free_all(tree);
aPiecekb7b29e62021-05-11 10:02:43 +0200526
Michal Vasko6a6e3082022-05-10 10:32:38 +0200527 /* invalid metadata */
aPiecekc5f36a72021-05-18 14:12:31 +0200528 data = "{\"@a:foo\":\"str\",\"@a:foo3\":1,\"a:foo3\":2}";
Michal Vasko6a6e3082022-05-10 10:32:38 +0200529 PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
530 "Unknown module of node \"@a:foo\".", "Data location /@a:foo, line number 1.");
aPiecekc5f36a72021-05-18 14:12:31 +0200531
aPiecekb7b29e62021-05-11 10:02:43 +0200532 /* empty name */
533 PARSER_CHECK_ERROR("{\"@a:foo\":{\"\":0}}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
534 "A JSON object member name cannot be a zero-length string.", "Line number 1.");
Michal Vasko1a85d332021-08-27 10:35:28 +0200535
536 /* opaque data tree format print */
537 data =
538 "{\n"
539 " \"ietf-netconf-nmda:get-data\": {\n"
540 " \"data\": {\n"
541 " \"ietf-keystore:keystore\": {\n"
542 " \"asymmetric-keys\": {\n"
543 " \"asymmetric-key\": [\n"
544 " {\n"
545 " \"name\": \"genkey\",\n"
546 " \"algorithm\": \"rsa2048\"\n"
547 " }\n"
548 " ]\n"
549 " }\n"
550 " },\n"
551 " \"ietf-netconf-server:netconf-server\": {\n"
552 " \"listen\": {\n"
553 " \"idle-timeout\": 3600,\n"
554 " \"endpoint\": [\n"
555 " {\n"
556 " \"name\": \"default-ssh\",\n"
557 " \"ssh\": {\n"
558 " \"tcp-server-parameters\": {\n"
559 " \"local-address\": \"0.0.0.0\",\n"
560 " \"local-port\": 830\n"
561 " },\n"
562 " \"ssh-server-parameters\": {\n"
563 " \"server-identity\": {\n"
564 " \"host-key\": [\n"
565 " {\n"
566 " \"name\": \"default-key\",\n"
567 " \"public-key\": {\n"
568 " \"keystore-reference\": \"genkey\"\n"
569 " }\n"
570 " }\n"
571 " ]\n"
572 " },\n"
573 " \"client-authentication\": {\n"
574 " \"supported-authentication-methods\": {\n"
575 " \"publickey\": [null],\n"
576 " \"passsword\": [null],\n"
577 " \"other\": [\n"
578 " \"interactive\",\n"
579 " \"gssapi\"\n"
580 " ]\n"
581 " }\n"
582 " }\n"
583 " }\n"
584 " }\n"
585 " }\n"
586 " ]\n"
587 " }\n"
588 " }\n"
589 " }\n"
590 " }\n"
591 "}\n";
592 CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
593 CHECK_LYD_STRING(tree, LYD_PRINT_WITHSIBLINGS, data);
594 lyd_free_all(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200595}
596
597static void
598test_rpc(void **state)
599{
Radek Krejci1798aae2020-07-14 13:26:06 +0200600 const char *data;
601 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200602 struct lyd_node *tree, *op;
603 const struct lyd_node *node;
Michal Vaskobbdadda2022-01-06 11:40:10 +0100604 const char *dsc = "Edit data in an NMDA datastore.\n"
605 "\n"
606 "If an error condition occurs such that an error severity\n"
607 "<rpc-error> element is generated, the server will stop\n"
608 "processing the <edit-data> operation and restore the\n"
609 "specified configuration to its complete state at\n"
610 "the start of this <edit-data> operation.";
Radek Krejci1798aae2020-07-14 13:26:06 +0200611
Michal Vaskobbdadda2022-01-06 11:40:10 +0100612 assert_non_null((ly_ctx_load_module(UTEST_LYCTX, "ietf-netconf-nmda", "2019-01-07", NULL)));
Radek Krejci1798aae2020-07-14 13:26:06 +0200613
Michal Vaskobbdadda2022-01-06 11:40:10 +0100614 data = "{\"ietf-netconf-nmda:edit-data\":{"
615 "\"datastore\":\"ietf-datastores:running\","
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100616 "\"config\":{\"a:cp\":{\"z\":[null],\"@z\":{\"ietf-netconf:operation\":\"replace\"}},"
617 "\"a:l1\":[{\"@\":{\"ietf-netconf:operation\":\"replace\"},\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}"
Michal Vasko2552ea32020-12-08 15:32:34 +0100618 "}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200619 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100620 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_RPC_YANG, &tree, &op));
Radek Krejci1798aae2020-07-14 13:26:06 +0200621 ly_in_free(in, 0);
622
623 assert_non_null(op);
Radek Krejci1798aae2020-07-14 13:26:06 +0200624
Radek Krejci2a9fc652021-01-22 17:44:34 +0100625 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, dsc, 0, LYS_STATUS_CURR,
Michal Vaskobbdadda2022-01-06 11:40:10 +0100626 1, 0, 0, 1, "edit-data", LYS_RPC,
627 0, 0, 0, 0, 0, NULL, 0);
Radek Iša56ca9e42020-09-08 18:42:00 +0200628
Michal Vasko2552ea32020-12-08 15:32:34 +0100629 node = tree;
Radek Krejci2a9fc652021-01-22 17:44:34 +0100630 CHECK_LYSC_ACTION((struct lysc_node_action *)node->schema, dsc, 0, LYS_STATUS_CURR,
Michal Vaskobbdadda2022-01-06 11:40:10 +0100631 1, 0, 0, 1, "edit-data", LYS_RPC,
632 0, 0, 0, 0, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200633 node = lyd_child(node)->next;
Michal Vaskobbdadda2022-01-06 11:40:10 +0100634 CHECK_LYSC_NODE(node->schema, "Inline config content.", 0, LYS_STATUS_CURR | LYS_IS_INPUT, 1, "config",
635 0, LYS_ANYDATA, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200636
637 node = ((struct lyd_node_any *)node)->value.tree;
Michal Vaskoe16c7b72021-02-26 10:39:06 +0100638 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 +0200639 1, LYS_CONTAINER, 0, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200640 node = lyd_child(node);
Radek Krejci1798aae2020-07-14 13:26:06 +0200641 /* z has no value */
Radek Krejci8df109d2021-04-23 12:19:08 +0200642 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0, LY_VALUE_JSON, "z", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200643 node = node->parent->next;
644 /* l1 key c has invalid value so it is at the end */
Radek Krejci8df109d2021-04-23 12:19:08 +0200645 CHECK_LYD_NODE_OPAQ((struct lyd_node_opaq *)node, 0x1, 0x1, LY_VALUE_JSON, "l1", 0, 0, NULL, 0, "");
Radek Krejci1798aae2020-07-14 13:26:06 +0200646
Radek Iša56ca9e42020-09-08 18:42:00 +0200647 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200648 lyd_free_all(tree);
649
650 /* wrong namespace, element name, whatever... */
651 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200652}
653
654static void
655test_action(void **state)
656{
Radek Krejci1798aae2020-07-14 13:26:06 +0200657 const char *data;
658 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200659 struct lyd_node *tree, *op;
Radek Krejci1798aae2020-07-14 13:26:06 +0200660
Michal Vasko2552ea32020-12-08 15:32:34 +0100661 data = "{\"a:c\":{\"act\":{\"al\":\"value\"}}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200662 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100663 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_RPC_YANG, &tree, &op));
Radek Krejci1798aae2020-07-14 13:26:06 +0200664 ly_in_free(in, 0);
665
666 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100667 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200668 1, 0, 0, 1, "act", LYS_ACTION,
669 1, 0, 0, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200670
Radek Iša56ca9e42020-09-08 18:42:00 +0200671 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200672 lyd_free_all(tree);
673
674 /* wrong namespace, element name, whatever... */
675 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200676}
677
678static void
679test_notification(void **state)
680{
Radek Krejci1798aae2020-07-14 13:26:06 +0200681 const char *data;
682 struct ly_in *in;
Radek Krejci1798aae2020-07-14 13:26:06 +0200683 struct lyd_node *tree, *ntf;
Radek Krejci1798aae2020-07-14 13:26:06 +0200684
Michal Vasko2552ea32020-12-08 15:32:34 +0100685 data = "{\"a:c\":{\"n1\":{\"nl\":\"value\"}}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200686 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100687 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_NOTIF_YANG, &tree, &ntf));
Radek Krejci1798aae2020-07-14 13:26:06 +0200688 ly_in_free(in, 0);
689
690 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100691 CHECK_LYSC_NOTIF((struct lysc_node_notif *)ntf->schema, 1, NULL, 0, 0x4, 1, 0, "n1", 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200692
Michal Vasko2552ea32020-12-08 15:32:34 +0100693 CHECK_LYSC_NODE(tree->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 +0200694
Radek Iša56ca9e42020-09-08 18:42:00 +0200695 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200696 lyd_free_all(tree);
697
Radek Krejci1798aae2020-07-14 13:26:06 +0200698 data = "{\"a:n2\":{}}";
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, NULL, in, LYD_JSON, LYD_TYPE_NOTIF_YANG, &tree, &ntf));
Radek Krejci1798aae2020-07-14 13:26:06 +0200701 ly_in_free(in, 0);
702
703 assert_non_null(ntf);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100704 CHECK_LYSC_NOTIF((struct lysc_node_notif *)ntf->schema, 0, NULL, 0, 0x4, 1, 0, "n2", 0, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200705
706 assert_non_null(tree);
707 assert_ptr_equal(ntf, tree);
708
Radek Iša56ca9e42020-09-08 18:42:00 +0200709 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, data);
Radek Krejci1798aae2020-07-14 13:26:06 +0200710 lyd_free_all(tree);
711
712 /* wrong namespace, element name, whatever... */
713 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200714}
715
716static void
717test_reply(void **state)
718{
Radek Krejci1798aae2020-07-14 13:26:06 +0200719 const char *data;
720 struct ly_in *in;
Michal Vasko2552ea32020-12-08 15:32:34 +0100721 struct lyd_node *tree, *op;
Radek Krejci1798aae2020-07-14 13:26:06 +0200722 const struct lyd_node *node;
723
Michal Vasko2552ea32020-12-08 15:32:34 +0100724 data = "{\"a:c\":{\"act\":{\"al\":25}}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200725 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
Michal Vasko1e4c68e2021-02-18 15:03:01 +0100726 assert_int_equal(LY_SUCCESS, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_JSON, LYD_TYPE_REPLY_YANG, &tree, &op));
Radek Krejci1798aae2020-07-14 13:26:06 +0200727 ly_in_free(in, 0);
728
Radek Krejci1798aae2020-07-14 13:26:06 +0200729 assert_non_null(op);
Radek Krejci2a9fc652021-01-22 17:44:34 +0100730 CHECK_LYSC_ACTION((struct lysc_node_action *)op->schema, NULL, 0, LYS_STATUS_CURR,
Radek Iša56ca9e42020-09-08 18:42:00 +0200731 1, 0, 0, 1, "act", LYS_ACTION,
732 1, 0, 0, 1, 0, NULL, 0);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200733 node = lyd_child(op);
Michal Vaskod1e53b92021-01-28 13:11:06 +0100734 CHECK_LYSC_NODE(node->schema, NULL, 0, LYS_STATUS_CURR | LYS_IS_OUTPUT, 1, "al", 0, LYS_LEAF, 1, 0, NULL, 0);
Radek Krejci1798aae2020-07-14 13:26:06 +0200735
Michal Vasko2552ea32020-12-08 15:32:34 +0100736 CHECK_LYSC_NODE(tree->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 +0200737
738 /* TODO print only rpc-reply node and then output subtree */
Radek Iša56ca9e42020-09-08 18:42:00 +0200739 CHECK_LYD_STRING(lyd_child(op), LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:al\":25}");
Michal Vasko2552ea32020-12-08 15:32:34 +0100740 CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS, "{\"a:c\":{\"act\":{\"al\":25}}}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200741 lyd_free_all(tree);
742
743 /* wrong namespace, element name, whatever... */
744 /* TODO */
Radek Krejci1798aae2020-07-14 13:26:06 +0200745}
746
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100747int
748main(void)
Radek Krejci1798aae2020-07-14 13:26:06 +0200749{
750 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200751 UTEST(test_leaf, setup),
752 UTEST(test_leaflist, setup),
753 UTEST(test_anydata, setup),
Michal Vasko76096ec2022-02-24 16:06:16 +0100754 UTEST(test_anyxml, setup),
Radek Iša56ca9e42020-09-08 18:42:00 +0200755 UTEST(test_list, setup),
756 UTEST(test_container, setup),
757 UTEST(test_opaq, setup),
758 UTEST(test_rpc, setup),
759 UTEST(test_action, setup),
760 UTEST(test_notification, setup),
761 UTEST(test_reply, setup),
Radek Krejci1798aae2020-07-14 13:26:06 +0200762 };
763
764 return cmocka_run_group_tests(tests, NULL, NULL);
765}