blob: ae810a5491078e1a944eeb65f59a50f03c90358e [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"
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010024#include "in.h"
Radek Krejci70593c12020-06-13 20:48:09 +020025#include "log.h"
26#include "set.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020027#include "tests/config.h"
Radek Krejci70593c12020-06-13 20:48:09 +020028#include "tree_data.h"
29#include "tree_schema.h"
Michal Vasko57c10cd2020-05-27 15:57:11 +020030
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;
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100141 const char *feats[] = {"feat1", NULL};
142 struct ly_in *in;
Michal Vasko57c10cd2020-05-27 15:57:11 +0200143
144#if ENABLE_LOGGER_CHECKING
145 ly_set_log_clb(logger, 1);
146#endif
147
148 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &ctx));
149 ly_ctx_set_module_imp_clb(ctx, test_imp_clb, NULL);
150
Michal Vasko7b1ad1a2020-11-02 15:41:27 +0100151 assert_int_equal(LY_SUCCESS, ly_in_new_memory(schema_a, &in));
152 assert_int_equal(LY_SUCCESS, lys_parse(ctx, in, LYS_IN_YANG, feats, &mod));
153 ly_in_free(in, 0);
Michal Vasko3a41dff2020-07-15 14:30:28 +0200154 assert_int_equal(LY_SUCCESS, lys_parse_mem(ctx, schema_b, LYS_IN_YANG, NULL));
Michal Vasko57c10cd2020-05-27 15:57:11 +0200155
156 return 0;
157}
158
159static int
160teardown(void **state)
161{
162#if ENABLE_LOGGER_CHECKING
163 if (*state) {
164 fprintf(stderr, "%s\n", logbuf);
165 }
166#else
167 (void) state; /* unused */
168#endif
169
170 ly_ctx_destroy(ctx, NULL);
171 ctx = NULL;
172
173 return 0;
174}
175
176void
177logbuf_clean(void)
178{
179 logbuf[0] = '\0';
180}
181
182#if ENABLE_LOGGER_CHECKING
183# define logbuf_assert(str) assert_string_equal(logbuf, str)
184#else
185# define logbuf_assert(str)
186#endif
187
188static void
189test_yanglib(void **state)
190{
191 *state = test_yanglib;
192
193 struct lyd_node *tree;
194 struct ly_set *set;
195 LY_ERR ret;
196
Michal Vasko3a41dff2020-07-15 14:30:28 +0200197 assert_int_equal(LY_SUCCESS, ly_ctx_get_yanglib_data(ctx, &tree));
Michal Vasko57c10cd2020-05-27 15:57:11 +0200198
199 /* make sure there is "a" with a submodule and deviation */
200 ret = lyd_find_xpath(tree, "/ietf-yang-library:yang-library/module-set/module[name='a'][submodule/name='a_sub']"
201 "[feature='feat1'][deviation='b']", &set);
202 assert_int_equal(ret, LY_SUCCESS);
203
204 assert_int_equal(set->count, 1);
205 ly_set_free(set, NULL);
206
207 lyd_free_all(tree);
208 *state = NULL;
209}
210
211int main(void)
212{
213 const struct CMUnitTest tests[] = {
214 cmocka_unit_test_setup_teardown(test_yanglib, setup, teardown),
215 };
216
217 return cmocka_run_group_tests(tests, NULL, NULL);
218}