blob: 39d5d5c5ad71a495e09b821c3afa642bec7f547f [file] [log] [blame]
Radek Krejci509e2592019-05-15 16:30:48 +02001/*
2 * @file test_parser_xml.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from parser_xml.c
5 *
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
Radek Krejci509e2592019-05-15 16:30:48 +020015#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
Radek Krejci2d7a47b2019-05-16 13:34:10 +020023#include "../../src/context.h"
24#include "../../src/tree_data_internal.h"
Radek Krejci509e2592019-05-15 16:30:48 +020025
26#define BUFSIZE 1024
27char logbuf[BUFSIZE] = {0};
28int store = -1; /* negative for infinite logging, positive for limited logging */
29
30struct ly_ctx *ctx; /* context for tests */
31
32/* set to 0 to printing error messages to stderr instead of checking them in code */
33#define ENABLE_LOGGER_CHECKING 1
34
35#if ENABLE_LOGGER_CHECKING
36static void
37logger(LY_LOG_LEVEL level, const char *msg, const char *path)
38{
39 (void) level; /* unused */
40 if (store) {
41 if (path && path[0]) {
42 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
43 } else {
44 strncpy(logbuf, msg, BUFSIZE - 1);
45 }
46 if (store > 0) {
47 --store;
48 }
49 }
50}
51#endif
52
53static int
54setup(void **state)
55{
56 (void) state; /* unused */
57
58 const char *schema_a = "module a {namespace urn:tests:a;prefix a;yang-version 1.1;"
Radek Krejci710226d2019-07-24 17:24:59 +020059 "list l1 { key \"a b c\"; leaf a {type string;} leaf b {type string;} leaf c {type string;} leaf d {type string;}}"
Radek Krejciee4cab22019-07-17 17:07:47 +020060 "leaf foo { type string;}"
Radek Krejcib6f7ae52019-07-19 10:31:42 +020061 "container c { leaf x {type string;}}"
62 "container cp {presence \"container switch\"; leaf y {type string;}}"
Radek Krejciee4cab22019-07-17 17:07:47 +020063 "anydata any {config false;} }";
Radek Krejci509e2592019-05-15 16:30:48 +020064
65#if ENABLE_LOGGER_CHECKING
66 ly_set_log_clb(logger, 1);
67#endif
68
69 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
70 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
71
72 return 0;
73}
74
75static int
76teardown(void **state)
77{
78#if ENABLE_LOGGER_CHECKING
79 if (*state) {
80 fprintf(stderr, "%s\n", logbuf);
81 }
82#else
83 (void) state; /* unused */
84#endif
85
86 ly_ctx_destroy(ctx, NULL);
87 ctx = NULL;
88
89 return 0;
90}
91
92void
93logbuf_clean(void)
94{
95 logbuf[0] = '\0';
96}
97
98#if ENABLE_LOGGER_CHECKING
99# define logbuf_assert(str) assert_string_equal(logbuf, str)
100#else
101# define logbuf_assert(str)
102#endif
103
Radek Krejci509e2592019-05-15 16:30:48 +0200104static void
105test_leaf(void **state)
106{
107 *state = test_leaf;
108
109 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
110 struct lyd_node *tree;
111 struct lyd_node_term *leaf;
112
Radek Krejcif3b6fec2019-07-24 15:53:11 +0200113 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
Radek Krejci509e2592019-05-15 16:30:48 +0200114 assert_non_null(tree);
115 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
116 assert_string_equal("foo", tree->schema->name);
117 leaf = (struct lyd_node_term*)tree;
118 assert_string_equal("foo value", leaf->value.canonized);
119
120 lyd_free_all(tree);
121 *state = NULL;
122}
123
Radek Krejciee4cab22019-07-17 17:07:47 +0200124static void
125test_anydata(void **state)
126{
127 *state = test_anydata;
128
129 const char *data = "<any xmlns=\"urn:tests:a\">"
130 "<element1><x:element2 x:attr2=\"test\" xmlns:x=\"urn:x\">x:data</x:element2></element1><element1a/>"
131 "</any>";
132 struct lyd_node *tree;
133 struct lyd_node_any *any;
134
Radek Krejcif3b6fec2019-07-24 15:53:11 +0200135 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
Radek Krejciee4cab22019-07-17 17:07:47 +0200136 assert_non_null(tree);
137 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
138 assert_string_equal("any", tree->schema->name);
139 any = (struct lyd_node_any*)tree;
140 assert_int_equal(LYD_ANYDATA_XML, any->value_type);
141 assert_string_equal("<element1><x:element2 x:attr2=\"test\" xmlns:x=\"urn:x\">x:data</x:element2></element1><element1a/>", any->value.xml);
142
143 lyd_free_all(tree);
144 *state = NULL;
145}
146
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200147static void
148test_list(void **state)
149{
150 *state = test_list;
151
152 const char *data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>one</c></l1>";
153 struct lyd_node *tree, *iter;
154 struct lyd_node_inner *list;
Radek Krejci710226d2019-07-24 17:24:59 +0200155 struct lyd_node_term *leaf;
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200156
Radek Krejci710226d2019-07-24 17:24:59 +0200157 /* check hashes */
Radek Krejcif3b6fec2019-07-24 15:53:11 +0200158 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200159 assert_non_null(tree);
160 assert_int_equal(LYS_LIST, tree->schema->nodetype);
161 assert_string_equal("l1", tree->schema->name);
162 list = (struct lyd_node_inner*)tree;
163 LY_LIST_FOR(list->child, iter) {
164 assert_int_not_equal(0, iter->hash);
165 }
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200166 lyd_free_all(tree);
Radek Krejci710226d2019-07-24 17:24:59 +0200167
168 /* keys order */
169 data = "<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>c</c><b>b</b></l1>";
170 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
171 assert_non_null(tree);
172 assert_int_equal(LYS_LIST, tree->schema->nodetype);
173 assert_string_equal("l1", tree->schema->name);
174 list = (struct lyd_node_inner*)tree;
175 assert_non_null(leaf = (struct lyd_node_term*)list->child);
176 assert_string_equal("a", leaf->schema->name);
177 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
178 assert_string_equal("b", leaf->schema->name);
179 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
180 assert_string_equal("c", leaf->schema->name);
181 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
182 assert_string_equal("d", leaf->schema->name);
183 logbuf_assert("Invalid position of the key \"b\" in a list.");
184 lyd_free_all(tree);
185
186 data = "<l1 xmlns=\"urn:tests:a\"><c>c</c><b>b</b><a>a</a></l1>";
187 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
188 assert_non_null(tree);
189 assert_int_equal(LYS_LIST, tree->schema->nodetype);
190 assert_string_equal("l1", tree->schema->name);
191 list = (struct lyd_node_inner*)tree;
192 assert_non_null(leaf = (struct lyd_node_term*)list->child);
193 assert_string_equal("a", leaf->schema->name);
194 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
195 assert_string_equal("b", leaf->schema->name);
196 assert_non_null(leaf = (struct lyd_node_term*)leaf->next);
197 assert_string_equal("c", leaf->schema->name);
198 logbuf_assert("Invalid position of the key \"a\" in a list.");
199 logbuf_clean();
200 lyd_free_all(tree);
201
202 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_STRICT, NULL, &tree));
203 logbuf_assert("Invalid position of the key \"b\" in a list. Line number 1.");
Radek Krejci22ebdba2019-07-25 13:59:43 +0200204/* TODO validation
205 data = "<l1 xmlns=\"urn:tests:a\"><a>a</a><c>c</c><d>d</d></l1>";
206 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_STRICT, NULL, &tree));
207 logbuf_assert("Missing key \"b\" in a list. Line number 1.");
208*/
Radek Krejci710226d2019-07-24 17:24:59 +0200209
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200210 *state = NULL;
211}
212
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200213static void
214test_container(void **state)
215{
216 *state = test_container;
217
218 const char *data = "<c xmlns=\"urn:tests:a\"/>";
219 struct lyd_node *tree;
220 struct lyd_node_inner *cont;
221
Radek Krejcif3b6fec2019-07-24 15:53:11 +0200222 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200223 assert_non_null(tree);
224 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
225 assert_string_equal("c", tree->schema->name);
226 cont = (struct lyd_node_inner*)tree;
227 assert_true(cont->flags & LYD_DEFAULT);
228 lyd_free_all(tree);
229
230 data = "<cp xmlns=\"urn:tests:a\"/>";
Radek Krejcif3b6fec2019-07-24 15:53:11 +0200231 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, NULL, &tree));
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200232 assert_non_null(tree);
233 assert_int_equal(LYS_CONTAINER, tree->schema->nodetype);
234 assert_string_equal("cp", tree->schema->name);
235 cont = (struct lyd_node_inner*)tree;
236 assert_false(cont->flags & LYD_DEFAULT);
237 lyd_free_all(tree);
238
239 *state = NULL;
240}
241
Radek Krejci509e2592019-05-15 16:30:48 +0200242int main(void)
243{
244 const struct CMUnitTest tests[] = {
245 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200246 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200247 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejcib6f7ae52019-07-19 10:31:42 +0200248 cmocka_unit_test_setup_teardown(test_container, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200249 };
250
251 return cmocka_run_group_tests(tests, NULL, NULL);
252}