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