blob: 9ade723893bed9e3f7dcf20e0776ff716667c623 [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 Krejci1f05b6a2019-07-18 16:15:06 +020059 "list l1 { key \"a b\"; leaf a {type string;} leaf b {type string;} leaf c {type string;}}"
Radek Krejciee4cab22019-07-17 17:07:47 +020060 "leaf foo { type string;}"
61 "anydata any {config false;} }";
Radek Krejci509e2592019-05-15 16:30:48 +020062
63#if ENABLE_LOGGER_CHECKING
64 ly_set_log_clb(logger, 1);
65#endif
66
67 assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, 0, &ctx));
68 assert_non_null(lys_parse_mem(ctx, schema_a, LYS_IN_YANG));
69
70 return 0;
71}
72
73static int
74teardown(void **state)
75{
76#if ENABLE_LOGGER_CHECKING
77 if (*state) {
78 fprintf(stderr, "%s\n", logbuf);
79 }
80#else
81 (void) state; /* unused */
82#endif
83
84 ly_ctx_destroy(ctx, NULL);
85 ctx = NULL;
86
87 return 0;
88}
89
90void
91logbuf_clean(void)
92{
93 logbuf[0] = '\0';
94}
95
96#if ENABLE_LOGGER_CHECKING
97# define logbuf_assert(str) assert_string_equal(logbuf, str)
98#else
99# define logbuf_assert(str)
100#endif
101
Radek Krejci509e2592019-05-15 16:30:48 +0200102static void
103test_leaf(void **state)
104{
105 *state = test_leaf;
106
107 const char *data = "<foo xmlns=\"urn:tests:a\">foo value</foo>";
108 struct lyd_node *tree;
109 struct lyd_node_term *leaf;
110
111 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, &tree));
112 assert_non_null(tree);
113 assert_int_equal(LYS_LEAF, tree->schema->nodetype);
114 assert_string_equal("foo", tree->schema->name);
115 leaf = (struct lyd_node_term*)tree;
116 assert_string_equal("foo value", leaf->value.canonized);
117
118 lyd_free_all(tree);
119 *state = NULL;
120}
121
Radek Krejciee4cab22019-07-17 17:07:47 +0200122static void
123test_anydata(void **state)
124{
125 *state = test_anydata;
126
127 const char *data = "<any xmlns=\"urn:tests:a\">"
128 "<element1><x:element2 x:attr2=\"test\" xmlns:x=\"urn:x\">x:data</x:element2></element1><element1a/>"
129 "</any>";
130 struct lyd_node *tree;
131 struct lyd_node_any *any;
132
133 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, &tree));
134 assert_non_null(tree);
135 assert_int_equal(LYS_ANYDATA, tree->schema->nodetype);
136 assert_string_equal("any", tree->schema->name);
137 any = (struct lyd_node_any*)tree;
138 assert_int_equal(LYD_ANYDATA_XML, any->value_type);
139 assert_string_equal("<element1><x:element2 x:attr2=\"test\" xmlns:x=\"urn:x\">x:data</x:element2></element1><element1a/>", any->value.xml);
140
141 lyd_free_all(tree);
142 *state = NULL;
143}
144
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200145static void
146test_list(void **state)
147{
148 *state = test_list;
149
150 const char *data = "<l1 xmlns=\"urn:tests:a\"><a>one</a><b>one</b><c>one</c></l1>";
151 struct lyd_node *tree, *iter;
152 struct lyd_node_inner *list;
153
154 assert_int_equal(LY_SUCCESS, lyd_parse_xml(ctx, data, 0, &tree));
155 assert_non_null(tree);
156 assert_int_equal(LYS_LIST, tree->schema->nodetype);
157 assert_string_equal("l1", tree->schema->name);
158 list = (struct lyd_node_inner*)tree;
159 LY_LIST_FOR(list->child, iter) {
160 assert_int_not_equal(0, iter->hash);
161 }
162
163 lyd_free_all(tree);
164 *state = NULL;
165}
166
Radek Krejci509e2592019-05-15 16:30:48 +0200167int main(void)
168{
169 const struct CMUnitTest tests[] = {
170 cmocka_unit_test_setup_teardown(test_leaf, setup, teardown),
Radek Krejciee4cab22019-07-17 17:07:47 +0200171 cmocka_unit_test_setup_teardown(test_anydata, setup, teardown),
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200172 cmocka_unit_test_setup_teardown(test_list, setup, teardown),
Radek Krejci509e2592019-05-15 16:30:48 +0200173 };
174
175 return cmocka_run_group_tests(tests, NULL, NULL);
176}