blob: 449d1633affb81fb281bc19d89b65aa8086e5c5f [file] [log] [blame]
Radek Krejci0935f412019-08-20 16:15:18 +02001/*
2 * @file test_nacm.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for NACM extensions support
5 *
6 * Copyright (c) 2019 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 "tests/config.h"
16
17#include <stdarg.h>
18#include <stddef.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include <stdio.h>
23#include <string.h>
24
25#include "../../src/libyang.h"
26
27#define BUFSIZE 1024
28char logbuf[BUFSIZE] = {0};
29int store = -1; /* negative for infinite logging, positive for limited logging */
30
31struct state_s {
32 void *func;
33 struct ly_ctx *ctx;
34};
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 int
58setup(void **state)
59{
60 struct state_s *s;
61
62 s = calloc(1, sizeof *s);
63 assert_non_null(s);
64
65#if ENABLE_LOGGER_CHECKING
66 ly_set_log_clb(logger, 1);
67#endif
68
69 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &s->ctx));
70 assert_non_null(ly_ctx_load_module(s->ctx, "ietf-netconf-acm", "2018-02-14"));
71
72 *state = s;
73
74 return 0;
75}
76
77static int
78teardown(void **state)
79{
80 struct state_s *s = (struct state_s*)(*state);
81
82#if ENABLE_LOGGER_CHECKING
83 if (s->func) {
84 fprintf(stderr, "%s\n", logbuf);
85 }
86#endif
87
88 ly_ctx_destroy(s->ctx, NULL);
89 free(s);
90
91 return 0;
92}
93
94void
95logbuf_clean(void)
96{
97 logbuf[0] = '\0';
98}
99
100#if ENABLE_LOGGER_CHECKING
101# define logbuf_assert(str) assert_string_equal(logbuf, str)
102#else
103# define logbuf_assert(str)
104#endif
105
106static void
107test_deny_all(void **state)
108{
109 struct state_s *s = (struct state_s*)(*state);
110 s->func = test_deny_all;
111
112 struct lys_module *mod;
113 struct lysc_node_container *cont;
114 struct lysc_node_leaf *leaf;
115 struct lysc_ext_instance *e;
116
117 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
118 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
119 "container a { nacm:default-deny-all; leaf aa {type string;}}"
120 "leaf b {type string;}}";
121
122 /* valid data */
123 assert_non_null(mod = lys_parse_mem(s->ctx, data, LYS_IN_YANG));
124 assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
125 assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
126 assert_non_null(e = &cont->exts[0]);
127 assert_int_equal(LY_ARRAY_SIZE(cont->exts), 1);
128 assert_int_equal(LY_ARRAY_SIZE(leaf->exts), 1); /* NACM extensions inherit */
129 assert_ptr_equal(e->def, leaf->exts[0].def);
130 assert_int_equal(1, *((uint8_t*)e->data)); /* plugin's value for default-deny-all */
131 assert_null(cont->next->exts);
132
133 /* invalid */
134 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
135 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
136 "nacm:default-deny-all;}";
137 assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
138 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200139 "Extension nacm:default-deny-all is allowed only in a data nodes, but it is placed in \"module\" statement.) /aa:{extension='nacm:default-deny-all'}");
Radek Krejci0935f412019-08-20 16:15:18 +0200140
141 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
142 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
143 "leaf l { type string; nacm:default-deny-all; nacm:default-deny-write;}}";
144 assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
145 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200146 "Extension nacm:default-deny-write is mixed with nacm:default-deny-all.) /aa:l/{extension='nacm:default-deny-write'}");
Radek Krejci0935f412019-08-20 16:15:18 +0200147
148 s->func = NULL;
149}
150
151static void
152test_deny_write(void **state)
153{
154 struct state_s *s = (struct state_s*)(*state);
155 s->func = test_deny_write;
156
157 struct lys_module *mod;
158 struct lysc_node_container *cont;
159 struct lysc_node_leaf *leaf;
160 struct lysc_ext_instance *e;
161
162 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
163 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
164 "container a { nacm:default-deny-write; leaf aa {type string;}}"
165 "leaf b {type string;}}";
166
167 /* valid data */
168 assert_non_null(mod = lys_parse_mem(s->ctx, data, LYS_IN_YANG));
169 assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
170 assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
171 assert_non_null(e = &cont->exts[0]);
172 assert_int_equal(LY_ARRAY_SIZE(cont->exts), 1);
173 assert_int_equal(LY_ARRAY_SIZE(leaf->exts), 1); /* NACM extensions inherit */
174 assert_ptr_equal(e->def, leaf->exts[0].def);
175 assert_int_equal(2, *((uint8_t*)e->data)); /* plugin's value for default-deny-write */
176 assert_null(cont->next->exts);
177
178 /* invalid */
179 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
180 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
181 "notification notif {nacm:default-deny-write;}}";
182 assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
183 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Michal Vaskoa3881362020-01-21 15:57:35 +0100184 "Extension nacm:default-deny-write is not allowed in notification statement.) /aa:notif/{extension='nacm:default-deny-write'}");
Radek Krejci0935f412019-08-20 16:15:18 +0200185
186 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
187 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
188 "leaf l { type string; nacm:default-deny-write; nacm:default-deny-write;}}";
189 assert_null(lys_parse_mem(s->ctx, data, LYS_IN_YANG));
190 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200191 "Extension nacm:default-deny-write is instantiated multiple times.) /aa:l/{extension='nacm:default-deny-write'}");
Radek Krejci0935f412019-08-20 16:15:18 +0200192
193 s->func = NULL;
194}
195
196int main(void)
197{
198 const struct CMUnitTest tests[] = {
199 cmocka_unit_test_setup_teardown(test_deny_all, setup, teardown),
200 cmocka_unit_test_setup_teardown(test_deny_write, setup, teardown),
201 };
202
203 return cmocka_run_group_tests(tests, NULL, NULL);
204}