blob: 8f72540e4ec43f839f56a7ccd1ab4693287cda03 [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
Michal Vasko3a41dff2020-07-15 14:30:28 +0200148 assert_int_equal(LY_SUCCESS, lys_parse_mem(ctx, schema_a, LYS_IN_YANG, &mod));
Michal Vasko57c10cd2020-05-27 15:57:11 +0200149 assert_int_equal(LY_SUCCESS, lys_feature_enable(mod, "feat1"));
Michal Vasko3a41dff2020-07-15 14:30:28 +0200150 assert_int_equal(LY_SUCCESS, lys_parse_mem(ctx, schema_b, LYS_IN_YANG, NULL));
Michal Vasko57c10cd2020-05-27 15:57:11 +0200151
152 return 0;
153}
154
155static int
156teardown(void **state)
157{
158#if ENABLE_LOGGER_CHECKING
159 if (*state) {
160 fprintf(stderr, "%s\n", logbuf);
161 }
162#else
163 (void) state; /* unused */
164#endif
165
166 ly_ctx_destroy(ctx, NULL);
167 ctx = NULL;
168
169 return 0;
170}
171
172void
173logbuf_clean(void)
174{
175 logbuf[0] = '\0';
176}
177
178#if ENABLE_LOGGER_CHECKING
179# define logbuf_assert(str) assert_string_equal(logbuf, str)
180#else
181# define logbuf_assert(str)
182#endif
183
184static void
185test_yanglib(void **state)
186{
187 *state = test_yanglib;
188
189 struct lyd_node *tree;
190 struct ly_set *set;
191 LY_ERR ret;
192
Michal Vasko3a41dff2020-07-15 14:30:28 +0200193 assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(ctx, &tree));
Michal Vasko57c10cd2020-05-27 15:57:11 +0200194
195 /* make sure there is "a" with a submodule and deviation */
196 ret = lyd_find_xpath(tree, "/ietf-yang-library:yang-library/module-set/module[name='a'][submodule/name='a_sub']"
197 "[feature='feat1'][deviation='b']", &set);
198 assert_int_equal(ret, LY_SUCCESS);
199
200 assert_int_equal(set->count, 1);
201 ly_set_free(set, NULL);
202
203 lyd_free_all(tree);
204 *state = NULL;
205}
206
207int main(void)
208{
209 const struct CMUnitTest tests[] = {
210 cmocka_unit_test_setup_teardown(test_yanglib, setup, teardown),
211 };
212
213 return cmocka_run_group_tests(tests, NULL, NULL);
214}