blob: 15afc81095dd1953e53fc54bfcfb1039fdd10f0b [file] [log] [blame]
Michal Vasko57c10cd2020-05-27 15:57:11 +02001/**
2 * @file test_yanglib.c
3 * @author: Michal Vasko <mvasko@cesnet.cz>
4 * @brief unit tests for ietf-yang-library data
5 *
6 * Copyright (c) 2020 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
Michal Vasko57c10cd2020-05-27 15:57:11 +020015#include <stdarg.h>
16#include <stddef.h>
Radek Krejci535ea9f2020-05-29 16:01:05 +020017#include <stdlib.h>
Michal Vasko57c10cd2020-05-27 15:57:11 +020018#include <setjmp.h>
Michal Vasko57c10cd2020-05-27 15:57:11 +020019#include <string.h>
20
Radek Krejci535ea9f2020-05-29 16:01:05 +020021#include <cmocka.h>
22
23#include "tests/config.h"
24
Michal Vasko57c10cd2020-05-27 15:57:11 +020025#include "../../src/context.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020026#include "../../src/log.h"
27#include "../../src/set.h"
28#include "../../src/tree_data.h"
Michal Vasko57c10cd2020-05-27 15:57:11 +020029#include "../../src/tree_schema.h"
30
31#define BUFSIZE 1024
32char logbuf[BUFSIZE] = {0};
33int store = -1; /* negative for infinite logging, positive for limited logging */
34
35struct ly_ctx *ctx; /* context for tests */
36
37/* set to 0 to printing error messages to stderr instead of checking them in code */
38#define ENABLE_LOGGER_CHECKING 1
39
40#if ENABLE_LOGGER_CHECKING
41static void
42logger(LY_LOG_LEVEL level, const char *msg, const char *path)
43{
44 (void) level; /* unused */
45 if (store) {
46 if (path && path[0]) {
47 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
48 } else {
49 strncpy(logbuf, msg, BUFSIZE - 1);
50 }
51 if (store > 0) {
52 --store;
53 }
54 }
55}
56#endif
57
58static LY_ERR
59test_imp_clb(const char *mod_name, const char *mod_rev, const char *submod_name, const char *sub_rev, void *user_data,
60 LYS_INFORMAT *format, const char **module_data, void (**free_module_data)(void *model_data, void *user_data))
61{
62 const char *schema_a_sub =
63 "submodule a_sub {"
64 "belongs-to a {"
65 "prefix a;"
66 "}"
67 "yang-version 1.1;"
68
69 "feature feat1;"
70
71 "list l3 {"
72 "key \"a\";"
73 "leaf a {"
74 "type uint16;"
75 "}"
76 "leaf b {"
77 "type uint16;"
78 "}"
79 "}"
80 "}";
81
82 assert_string_equal(mod_name, "a");
83 assert_null(mod_rev);
84 if (!submod_name) {
85 return LY_ENOTFOUND;
86 }
87 assert_string_equal(submod_name, "a_sub");
88 assert_null(sub_rev);
89 assert_null(user_data);
90
91 *format = LYS_IN_YANG;
92 *module_data = schema_a_sub;
93 *free_module_data = NULL;
94 return LY_SUCCESS;
95}
96
97static int
98setup(void **state)
99{
100 (void) state; /* unused */
101
102 const char *schema_a =
103 "module a {"
104 "namespace urn:tests:a;"
105 "prefix a;"
106 "yang-version 1.1;"
107
108 "include a_sub;"
109
110 "list l2 {"
111 "key \"a\";"
112 "leaf a {"
113 "type uint16;"
114 "}"
115 "leaf b {"
116 "type uint16;"
117 "}"
118 "}"
119 "}";
120 const char *schema_b =
121 "module b {"
122 "namespace urn:tests:b;"
123 "prefix b;"
124 "yang-version 1.1;"
125
126 "import a {"
127 "prefix a;"
128 "}"
129
130 "deviation /a:l2 {"
131 "deviate add {"
132 "max-elements 40;"
133 "}"
134 "}"
135
136 "leaf foo {"
137 "type string;"
138 "}"
139 "}";
140 const struct lys_module *mod;
141
142#if ENABLE_LOGGER_CHECKING
143 ly_set_log_clb(logger, 1);
144#endif
145
146 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
147 ly_ctx_set_module_imp_clb(ctx, test_imp_clb, NULL);
148
149 mod = lys_parse_mem(ctx, schema_a, LYS_IN_YANG);
150 assert_non_null(mod);
151 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "feat1"));
152 assert_non_null(lys_parse_mem(ctx, schema_b, LYS_IN_YANG));
153
154 return 0;
155}
156
157static int
158teardown(void **state)
159{
160#if ENABLE_LOGGER_CHECKING
161 if (*state) {
162 fprintf(stderr, "%s\n", logbuf);
163 }
164#else
165 (void) state; /* unused */
166#endif
167
168 ly_ctx_destroy(ctx, NULL);
169 ctx = NULL;
170
171 return 0;
172}
173
174void
175logbuf_clean(void)
176{
177 logbuf[0] = '\0';
178}
179
180#if ENABLE_LOGGER_CHECKING
181# define logbuf_assert(str) assert_string_equal(logbuf, str)
182#else
183# define logbuf_assert(str)
184#endif
185
186static void
187test_yanglib(void **state)
188{
189 *state = test_yanglib;
190
191 struct lyd_node *tree;
192 struct ly_set *set;
193 LY_ERR ret;
194
195 tree = ly_ctx_get_yanglib_data(ctx);
196 assert_non_null(tree);
197
198 /* make sure there is "a" with a submodule and deviation */
199 ret = lyd_find_xpath(tree, "/ietf-yang-library:yang-library/module-set/module[name='a'][submodule/name='a_sub']"
200 "[feature='feat1'][deviation='b']", &set);
201 assert_int_equal(ret, LY_SUCCESS);
202
203 assert_int_equal(set->count, 1);
204 ly_set_free(set, NULL);
205
206 lyd_free_all(tree);
207 *state = NULL;
208}
209
210int main(void)
211{
212 const struct CMUnitTest tests[] = {
213 cmocka_unit_test_setup_teardown(test_yanglib, setup, teardown),
214 };
215
216 return cmocka_run_group_tests(tests, NULL, NULL);
217}