blob: 29ff064b9c36855658ad685b068a1cd31b012a17 [file] [log] [blame]
Michal Vaskocde73ac2019-11-14 16:10:27 +01001/*
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 "../../src/context.h"
24#include "../../src/tree_data_internal.h"
25
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 =
59 "module a {"
60 "namespace urn:tests:a;"
61 "prefix a;"
62 "yang-version 1.1;"
63
64 "container cont {"
65 "leaf a {"
66 "when \"../../c = 'val_c'\";"
67 "type string;"
68 "}"
69 "leaf b {"
70 "type string;"
71 "}"
72 "}"
73 "leaf c {"
74 "when \"/cont/b = 'val_b'\";"
75 "type string;"
76 "}"
77 "}";
Michal Vaskoa3881362020-01-21 15:57:35 +010078 const char *schema_b =
79 "module b {"
80 "namespace urn:tests:b;"
81 "prefix b;"
82 "yang-version 1.1;"
83
84 "choice choic {"
85 "mandatory true;"
86 "leaf a {"
87 "type string;"
88 "}"
89 "case b {"
90 "leaf l {"
91 "type string;"
92 "}"
93 "}"
94 "}"
95 "leaf c {"
96 "mandatory true;"
97 "type string;"
98 "}"
99 "leaf d {"
100 "type empty;"
101 "}"
102 "}";
Michal Vaskocde73ac2019-11-14 16:10:27 +0100103
104#if ENABLE_LOGGER_CHECKING
105 ly_set_log_clb(logger, 1);
106#endif
107
108 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
109 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
Michal Vaskoa3881362020-01-21 15:57:35 +0100110 assert_non_null(lys_parse_mem(ctx, schema_b, LYS_IN_YANG));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100111
112 return 0;
113}
114
115static int
116teardown(void **state)
117{
118#if ENABLE_LOGGER_CHECKING
119 if (*state) {
120 fprintf(stderr, "%s\n", logbuf);
121 }
122#else
123 (void) state; /* unused */
124#endif
125
126 ly_ctx_destroy(ctx, NULL);
127 ctx = NULL;
128
129 return 0;
130}
131
132void
133logbuf_clean(void)
134{
135 logbuf[0] = '\0';
136}
137
138#if ENABLE_LOGGER_CHECKING
139# define logbuf_assert(str) assert_string_equal(logbuf, str)
140#else
141# define logbuf_assert(str)
142#endif
143
144static void
145test_when(void **state)
146{
147 *state = test_when;
148
149 const char *data;
150 struct lyd_node *tree;
151
152 data = "<c xmlns=\"urn:tests:a\">hey</c>";
Michal Vaskoa3881362020-01-21 15:57:35 +0100153 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100154 assert_null(tree);
155 logbuf_assert("When condition \"/cont/b = 'val_b'\" not satisfied.");
156
157 data = "<cont xmlns=\"urn:tests:a\"><b>val_b</b></cont><c xmlns=\"urn:tests:a\">hey</c>";
Michal Vaskoa3881362020-01-21 15:57:35 +0100158 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100159 assert_non_null(tree);
160 assert_string_equal("c", tree->next->schema->name);
161 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
162 lyd_free_all(tree);
163
164 data = "<cont xmlns=\"urn:tests:a\"><a>val</a><b>val_b</b></cont><c xmlns=\"urn:tests:a\">val_c</c>";
Michal Vaskoa3881362020-01-21 15:57:35 +0100165 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
Michal Vaskocde73ac2019-11-14 16:10:27 +0100166 assert_non_null(tree);
167 assert_string_equal("a", lyd_node_children(tree)->schema->name);
168 assert_int_equal(LYD_WHEN_TRUE, lyd_node_children(tree)->flags);
169 assert_string_equal("c", tree->next->schema->name);
170 assert_int_equal(LYD_WHEN_TRUE, tree->next->flags);
171 lyd_free_all(tree);
172
173 *state = NULL;
174}
175
Michal Vaskoa3881362020-01-21 15:57:35 +0100176static void
177test_mandatory(void **state)
178{
179 *state = test_mandatory;
180
181 const char *data;
182 struct lyd_node *tree;
183
184 data = "<d xmlns=\"urn:tests:b\"/>";
185 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
186 assert_null(tree);
187 logbuf_assert("Mandatory node \"choic\" instance does not exist. /b:choic");
188
189 data = "<l xmlns=\"urn:tests:b\">string</l><d xmlns=\"urn:tests:b\"/>";
190 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
191 assert_null(tree);
192 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
193
194 data = "<a xmlns=\"urn:tests:b\">string</a>";
195 assert_int_equal(LY_EVALID, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
196 assert_null(tree);
197 logbuf_assert("Mandatory node \"c\" instance does not exist. /b:c");
198
199 data = "<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>";
200 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, LYD_OPT_VAL_DATA_ONLY, &tree));
201 assert_non_null(tree);
202 lyd_free_withsiblings(tree);
203
204 *state = NULL;
205}
206
Michal Vaskocde73ac2019-11-14 16:10:27 +0100207int main(void)
208{
209 const struct CMUnitTest tests[] = {
210 cmocka_unit_test_setup_teardown(test_when, setup, teardown),
Michal Vaskoa3881362020-01-21 15:57:35 +0100211 cmocka_unit_test_setup_teardown(test_mandatory, setup, teardown),
Michal Vaskocde73ac2019-11-14 16:10:27 +0100212 };
213
214 return cmocka_run_group_tests(tests, NULL, NULL);
215}