blob: 04b4407276ba7fcb7055b426752bae07980b7016 [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
Radek Krejci0935f412019-08-20 16:15:18 +020015#include <stdarg.h>
16#include <stddef.h>
17#include <setjmp.h>
18#include <cmocka.h>
19
20#include <stdio.h>
21#include <string.h>
22
Radek Krejci70593c12020-06-13 20:48:09 +020023#include "libyang.h"
24#include "tests/config.h"
Radek Krejci0935f412019-08-20 16:15:18 +020025
26#define BUFSIZE 1024
27char logbuf[BUFSIZE] = {0};
28int store = -1; /* negative for infinite logging, positive for limited logging */
29
30struct state_s {
31 void *func;
32 struct ly_ctx *ctx;
33};
34
35/* set to 0 to printing error messages to stderr instead of checking them in code */
36#define ENABLE_LOGGER_CHECKING 1
37
38#if ENABLE_LOGGER_CHECKING
39static void
40logger(LY_LOG_LEVEL level, const char *msg, const char *path)
41{
42 (void) level; /* unused */
43 if (store) {
44 if (path && path[0]) {
45 snprintf(logbuf, BUFSIZE - 1, "%s %s", msg, path);
46 } else {
47 strncpy(logbuf, msg, BUFSIZE - 1);
48 }
49 if (store > 0) {
50 --store;
51 }
52 }
53}
54#endif
55
56static int
57setup(void **state)
58{
59 struct state_s *s;
60
61 s = calloc(1, sizeof *s);
62 assert_non_null(s);
63
64#if ENABLE_LOGGER_CHECKING
65 ly_set_log_clb(logger, 1);
66#endif
67
68 assert_int_equal(LY_SUCCESS, ly_ctx_new(TESTS_DIR_MODULES_YANG, 0, &s->ctx));
Michal Vasko7b1ad1a2020-11-02 15:41:27 +010069 assert_non_null(ly_ctx_load_module(s->ctx, "ietf-netconf-acm", "2018-02-14", NULL));
Radek Krejci0935f412019-08-20 16:15:18 +020070
71 *state = s;
72
73 return 0;
74}
75
76static int
77teardown(void **state)
78{
79 struct state_s *s = (struct state_s*)(*state);
80
81#if ENABLE_LOGGER_CHECKING
82 if (s->func) {
83 fprintf(stderr, "%s\n", logbuf);
84 }
85#endif
86
87 ly_ctx_destroy(s->ctx, NULL);
88 free(s);
89
90 return 0;
91}
92
93void
94logbuf_clean(void)
95{
96 logbuf[0] = '\0';
97}
98
99#if ENABLE_LOGGER_CHECKING
100# define logbuf_assert(str) assert_string_equal(logbuf, str)
101#else
102# define logbuf_assert(str)
103#endif
104
105static void
106test_deny_all(void **state)
107{
108 struct state_s *s = (struct state_s*)(*state);
109 s->func = test_deny_all;
110
Michal Vasko3a41dff2020-07-15 14:30:28 +0200111 const struct lys_module *mod;
Radek Krejci0935f412019-08-20 16:15:18 +0200112 struct lysc_node_container *cont;
113 struct lysc_node_leaf *leaf;
114 struct lysc_ext_instance *e;
115
116 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
117 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
118 "container a { nacm:default-deny-all; leaf aa {type string;}}"
119 "leaf b {type string;}}";
120
121 /* valid data */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200122 assert_int_equal(LY_SUCCESS, lys_parse_mem(s->ctx, data, LYS_IN_YANG, &mod));
Radek Krejci0935f412019-08-20 16:15:18 +0200123 assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
124 assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
125 assert_non_null(e = &cont->exts[0]);
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200126 assert_int_equal(LY_ARRAY_COUNT(cont->exts), 1);
127 assert_int_equal(LY_ARRAY_COUNT(leaf->exts), 1); /* NACM extensions inherit */
Radek Krejci0935f412019-08-20 16:15:18 +0200128 assert_ptr_equal(e->def, leaf->exts[0].def);
129 assert_int_equal(1, *((uint8_t*)e->data)); /* plugin's value for default-deny-all */
130 assert_null(cont->next->exts);
131
132 /* invalid */
133 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
134 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
135 "nacm:default-deny-all;}";
Michal Vasko3a41dff2020-07-15 14:30:28 +0200136 assert_int_equal(LY_EVALID, lys_parse_mem(s->ctx, data, LYS_IN_YANG, NULL));
Radek Krejci0935f412019-08-20 16:15:18 +0200137 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200138 "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 +0200139
140 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
141 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
142 "leaf l { type string; nacm:default-deny-all; nacm:default-deny-write;}}";
Michal Vasko3a41dff2020-07-15 14:30:28 +0200143 assert_int_equal(LY_EVALID, lys_parse_mem(s->ctx, data, LYS_IN_YANG, NULL));
Radek Krejci0935f412019-08-20 16:15:18 +0200144 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200145 "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 +0200146
147 s->func = NULL;
148}
149
150static void
151test_deny_write(void **state)
152{
153 struct state_s *s = (struct state_s*)(*state);
154 s->func = test_deny_write;
155
Michal Vasko3a41dff2020-07-15 14:30:28 +0200156 const struct lys_module *mod;
Radek Krejci0935f412019-08-20 16:15:18 +0200157 struct lysc_node_container *cont;
158 struct lysc_node_leaf *leaf;
159 struct lysc_ext_instance *e;
160
161 const char *data = "module a {yang-version 1.1; namespace urn:tests:extensions:nacm:a; prefix en;"
162 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
163 "container a { nacm:default-deny-write; leaf aa {type string;}}"
164 "leaf b {type string;}}";
165
166 /* valid data */
Michal Vasko3a41dff2020-07-15 14:30:28 +0200167 assert_int_equal(LY_SUCCESS, lys_parse_mem(s->ctx, data, LYS_IN_YANG, &mod));
Radek Krejci0935f412019-08-20 16:15:18 +0200168 assert_non_null(cont = (struct lysc_node_container*)mod->compiled->data);
169 assert_non_null(leaf = (struct lysc_node_leaf*)cont->child);
170 assert_non_null(e = &cont->exts[0]);
Michal Vaskofd69e1d2020-07-03 11:57:17 +0200171 assert_int_equal(LY_ARRAY_COUNT(cont->exts), 1);
172 assert_int_equal(LY_ARRAY_COUNT(leaf->exts), 1); /* NACM extensions inherit */
Radek Krejci0935f412019-08-20 16:15:18 +0200173 assert_ptr_equal(e->def, leaf->exts[0].def);
174 assert_int_equal(2, *((uint8_t*)e->data)); /* plugin's value for default-deny-write */
175 assert_null(cont->next->exts);
176
177 /* invalid */
178 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
179 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
180 "notification notif {nacm:default-deny-write;}}";
Michal Vasko3a41dff2020-07-15 14:30:28 +0200181 assert_int_equal(LY_EVALID, lys_parse_mem(s->ctx, data, LYS_IN_YANG, NULL));
Radek Krejci0935f412019-08-20 16:15:18 +0200182 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Michal Vaskoa3881362020-01-21 15:57:35 +0100183 "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 +0200184
185 data = "module aa {yang-version 1.1; namespace urn:tests:extensions:nacm:aa; prefix en;"
186 "import ietf-netconf-acm {revision-date 2018-02-14; prefix nacm;}"
187 "leaf l { type string; nacm:default-deny-write; nacm:default-deny-write;}}";
Michal Vasko3a41dff2020-07-15 14:30:28 +0200188 assert_int_equal(LY_EVALID, lys_parse_mem(s->ctx, data, LYS_IN_YANG, NULL));
Radek Krejci0935f412019-08-20 16:15:18 +0200189 logbuf_assert("Extension plugin \"libyang 2 - NACM, version 1\": "
Radek Krejciad5963b2019-09-06 16:03:05 +0200190 "Extension nacm:default-deny-write is instantiated multiple times.) /aa:l/{extension='nacm:default-deny-write'}");
Radek Krejci0935f412019-08-20 16:15:18 +0200191
192 s->func = NULL;
193}
194
195int main(void)
196{
197 const struct CMUnitTest tests[] = {
198 cmocka_unit_test_setup_teardown(test_deny_all, setup, teardown),
199 cmocka_unit_test_setup_teardown(test_deny_write, setup, teardown),
200 };
201
202 return cmocka_run_group_tests(tests, NULL, NULL);
203}