1 /**
2 * @file test_when_1.1.c
3 * @author Michal Vasko <mvasko@cesnet.cz>
4 * @brief Cmocka tests for resolving YANG 1.1 when-stmt constraints.
5 *
6 * Copyright (c) 2016 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
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <setjmp.h>
18 #include <stdarg.h>
19 #include <cmocka.h>
20
21 #include "tests/config.h"
22 #include "libyang.h"
23
24 struct state {
25 struct ly_ctx *ctx;
26 const struct lys_module *mod;
27 struct lyd_node *dt;
28 char *xml;
29 };
30
31 static int
setup_f(void ** state)32 setup_f(void **state)
33 {
34 struct state *st;
35
36 (*state) = st = calloc(1, sizeof *st);
37 if (!st) {
38 fprintf(stderr, "Memory allocation error");
39 return -1;
40 }
41
42 /* libyang context */
43 st->ctx = ly_ctx_new(NULL, 0);
44 if (!st->ctx) {
45 fprintf(stderr, "Failed to create context.\n");
46 goto error;
47 }
48
49 return 0;
50
51 error:
52 ly_ctx_destroy(st->ctx, NULL);
53 free(st);
54 (*state) = NULL;
55
56 return -1;
57 }
58
59 static int
teardown_f(void ** state)60 teardown_f(void **state)
61 {
62 struct state *st = (*state);
63
64 lyd_free_withsiblings(st->dt);
65 ly_ctx_destroy(st->ctx, NULL);
66 free(st->xml);
67 free(st);
68 (*state) = NULL;
69
70 return 0;
71 }
72
73 static void
test_unlink_uses(void ** state)74 test_unlink_uses(void **state)
75 {
76 struct state *st = (struct state *)*state;
77
78 /* schema */
79 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlink.yin", LYS_IN_YIN);
80 assert_ptr_not_equal(st->mod, NULL);
81
82 st->dt = lyd_new_path(NULL, st->ctx, "/when-unlink:top/e", "val_e", 0, 0);
83 assert_ptr_not_equal(st->dt, NULL);
84
85 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
86
87 lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
88 assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:when-unlink\"><e>val_e</e></top>");
89 }
90
91 static void
test_unlink_choice(void ** state)92 test_unlink_choice(void **state)
93 {
94 struct state *st = (struct state *)*state;
95
96 /* schema */
97 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlink.yin", LYS_IN_YIN);
98 assert_ptr_not_equal(st->mod, NULL);
99
100 st->dt = lyd_new_path(NULL, st->ctx, "/when-unlink:top/cas2", NULL, 0, 0);
101 assert_ptr_not_equal(st->dt, NULL);
102
103 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
104
105 lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
106 assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:when-unlink\"><cas2/></top>");
107 }
108
109 static void
test_unlink_case(void ** state)110 test_unlink_case(void **state)
111 {
112 struct state *st = (struct state *)*state;
113 struct lyd_node *node;
114
115 /* schema */
116 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlink.yin", LYS_IN_YIN);
117 assert_ptr_not_equal(st->mod, NULL);
118
119 st->dt = lyd_new_path(NULL, st->ctx, "/when-unlink:top/a", "val_a", 0, 0);
120 assert_ptr_not_equal(st->dt, NULL);
121 node = lyd_new_path(st->dt, st->ctx, "/when-unlink:top/b", "val_b", 0, 0);
122 assert_ptr_not_equal(node, NULL);
123
124 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
125
126 lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
127 assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:when-unlink\"><a>val_a</a><b>val_b</b></top>");
128 }
129
130 static void
test_unlink_augment(void ** state)131 test_unlink_augment(void **state)
132 {
133 struct state *st = (struct state *)*state;
134 struct lyd_node *node;
135
136 /* schema */
137 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlink.yin", LYS_IN_YIN);
138 assert_ptr_not_equal(st->mod, NULL);
139
140 st->dt = lyd_new_path(NULL, st->ctx, "/when-unlink:top/d", "1", 0, 0);
141 assert_ptr_not_equal(st->dt, NULL);
142 node = lyd_new_path(st->dt, st->ctx, "/when-unlink:top/d", "2", 0, 0);
143 assert_ptr_not_equal(node, NULL);
144
145 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
146
147 lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
148 assert_string_equal(st->xml, "<top xmlns=\"urn:libyang:tests:when-unlink\"><d>1</d><d>2</d></top>");
149 }
150
151 static void
test_dummy(void ** state)152 test_dummy(void **state)
153 {
154 struct state *st = (struct state *)*state;
155
156 /* schema */
157 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-dummy.yin", LYS_IN_YIN);
158 assert_ptr_not_equal(st->mod, NULL);
159
160 st->dt = lyd_new_path(NULL, st->ctx, "/when-dummy:c", "value", 0, 0);
161 assert_ptr_not_equal(st->dt, NULL);
162
163 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 1);
164 assert_int_equal(ly_errno, LY_EVALID);
165 assert_int_equal(ly_vecode(st->ctx), LYVE_XPATH_DUMMY);
166 }
167
168 static void
test_dependency_noautodel(void ** state)169 test_dependency_noautodel(void **state)
170 {
171 struct state *st = (struct state *)*state;
172 struct lyd_node *node;
173
174 /* schema */
175 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-depend.yin", LYS_IN_YIN);
176 assert_ptr_not_equal(st->mod, NULL);
177
178 st->dt = lyd_new_path(NULL, st->ctx, "/when-depend:top/a", "val_a", 0, 0);
179 assert_ptr_not_equal(st->dt, NULL);
180 node = lyd_new_path(st->dt, st->ctx, "/when-depend:top/b", "val_b", 0, 0);
181 assert_ptr_not_equal(node, NULL);
182 node = lyd_new_path(st->dt, st->ctx, "/when-depend:top/d", "1", 0, 0);
183 assert_ptr_not_equal(node, NULL);
184 node = lyd_new_path(st->dt, st->ctx, "/when-depend:top/d", "2", 0, 0);
185 assert_ptr_not_equal(node, NULL);
186 node = lyd_new_path(st->dt, st->ctx, "/when-depend:top/e", "val_e", 0, 0);
187 assert_ptr_not_equal(node, NULL);
188
189 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL, NULL), 1);
190 assert_int_equal(ly_errno, LY_EVALID);
191 assert_int_equal(ly_vecode(st->ctx), LYVE_NOWHEN);
192 }
193
194 static void
test_dependency_circular(void ** state)195 test_dependency_circular(void **state)
196 {
197 struct state *st = (struct state *)*state;
198 struct lyd_node *node;
199
200 /* schema */
201 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-circdepend.yin", LYS_IN_YIN);
202 assert_ptr_not_equal(st->mod, NULL);
203
204 st->dt = lyd_new_path(NULL, st->ctx, "/when-circdepend:top/a", "val_a", 0, 0);
205 assert_ptr_not_equal(st->dt, NULL);
206 node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/b", "val_b", 0, 0);
207 assert_ptr_not_equal(node, NULL);
208 node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/d", "1", 0, 0);
209 assert_ptr_not_equal(node, NULL);
210 node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/d", "2", 0, 0);
211 assert_ptr_not_equal(node, NULL);
212 node = lyd_new_path(st->dt, st->ctx, "/when-circdepend:top/e", "val_e", 0, 0);
213 assert_ptr_not_equal(node, NULL);
214
215 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 1);
216 assert_int_equal(ly_errno, LY_EVALID);
217 assert_int_equal(ly_vecode(st->ctx), LYVE_INWHEN);
218 }
219
220 static void
test_unlink_all(void ** state)221 test_unlink_all(void **state)
222 {
223 struct state *st = (struct state *)*state;
224
225 /* schema */
226 st->mod = lys_parse_path(st->ctx, TESTS_DIR"/data/files/when-unlinkall.yin", LYS_IN_YIN);
227 assert_ptr_not_equal(st->mod, NULL);
228
229 st->dt = lyd_new_path(NULL, st->ctx, "/when-unlinkall:a", "val_a", 0, 0);
230 assert_ptr_not_equal(st->dt, NULL);
231
232 assert_int_equal(lyd_validate(&(st->dt), LYD_OPT_CONFIG, NULL), 0);
233
234 lyd_print_mem(&(st->xml), st->dt, LYD_XML, LYP_WITHSIBLINGS);
235 assert_string_equal(st->xml, "<a xmlns=\"urn:libyang:tests:when-unlinkall\">val_a</a>");
236 }
237
main(void)238 int main(void)
239 {
240 const struct CMUnitTest tests[] = {
241 cmocka_unit_test_setup_teardown(test_unlink_uses, setup_f, teardown_f),
242 cmocka_unit_test_setup_teardown(test_unlink_choice, setup_f, teardown_f),
243 cmocka_unit_test_setup_teardown(test_unlink_case, setup_f, teardown_f),
244 cmocka_unit_test_setup_teardown(test_unlink_augment, setup_f, teardown_f),
245 cmocka_unit_test_setup_teardown(test_dummy, setup_f, teardown_f),
246 cmocka_unit_test_setup_teardown(test_dependency_noautodel, setup_f, teardown_f),
247 cmocka_unit_test_setup_teardown(test_dependency_circular, setup_f, teardown_f),
248 cmocka_unit_test_setup_teardown(test_unlink_all, setup_f, teardown_f)
249 };
250
251 return cmocka_run_group_tests(tests, NULL, NULL);
252 }
253