blob: 45aca940a05ae9d03ae7441befb5f1cff69171dd [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 */
14
15#include <stdarg.h>
16#include <stddef.h>
17#include <setjmp.h>
18#include <cmocka.h>
19
20#include <stdio.h>
21#include <string.h>
22
23#include "context.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020024#include "in.h"
Radek Krejci1798aae2020-07-14 13:26:06 +020025#include "parser_data.h"
Michal Vaskoafac7822020-10-20 14:22:26 +020026#include "out.h"
Radek Krejci1798aae2020-07-14 13:26:06 +020027#include "printer_data.h"
28#include "tests/config.h"
29#include "tree_data_internal.h"
30#include "tree_schema.h"
31
32#define BUFSIZE 1024
33char logbuf[BUFSIZE] = {0};
34int store = -1; /* negative for infinite logging, positive for limited logging */
35
36struct ly_ctx *ctx; /* context for tests */
37
38/* set to 0 to printing error messages to stderr instead of checking them in code */
39#define ENABLE_LOGGER_CHECKING 1
40
41#if ENABLE_LOGGER_CHECKING
42static void
43logger(LY_LOG_LEVEL level, const char *msg, const char *path)
44{
45 (void) level; /* unused */
46 if (store) {
47 if (path && path[0]) {
48 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
49 } else {
50 strncpy(logbuf, msg, BUFSIZE - 1);
51 }
52 if (store > 0) {
53 --store;
54 }
55 }
56}
57#endif
58
59static int
60setup(void **state)
61{
62 (void) state; /* unused */
63
64 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1; import ietf-yang-metadata {prefix md;}"
65 "md:annotation hint { type int8;}"
66 "list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type int16;} leaf d {type string;}}"
67 "leaf foo { type string;}"
68 "container c {"
69 "leaf x {type string;}"
70 "action act { input { leaf al {type string;} } output { leaf al {type uint8;} } }"
71 "notification n1 { leaf nl {type string;} }"
72 "}"
73 "container cp {presence \"container switch\"; leaf y {type string;} leaf z {type int8;}}"
74 "anydata any {config false;}"
75 "leaf-list ll1 { type uint8; }"
76 "leaf foo2 { type string; default \"default-val\"; }"
77 "leaf foo3 { type uint32; }"
78 "notification n2;}";
79 const struct lys_module *mod;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010080 const char *feats[] = {"writable-running", NULL};
Radek Krejci1798aae2020-07-14 13:26:06 +020081
82#if ENABLE_LOGGER_CHECKING
83 ly_set_log_clb(logger, 1);
84#endif
85
86 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010087 assert_non_null((mod = ly_ctx_load_module(ctx, "ietf-netconf", "2011-06-01", feats)));
88 assert_non_null(ly_ctx_load_module(ctx, "ietf-netconf-with-defaults", "2011-06-01", NULL));
Radek Krejci1798aae2020-07-14 13:26:06 +020089 assert_int_equal(LY_SUCCESS, lys_parse_mem(ctx, schema_a, LYS_IN_YANG, NULL));
90
91 return 0;
92}
93
94static int
95teardown(void **state)
96{
97#if ENABLE_LOGGER_CHECKING
98 if (*state) {
99 fprintf(stderr, "%s\n", logbuf);
100 }
101#else
102 (void) state; /* unused */
103#endif
104
105 ly_ctx_destroy(ctx, NULL);
106 ctx = NULL;
107
108 return 0;
109}
110
111void
112logbuf_clean(void)
113{
114 logbuf[0] = '\0';
115}
116
117#if ENABLE_LOGGER_CHECKING
118# define logbuf_assert(str) assert_string_equal(logbuf, str)
119#else
120# define logbuf_assert(str)
121#endif
122
123static void
124test_leaf(void **state)
125{
126 *state = test_leaf;
127
128 const char *data = "{\"a:foo\":\"foo value\"}";
129 struct lyd_node *tree;
130 struct lyd_node_term *leaf;
131
132 char *printed;
133 struct ly_out *out;
134 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
135
136 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
137 assert_non_null(tree);
138 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
139 assert_string_equal("foo", tree->schema->name);
140 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200141 assert_string_equal("foo value", leaf->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200142
143 assert_int_equal(LYS_LEAF, tree->next->next->schema->nodetype);
144 assert_string_equal("foo2", tree->next->next->schema->name);
145 leaf = (struct lyd_node_term*)tree->next->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200146 assert_string_equal("default-val", leaf->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200147 assert_true(leaf->flags & LYD_DEFAULT);
148
Radek Krejci52f65552020-09-01 17:03:35 +0200149 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200150 assert_string_equal(printed, data);
151 ly_out_reset(out);
152 lyd_free_all(tree);
153
154 /* make foo2 explicit */
155 data = "{\"a:foo2\":\"default-val\"}";
156 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
157 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100158 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200159 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
160 assert_string_equal("foo2", tree->schema->name);
161 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200162 assert_string_equal("default-val", leaf->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200163 assert_false(leaf->flags & LYD_DEFAULT);
164
Radek Krejci52f65552020-09-01 17:03:35 +0200165 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200166 assert_string_equal(printed, data);
167 ly_out_reset(out);
168 lyd_free_all(tree);
169
170 /* parse foo2 but make it implicit */
Radek Krejci5536d282020-08-04 23:27:44 +0200171 data = "{\"a:foo2\":\"default-val\",\"@a:foo2\":{\"ietf-netconf-with-defaults:default\":true}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200172 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
173 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100174 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200175 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
176 assert_string_equal("foo2", tree->schema->name);
177 leaf = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200178 assert_string_equal("default-val", leaf->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200179 assert_true(leaf->flags & LYD_DEFAULT);
180
Radek Krejci5536d282020-08-04 23:27:44 +0200181 /* TODO default values
Radek Krejci52f65552020-09-01 17:03:35 +0200182 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200183 assert_string_equal(printed, data);
184 ly_out_reset(out);
185 */
Radek Krejci1798aae2020-07-14 13:26:06 +0200186 lyd_free_all(tree);
187
188 /* multiple meatadata hint and unknown metadata xxx supposed to be skipped since it is from missing schema */
Radek Krejci5536d282020-08-04 23:27:44 +0200189 data = "{\"@a:foo\":{\"a:hint\":1,\"a:hint\":2,\"x:xxx\":{\"value\":\"/x:no/x:yes\"}},\"a:foo\":\"xxx\"}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200190 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
191 assert_non_null(tree);
192 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
193 assert_string_equal("foo", tree->schema->name);
194 assert_non_null(tree->meta);
195 assert_string_equal("hint", tree->meta->name);
196 assert_int_equal(LY_TYPE_INT8, tree->meta->value.realtype->basetype);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200197 assert_string_equal("1", tree->meta->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200198 assert_int_equal(1, tree->meta->value.int8);
199 assert_ptr_equal(tree, tree->meta->parent);
200 assert_non_null(tree->meta->next);
201 assert_string_equal("hint", tree->meta->next->name);
202 assert_int_equal(LY_TYPE_INT8, tree->meta->next->value.realtype->basetype);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200203 assert_string_equal("2", tree->meta->next->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200204 assert_int_equal(2, tree->meta->next->value.int8);
205 assert_ptr_equal(tree, tree->meta->next->parent);
206 assert_null(tree->meta->next->next);
207
Radek Krejci52f65552020-09-01 17:03:35 +0200208 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200209 assert_string_equal(printed, "{\"a:foo\":\"xxx\",\"@a:foo\":{\"a:hint\":1,\"a:hint\":2}}");
Radek Krejci1798aae2020-07-14 13:26:06 +0200210 ly_out_free(out, NULL, 1);
211 lyd_free_all(tree);
212
213 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
214 logbuf_assert("Unknown (or not implemented) YANG module \"x\" for metadata \"x:xxx\". /a:foo");
215
216 /* missing referenced metadata node */
217 data = "{\"@a:foo\" : { \"a:hint\" : 1 }}";
218 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
219 logbuf_assert("Missing JSON data instance to be coupled with @a:foo metadata. /");
220
221 /* missing namespace for meatadata*/
222 data = "{\"a:foo\" : \"value\", \"@a:foo\" : { \"hint\" : 1 }}";
223 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
224 logbuf_assert("Metadata in JSON must be namespace-qualified, missing prefix for \"hint\". /a:foo");
225
226 *state = NULL;
227}
228
229static void
230test_leaflist(void **state)
231{
232 *state = test_leaflist;
233
Radek Krejci5536d282020-08-04 23:27:44 +0200234 const char *data = "{\"a:ll1\":[10,11]}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200235 struct lyd_node *tree;
236 struct lyd_node_term *ll;
237
Radek Krejci5536d282020-08-04 23:27:44 +0200238 char *printed;
239 struct ly_out *out;
240 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
241
Radek Krejci1798aae2020-07-14 13:26:06 +0200242 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
243 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100244 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200245 assert_int_equal(LYS_LEAFLIST, tree->schema->nodetype);
246 assert_string_equal("ll1", tree->schema->name);
247 ll = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200248 assert_string_equal("10", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200249
250 assert_non_null(tree->next);
251 assert_int_equal(LYS_LEAFLIST, tree->next->schema->nodetype);
252 assert_string_equal("ll1", tree->next->schema->name);
253 ll = (struct lyd_node_term*)tree->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200254 assert_string_equal("11", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200255
Radek Krejci52f65552020-09-01 17:03:35 +0200256 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200257 assert_string_equal(printed, data);
258 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200259 lyd_free_all(tree);
260
261 /* simple metadata */
Radek Krejci5536d282020-08-04 23:27:44 +0200262 data = "{\"a:ll1\":[10,11],\"@a:ll1\":[null,{\"a:hint\":2}]}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200263 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
264 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100265 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200266 assert_int_equal(LYS_LEAFLIST, tree->schema->nodetype);
267 assert_string_equal("ll1", tree->schema->name);
268 ll = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200269 assert_string_equal("10", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200270 assert_null(ll->meta);
271
272 assert_non_null(tree->next);
273 assert_int_equal(LYS_LEAFLIST, tree->next->schema->nodetype);
274 assert_string_equal("ll1", tree->next->schema->name);
275 ll = (struct lyd_node_term*)tree->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200276 assert_string_equal("11", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200277 assert_non_null(ll->meta);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200278 assert_string_equal("2", ll->meta->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200279 assert_null(ll->meta->next);
280
Radek Krejci52f65552020-09-01 17:03:35 +0200281 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200282 assert_string_equal(printed, data);
283 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200284 lyd_free_all(tree);
285
286 /* multiple meatadata hint and unknown metadata xxx supposed to be skipped since it is from missing schema */
287 data = "{\"@a:ll1\" : [{\"a:hint\" : 1, \"x:xxx\" : { \"value\" : \"/x:no/x:yes\" }, \"a:hint\" : 10},null,{\"a:hint\" : 3}], \"a:ll1\" : [1,2,3]}";
288 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
289 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100290 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200291 assert_int_equal(LYS_LEAFLIST, tree->schema->nodetype);
292 assert_string_equal("ll1", tree->schema->name);
293 ll = (struct lyd_node_term*)tree;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200294 assert_string_equal("1", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200295 assert_non_null(ll->meta);
296 assert_string_equal("hint", ll->meta->name);
297 assert_int_equal(LY_TYPE_INT8, ll->meta->value.realtype->basetype);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200298 assert_string_equal("1", ll->meta->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200299 assert_int_equal(1, ll->meta->value.int8);
300 assert_ptr_equal(ll, ll->meta->parent);
301 assert_non_null(ll->meta->next);
302 assert_string_equal("hint", ll->meta->next->name);
303 assert_int_equal(LY_TYPE_INT8, ll->meta->next->value.realtype->basetype);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200304 assert_string_equal("10", ll->meta->next->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200305 assert_int_equal(10, ll->meta->next->value.int8);
306 assert_ptr_equal(ll, ll->meta->next->parent);
307 assert_null(ll->meta->next->next);
308
309 assert_non_null(tree->next);
310 assert_int_equal(LYS_LEAFLIST, tree->next->schema->nodetype);
311 assert_string_equal("ll1", tree->next->schema->name);
312 ll = (struct lyd_node_term*)tree->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200313 assert_string_equal("2", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200314 assert_null(ll->meta);
315
316 assert_non_null(tree->next->next);
317 assert_int_equal(LYS_LEAFLIST, tree->next->next->schema->nodetype);
318 assert_string_equal("ll1", tree->next->next->schema->name);
319 ll = (struct lyd_node_term*)tree->next->next;
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200320 assert_string_equal("3", ll->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200321 assert_non_null(ll->meta);
322 assert_string_equal("hint", ll->meta->name);
323 assert_int_equal(LY_TYPE_INT8, ll->meta->value.realtype->basetype);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200324 assert_string_equal("3", ll->meta->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200325 assert_int_equal(3, ll->meta->value.int8);
326 assert_ptr_equal(ll, ll->meta->parent);
327 assert_null(ll->meta->next);
328
Radek Krejci52f65552020-09-01 17:03:35 +0200329 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200330 assert_string_equal(printed, "{\"a:ll1\":[1,2,3],\"@a:ll1\":[{\"a:hint\":1,\"a:hint\":10},null,{\"a:hint\":3}]}");
331 ly_out_free(out, NULL, 1);
Radek Krejci1798aae2020-07-14 13:26:06 +0200332 lyd_free_all(tree);
333
334 /* missing referenced metadata node */
335 data = "{\"@a:ll1\":[{\"a:hint\":1}]}";
336 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
337 logbuf_assert("Missing JSON data instance to be coupled with @a:ll1 metadata. /");
338
339 data = "{\"a:ll1\":[1],\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2}]}";
340 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
341 logbuf_assert("Missing JSON data instance no. 2 of a:ll1 to be coupled with metadata. /");
342
343 data = "{\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2},{\"a:hint\":3}],\"a:ll1\" : [1, 2]}";
344 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
345 logbuf_assert("Missing 3rd JSON data instance to be coupled with @a:ll1 metadata. /");
346
347 *state = NULL;
348}
349
350static void
351test_anydata(void **state)
352{
353 *state = test_anydata;
354
355 const char *data;
356 char *str;
357 struct lyd_node *tree;
358
359 struct ly_out *out;
360 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
361
362 data = "{\"a:any\":{\"x:element1\":{\"element2\":\"/a:some/a:path\",\"list\":[{},{\"key\":\"a\"}]}}}";
363 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
364 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100365 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200366 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
367 assert_string_equal("any", tree->schema->name);
368
Radek Krejci52f65552020-09-01 17:03:35 +0200369 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200370 assert_string_equal(str, data);
371 ly_out_reset(out);
372
373 lyd_free_all(tree);
374 ly_out_free(out, NULL, 1);
375
376 *state = NULL;
377}
378
379static void
380test_list(void **state)
381{
382 *state = test_list;
383
Radek Krejci5536d282020-08-04 23:27:44 +0200384 const char *data = "{\"a:l1\":[{\"a\":\"one\",\"b\":\"one\",\"c\":1}]}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200385 struct lyd_node *tree, *iter;
386 struct lyd_node_inner *list;
387 struct lyd_node_term *leaf;
388
Radek Krejci5536d282020-08-04 23:27:44 +0200389 char *printed;
390 struct ly_out *out;
391 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
392
Radek Krejci1798aae2020-07-14 13:26:06 +0200393 /* check hashes */
394 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
395 assert_non_null(tree);
396 assert_int_equal(LYS_LIST, tree->schema->nodetype);
397 assert_string_equal("l1", tree->schema->name);
398 list = (struct lyd_node_inner*)tree;
399 LY_LIST_FOR(list->child, iter) {
400 assert_int_not_equal(0, iter->hash);
401 }
Radek Krejci5536d282020-08-04 23:27:44 +0200402
Radek Krejci52f65552020-09-01 17:03:35 +0200403 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200404 assert_string_equal(printed, data);
405 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200406 lyd_free_all(tree);
407
408 /* missing keys */
409 data = "{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\"}]}";
410 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
411 logbuf_assert("List instance is missing its key \"a\". /a:l1[b='b'][c='1']");
412
413 data = "{ \"a:l1\": [ {\"a\" : \"a\"}]}";
414 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
415 logbuf_assert("List instance is missing its key \"b\". /a:l1[a='a']");
416
417 data = "{ \"a:l1\": [ {\"b\" : \"b\", \"a\" : \"a\"}]}";
418 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
419 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='a'][b='b']");
420
421 /* key duplicate */
422 data = "{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\", \"a\" : \"a\", \"c\" : 1}]}";
423 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
424 logbuf_assert("Duplicate instance of \"c\". /a:l1[a='a'][b='b'][c='1'][c='1']/c");
425
426 /* keys order, in contrast to XML, JSON accepts keys in any order even in strict mode */
427 logbuf_clean();
428 data = "{ \"a:l1\": [ {\"d\" : \"d\", \"a\" : \"a\", \"c\" : 1, \"b\" : \"b\"}]}";
429 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
430 assert_non_null(tree);
431 assert_int_equal(LYS_LIST, tree->schema->nodetype);
432 assert_string_equal("l1", tree->schema->name);
433 list = (struct lyd_node_inner*)tree;
434 assert_non_null(leaf = (struct lyd_node_term*)list->child);
435 assert_string_equal("a", leaf->schema->name);
436 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
437 assert_string_equal("b", leaf->schema->name);
438 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
439 assert_string_equal("c", leaf->schema->name);
440 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
441 assert_string_equal("d", leaf->schema->name);
442 logbuf_assert("");
Radek Krejci5536d282020-08-04 23:27:44 +0200443
Radek Krejci52f65552020-09-01 17:03:35 +0200444 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200445 assert_string_equal(printed, "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1,\"d\":\"d\"}]}");
446 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200447 lyd_free_all(tree);
448
449 /* */
Radek Krejci5536d282020-08-04 23:27:44 +0200450 data = "{\"a:l1\":[{\"c\":1,\"b\":\"b\",\"a\":\"a\"}]}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200451 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, &tree));
452 assert_non_null(tree);
453 assert_int_equal(LYS_LIST, tree->schema->nodetype);
454 assert_string_equal("l1", tree->schema->name);
455 list = (struct lyd_node_inner*)tree;
456 assert_non_null(leaf = (struct lyd_node_term*)list->child);
457 assert_string_equal("a", leaf->schema->name);
458 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
459 assert_string_equal("b", leaf->schema->name);
460 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
461 assert_string_equal("c", leaf->schema->name);
462 logbuf_assert("");
Radek Krejci5536d282020-08-04 23:27:44 +0200463
Radek Krejci52f65552020-09-01 17:03:35 +0200464 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200465 assert_string_equal(printed, "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1}]}");
466 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200467 lyd_free_all(tree);
468
Radek Krejci5536d282020-08-04 23:27:44 +0200469 data = "{\"a:cp\":{\"@\":{\"a:hint\":1}}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200470 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
471 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100472 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200473 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
474 assert_string_equal("cp", tree->schema->name);
475 assert_non_null(tree->meta);
476 assert_string_equal("hint", tree->meta->name);
Michal Vaskoba99a3e2020-08-18 15:50:05 +0200477 assert_string_equal("1", tree->meta->value.canonical);
Radek Krejci1798aae2020-07-14 13:26:06 +0200478 assert_ptr_equal(tree, tree->meta->parent);
479 assert_null(tree->meta->next);
Radek Krejci5536d282020-08-04 23:27:44 +0200480
Radek Krejci52f65552020-09-01 17:03:35 +0200481 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200482 assert_string_equal(printed, data);
483 ly_out_free(out, NULL, 1);
Radek Krejci1798aae2020-07-14 13:26:06 +0200484 lyd_free_all(tree);
485
486 *state = NULL;
487}
488
489static void
490test_container(void **state)
491{
492 *state = test_container;
493
Radek Krejci5536d282020-08-04 23:27:44 +0200494 const char *data = "{\"a:c\":{}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200495 struct lyd_node *tree;
496 struct lyd_node_inner *cont;
497
Radek Krejci5536d282020-08-04 23:27:44 +0200498 char *printed;
499 struct ly_out *out;
500 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&printed, 0, &out));
501
Radek Krejci1798aae2020-07-14 13:26:06 +0200502 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
503 assert_non_null(tree);
504 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
505 assert_string_equal("c", tree->schema->name);
506 cont = (struct lyd_node_inner*)tree;
507 assert_true(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200508
Radek Krejci52f65552020-09-01 17:03:35 +0200509 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200510 assert_string_equal(printed, "{}");
511 ly_out_reset(out);
Radek Krejci1798aae2020-07-14 13:26:06 +0200512 lyd_free_all(tree);
513
Radek Krejci5536d282020-08-04 23:27:44 +0200514 data = "{\"a:cp\":{}}";
Radek Krejci1798aae2020-07-14 13:26:06 +0200515 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
516 assert_non_null(tree);
Michal Vasko26123192020-11-09 21:02:34 +0100517 tree = tree->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200518 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
519 assert_string_equal("cp", tree->schema->name);
520 cont = (struct lyd_node_inner*)tree;
521 assert_false(cont->flags & LYD_DEFAULT);
Radek Krejci5536d282020-08-04 23:27:44 +0200522
Radek Krejci52f65552020-09-01 17:03:35 +0200523 lyd_print_all(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci5536d282020-08-04 23:27:44 +0200524 assert_string_equal(printed, data);
525 ly_out_free(out, NULL, 1);
Radek Krejci1798aae2020-07-14 13:26:06 +0200526 lyd_free_all(tree);
527
528 *state = NULL;
529}
530
531static void
532test_opaq(void **state)
533{
534 *state = test_opaq;
535
536 const char *data;
537 char *str;
538 struct lyd_node *tree;
539
540 struct ly_out *out;
541 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
542
543 /* invalid value, no flags */
544 data = "{\"a:foo3\":[null]}";
545 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskofeca4fb2020-10-05 08:58:40 +0200546 logbuf_assert("Invalid non-number-encoded uint32 value \"\". /a:foo3");
Radek Krejci1798aae2020-07-14 13:26:06 +0200547 assert_null(tree);
548
549 /* opaq flag */
550 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
551 assert_non_null(tree);
552 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100553 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "foo3");
Radek Krejci1798aae2020-07-14 13:26:06 +0200554 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
555
Radek Krejci52f65552020-09-01 17:03:35 +0200556 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200557 assert_string_equal(str, data);
558 ly_out_reset(out);
559 lyd_free_all(tree);
560
561 /* missing key, no flags */
562 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"d\":\"val_d\"}]}";
563 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
564 logbuf_assert("List instance is missing its key \"c\". /a:l1[a='val_a'][b='val_b']");
565 assert_null(tree);
566
567 /* opaq flag */
568 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
569 assert_non_null(tree);
570 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100571 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Radek Krejci1798aae2020-07-14 13:26:06 +0200572 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
573
Radek Krejci52f65552020-09-01 17:03:35 +0200574 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200575 assert_string_equal(str, data);
576 ly_out_reset(out);
577 lyd_free_all(tree);
578
579 /* invalid key, no flags */
580 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}";
581 assert_int_equal(LY_EVALID, lyd_parse_data_mem(ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
Michal Vaskofeca4fb2020-10-05 08:58:40 +0200582 logbuf_assert("Invalid non-number-encoded int16 value \"val_c\". /a:l1/c");
Radek Krejci1798aae2020-07-14 13:26:06 +0200583 assert_null(tree);
584
585 /* opaq flag */
586 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
587 assert_non_null(tree);
588 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100589 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Radek Krejci1798aae2020-07-14 13:26:06 +0200590 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
591
Radek Krejci52f65552020-09-01 17:03:35 +0200592 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200593 assert_string_equal(str, data);
594 ly_out_reset(out);
595 lyd_free_all(tree);
596
597 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":{\"val\":\"val_c\"}}]}";
598 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
599 assert_non_null(tree);
600 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100601 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Radek Krejci1798aae2020-07-14 13:26:06 +0200602 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
603
Radek Krejci52f65552020-09-01 17:03:35 +0200604 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200605 assert_string_equal(str, data);
606 ly_out_reset(out);
607 lyd_free_all(tree);
608
609 data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\"}]}";
610 assert_int_equal(LY_SUCCESS, lyd_parse_data_mem(ctx, data, LYD_JSON, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
611 assert_non_null(tree);
612 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100613 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "l1");
Radek Krejci1798aae2020-07-14 13:26:06 +0200614 assert_string_equal(((struct lyd_node_opaq *)tree)->value, "");
615
Radek Krejci52f65552020-09-01 17:03:35 +0200616 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200617 assert_string_equal(str, data);
618 ly_out_reset(out);
619 lyd_free_all(tree);
620
621 ly_out_free(out, NULL, 1);
622
623 *state = NULL;
624}
625
626static void
627test_rpc(void **state)
628{
629 *state = test_rpc;
630
631 const char *data;
632 struct ly_in *in;
633 char *str;
634 struct lyd_node *tree, *op;
635 const struct lyd_node *node;
636
637 struct ly_out *out;
638 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
639
640 data = "{\"ietf-netconf:rpc\":{\"edit-config\":{"
641 "\"target\":{\"running\":[null]},"
642 "\"config\":{\"a:cp\":{\"z\":[null],\"@z\":{\"ietf-netconf:operation\":\"replace\"}},"
643 "\"a:l1\":[{\"@\":{\"ietf-netconf:operation\":\"replace\"},\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}"
644 "}}}";
645 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
646 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_JSON, &tree, &op));
647 ly_in_free(in, 0);
648
649 assert_non_null(op);
650 assert_string_equal(op->schema->name, "edit-config");
651
652 assert_non_null(tree);
653 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100654 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc");
Radek Krejci1798aae2020-07-14 13:26:06 +0200655 /* TODO support generic attributes in JSON ?
656 assert_non_null(((struct lyd_node_opaq *)tree)->attr);
657 */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200658 node = lyd_child(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200659 assert_string_equal(node->schema->name, "edit-config");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200660 node = lyd_child(node)->next;
Radek Krejci1798aae2020-07-14 13:26:06 +0200661 assert_string_equal(node->schema->name, "config");
662
663 node = ((struct lyd_node_any *)node)->value.tree;
664 assert_non_null(node->schema);
665 assert_string_equal(node->schema->name, "cp");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200666 node = lyd_child(node);
Radek Krejci1798aae2020-07-14 13:26:06 +0200667 /* z has no value */
668 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100669 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "z");
Radek Krejci1798aae2020-07-14 13:26:06 +0200670 node = node->parent->next;
671 /* l1 key c has invalid value so it is at the end */
672 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100673 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "l1");
Radek Krejci1798aae2020-07-14 13:26:06 +0200674
Radek Krejci52f65552020-09-01 17:03:35 +0200675 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200676 assert_string_equal(str, data);
677 ly_out_reset(out);
678 lyd_free_all(tree);
679
680 /* wrong namespace, element name, whatever... */
681 /* TODO */
682
683 ly_out_free(out, NULL, 1);
684
685 *state = NULL;
686}
687
688static void
689test_action(void **state)
690{
691 *state = test_action;
692
693 const char *data;
694 struct ly_in *in;
695 char *str;
696 struct lyd_node *tree, *op;
697 const struct lyd_node *node;
698
699 struct ly_out *out;
700 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
701
702 data = "{\"ietf-netconf:rpc\":{\"yang:action\":{\"a:c\":{\"act\":{\"al\":\"value\"}}}}}";
703 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
704 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_JSON, &tree, &op));
705 ly_in_free(in, 0);
706
707 assert_non_null(op);
708 assert_string_equal(op->schema->name, "act");
709
710 assert_non_null(tree);
711 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100712 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc");
Radek Krejci1798aae2020-07-14 13:26:06 +0200713 assert_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200714 node = lyd_child(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200715 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100716 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "action");
Radek Krejci1798aae2020-07-14 13:26:06 +0200717 assert_null(((struct lyd_node_opaq *)node)->attr);
718
Radek Krejci52f65552020-09-01 17:03:35 +0200719 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200720 assert_string_equal(str, data);
721 ly_out_reset(out);
722 lyd_free_all(tree);
723
724 /* wrong namespace, element name, whatever... */
725 /* TODO */
726
727 ly_out_free(out, NULL, 1);
728
729 *state = NULL;
730}
731
732static void
733test_notification(void **state)
734{
735 *state = test_notification;
736
737 const char *data;
738 struct ly_in *in;
739 char *str;
740 struct lyd_node *tree, *ntf;
741 const struct lyd_node *node;
742
743 struct ly_out *out;
744 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
745
746 data = "{\"ietf-restconf:notification\":{\"eventTime\":\"2037-07-08T00:01:00Z\",\"a:c\":{\"n1\":{\"nl\":\"value\"}}}}";
747 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
748 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_JSON, &tree, &ntf));
749 ly_in_free(in, 0);
750
751 assert_non_null(ntf);
752 assert_string_equal(ntf->schema->name, "n1");
753
754 assert_non_null(tree);
755 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100756 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "notification");
Radek Krejci1798aae2020-07-14 13:26:06 +0200757 assert_null(((struct lyd_node_opaq *)tree)->attr);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200758 node = lyd_child(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200759 assert_null(node->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100760 assert_string_equal(((struct lyd_node_opaq *)node)->name.name, "eventTime");
Radek Krejci1798aae2020-07-14 13:26:06 +0200761 assert_string_equal(((struct lyd_node_opaq *)node)->value, "2037-07-08T00:01:00Z");
762 assert_null(((struct lyd_node_opaq *)node)->attr);
763 node = node->next;
764 assert_non_null(node->schema);
765 assert_string_equal(node->schema->name, "c");
766
Radek Krejci52f65552020-09-01 17:03:35 +0200767 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200768 assert_string_equal(str, data);
769 ly_out_reset(out);
770 lyd_free_all(tree);
771
772 /* top-level notif without envelope */
773 data = "{\"a:n2\":{}}";
774 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
775 assert_int_equal(LY_SUCCESS, lyd_parse_notif(ctx, in, LYD_JSON, &tree, &ntf));
776 ly_in_free(in, 0);
777
778 assert_non_null(ntf);
779 assert_string_equal(ntf->schema->name, "n2");
780
781 assert_non_null(tree);
782 assert_ptr_equal(ntf, tree);
783
Radek Krejci52f65552020-09-01 17:03:35 +0200784 lyd_print_tree(out, tree, LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200785 assert_string_equal(str, data);
786 ly_out_reset(out);
787 lyd_free_all(tree);
788
789 /* wrong namespace, element name, whatever... */
790 /* TODO */
791
792 ly_out_free(out, NULL, 1);
793
794 *state = NULL;
795}
796
797static void
798test_reply(void **state)
799{
800 *state = test_reply;
801
802 const char *data;
803 struct ly_in *in;
804 char *str;
805 struct lyd_node *request, *tree, *op;
806 const struct lyd_node *node;
807
808 struct ly_out *out;
809 assert_int_equal(LY_SUCCESS, ly_out_new_memory(&str, 0, &out));
810
811 data = "{\"a:c\":{\"act\":{\"al\":\"value\"}}}";
812 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
813 assert_int_equal(LY_SUCCESS, lyd_parse_rpc(ctx, in, LYD_JSON, &request, NULL));
814 ly_in_free(in, 0);
815
816 data = "{\"ietf-netconf:rpc-reply\":{\"a:al\":25}}";
817 assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
818 assert_int_equal(LY_SUCCESS, lyd_parse_reply(request, in, LYD_JSON, &tree, &op));
819 ly_in_free(in, 0);
820 lyd_free_all(request);
821
822 assert_non_null(op);
823 assert_string_equal(op->schema->name, "act");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200824 node = lyd_child(op);
Radek Krejci1798aae2020-07-14 13:26:06 +0200825 assert_non_null(node->schema);
826 assert_string_equal(node->schema->name, "al");
827 assert_true(node->schema->flags & LYS_CONFIG_R);
828
829 assert_non_null(tree);
830 assert_null(tree->schema);
Michal Vaskoad92b672020-11-12 13:11:31 +0100831 assert_string_equal(((struct lyd_node_opaq *)tree)->name.name, "rpc-reply");
Radek Krejcia1c1e542020-09-29 16:06:52 +0200832 node = lyd_child(tree);
Radek Krejci1798aae2020-07-14 13:26:06 +0200833 assert_non_null(node->schema);
834 assert_string_equal(node->schema->name, "c");
835
836 /* TODO print only rpc-reply node and then output subtree */
Radek Krejcia1c1e542020-09-29 16:06:52 +0200837 lyd_print_tree(out, lyd_child(op), LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200838 assert_string_equal(str, "{\"a:al\":25}");
839 ly_out_reset(out);
Radek Krejcia1c1e542020-09-29 16:06:52 +0200840 lyd_print_tree(out, lyd_child(tree), LYD_JSON, LYD_PRINT_SHRINK);
Radek Krejci1798aae2020-07-14 13:26:06 +0200841 assert_string_equal(str, "{\"a:c\":{\"act\":{\"al\":25}}}");
842 ly_out_reset(out);
843 lyd_free_all(tree);
844
845 /* wrong namespace, element name, whatever... */
846 /* TODO */
847
848 ly_out_free(out, NULL, 1);
849
850 *state = NULL;
851}
852
853int main(void)
854{
855 const struct CMUnitTest tests[] = {
856 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
857 cmocka_unit_test_setup_teardown(test_leaflist, setup, teardown),
858 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
859 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
860 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
861 cmocka_unit_test_setup_teardown(test_opaq, setup, teardown),
862 cmocka_unit_test_setup_teardown(test_rpc, setup, teardown),
863 cmocka_unit_test_setup_teardown(test_action, setup, teardown),
864 cmocka_unit_test_setup_teardown(test_notification, setup, teardown),
865 cmocka_unit_test_setup_teardown(test_reply, setup, teardown),
866 };
867
868 return cmocka_run_group_tests(tests, NULL, NULL);
869}