blob: 7d0af08ef4c2cceee2385c9d6ae195e2b5e88ea1 [file] [log] [blame]
Václav Kubernát4108e0d2018-10-29 13:32:22 +01001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8
Václav Kubernát26b56082020-02-03 18:28:56 +01009#include "trompeloeil_doctest.hpp"
Václav Kubernátcfdb9222021-07-07 22:36:24 +020010#include <libyang-cpp/Context.hpp>
Václav Kubernátcb3af402020-02-12 16:49:17 +010011#include "completion.hpp"
Václav Kubernát2984f442020-02-20 17:43:35 +010012#include "leaf_data_helpers.hpp"
Václav Kubernát2e4cafe2020-11-05 01:53:21 +010013#include "libyang_utils.hpp"
14#include "pretty_printers.hpp"
Václav Kubernát4108e0d2018-10-29 13:32:22 +010015#include "utils.hpp"
16
17TEST_CASE("utils")
18{
Václav Kubernáta395d332019-02-13 16:49:20 +010019 SECTION("filterByPrefix")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010020 {
Václav Kubernátcb3af402020-02-12 16:49:17 +010021 std::set<Completion> set{{"ahoj"}, {"coze"}, {"copak"}, {"aha"}, {"polivka"}};
Václav Kubernát4108e0d2018-10-29 13:32:22 +010022
Václav Kubernátcb3af402020-02-12 16:49:17 +010023 REQUIRE((filterByPrefix(set, "a") == std::set<Completion>{{"ahoj"}, {"aha"}}));
24 REQUIRE((filterByPrefix(set, "ah") == std::set<Completion>{{"ahoj"}, {"aha"}}));
25 REQUIRE((filterByPrefix(set, "aho") == std::set<Completion>{{"ahoj"}}));
26 REQUIRE((filterByPrefix(set, "polivka") == std::set<Completion>{{"polivka"}}));
27 REQUIRE((filterByPrefix(set, "polivkax") == std::set<Completion>{}));
28 REQUIRE((filterByPrefix(set, "co") == std::set<Completion>{{"copak"}, {"coze"}}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +010029 }
Václav Kubernáta44bdf22020-01-24 12:15:31 +010030
Václav Kubernátb4e5b182020-11-16 19:55:09 +010031 SECTION("joinPaths")
32 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010033 std::string prefix, suffix, result;
34
Václav Kubernátb4e5b182020-11-16 19:55:09 +010035 SECTION("regular")
36 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010037 prefix = "/example:a";
38 suffix = "leaf";
39 result = "/example:a/leaf";
40 }
41
Václav Kubernátb4e5b182020-11-16 19:55:09 +010042 SECTION("no prefix - absolute path")
43 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010044 suffix = "/example:a/leaf";
45 result = "/example:a/leaf";
46 }
47
Václav Kubernátb4e5b182020-11-16 19:55:09 +010048 SECTION("no prefix - relative path")
49 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010050 suffix = "example:a/leaf";
51 result = "example:a/leaf";
52 }
53
Václav Kubernátb4e5b182020-11-16 19:55:09 +010054 SECTION("no suffix")
55 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010056 prefix = "/example:a/leaf";
57 result = "/example:a/leaf";
58 }
59
Václav Kubernátb4e5b182020-11-16 19:55:09 +010060 SECTION("at root")
61 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010062 prefix = "/";
63 suffix = "example:a";
64 result = "/example:a";
65 }
66
Václav Kubernátb4e5b182020-11-16 19:55:09 +010067 SECTION("trailing slash")
68 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010069 prefix = "/example:a";
70 suffix = "/";
71 result = "/example:a/";
72 }
73
Václav Kubernátb4e5b182020-11-16 19:55:09 +010074 SECTION("prefix ends with slash")
75 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010076 prefix = "/example:a/";
77 suffix = "leaf";
78 result = "/example:a/leaf";
79 }
80
Václav Kubernátb4e5b182020-11-16 19:55:09 +010081 SECTION("suffix starts with slash")
82 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010083 prefix = "/example:a";
84 suffix = "/leaf";
85 result = "/example:a/leaf";
86 }
87
Václav Kubernátb4e5b182020-11-16 19:55:09 +010088 SECTION("slashes all the way to eleven")
89 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010090 prefix = "/example:a/";
91 suffix = "/leaf";
92 result = "/example:a/leaf";
93 }
94
95 REQUIRE(joinPaths(prefix, suffix) == result);
96 }
Václav Kubernát2984f442020-02-20 17:43:35 +010097
98 SECTION("leafDataTypeToString")
99 {
100 yang::LeafDataType type;
101 std::string expected;
102 SECTION("union")
103 {
104 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200105 yang::TypeInfo{yang::String{}},
106 yang::TypeInfo{createEnum({"foo", "bar"})},
107 yang::TypeInfo{yang::Int8{}},
108 yang::TypeInfo{yang::Int64{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100109 }};
110 expected = "a string, an enum, an 8-bit integer, a 64-bit integer";
111 }
112
113 REQUIRE(leafDataTypeToString(type) == expected);
Václav Kubernát2984f442020-02-20 17:43:35 +0100114 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100115}
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100116
117const auto schema = R"(
118module test-schema {
119 namespace "http://example.com/ayyyy";
120 prefix AHOJ;
121
122 leaf int8 {
123 type int8;
124 }
125 leaf int16 {
126 type int16;
127 }
128 leaf int32 {
129 type int32;
130 }
131 leaf int64 {
132 type int64;
133 }
134 leaf uint8 {
135 type uint8;
136 }
137 leaf uint16 {
138 type uint16;
139 }
140 leaf uint32 {
141 type uint32;
142 }
143 leaf uint64 {
144 type uint64;
145 }
146 leaf boolean {
147 type boolean;
148 }
149 leaf string {
150 type string;
151 }
152 leaf enum {
153 type enumeration {
154 enum A;
155 enum B;
156 enum C;
157 }
158 }
159 identity food;
160 identity apple {
161 base "food";
162 }
163 leaf identityRef {
164 type identityref {
165 base "food";
166 }
167 }
168 leaf binary {
169 type binary;
170 }
171 leaf empty {
172 type empty;
173 }
174 leaf bits {
175 type bits {
176 bit a;
177 bit b;
178 bit AHOJ;
179 }
180 }
Václav Kubernátd4800e52020-11-09 10:58:12 +0100181 typedef capabilitiesType {
182 type bits {
183 bit router;
184 bit switch;
185 bit hub;
186 }
187 }
188 leaf capabilities {
189 type capabilitiesType;
190 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100191 leaf dec64 {
192 type decimal64 {
193 fraction-digits 5;
194 }
195 }
196
197 list stuff {
198 key "name";
199 leaf name {
200 type string;
201 }
202 }
203
204 leaf leafRefPresent {
205 type leafref {
206 path ../stuff/name;
207 }
208 }
209
Václav Kubernát61d92d72020-11-06 03:14:18 +0100210 container users {
211 config false;
212 list userList {
213 leaf name {
214 type string;
215 }
216 }
217 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100218}
219)";
220
221const auto data = R"(
222{
223 "test-schema:int8": 8,
224 "test-schema:int16": 300,
225 "test-schema:int32": -300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100226 "test-schema:int64": "-999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100227 "test-schema:uint8": 8,
228 "test-schema:uint16": 300,
229 "test-schema:uint32": 300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100230 "test-schema:uint64": "999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100231 "test-schema:boolean": true,
232 "test-schema:string": "AHOJ",
233 "test-schema:enum": "A",
234 "test-schema:identityRef": "apple",
235 "test-schema:binary": "QUhPSgo=",
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200236 "test-schema:empty": [null],
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100237 "test-schema:bits": "a AHOJ",
Václav Kubernátd4800e52020-11-09 10:58:12 +0100238 "test-schema:capabilities": "switch hub",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100239 "test-schema:dec64": "43242.43260",
240 "test-schema:stuff": [
241 {
242 "name": "Xaver"
243 }
244 ],
245 "test-schema:leafRefPresent": "Xaver",
Václav Kubernát61d92d72020-11-06 03:14:18 +0100246 "test-schema:users": {
247 "userList": [
248 {
249 "name": "John"
250 },
251 {
252 "name": "Aneta"
253 },
254 {
255 "name": "Aneta"
256 }
257 ]
258 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100259}
260)";
261
262
263TEST_CASE("libyang_utils")
264{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200265 libyang::Context ctx;
266 ctx.parseModuleMem(schema, libyang::SchemaFormat::YANG);
267 auto dataNode = ctx.parseDataMem(data, libyang::DataFormat::JSON, std::nullopt, libyang::ValidationOptions::Present);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100268
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100269 SECTION("leafValueFromNode")
270 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100271 std::string path;
272 leaf_data_ expectedLeafData;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100273
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100274 SECTION("test-schema:int8")
275 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100276 path = "test-schema:int8";
277 expectedLeafData = int8_t{8};
278 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100279 SECTION("test-schema:int16")
280 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100281 path = "test-schema:int16";
282 expectedLeafData = int16_t{300};
283 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100284 SECTION("test-schema:int32")
285 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100286 path = "test-schema:int32";
287 expectedLeafData = int32_t{-300};
288 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100289 SECTION("test-schema:int64")
290 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100291 path = "test-schema:int64";
292 expectedLeafData = int64_t{-999999999999999};
293 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100294 SECTION("test-schema:uint8")
295 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100296 path = "test-schema:uint8";
297 expectedLeafData = uint8_t{8};
298 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100299 SECTION("test-schema:uint16")
300 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100301 path = "test-schema:uint16";
302 expectedLeafData = uint16_t{300};
303 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100304 SECTION("test-schema:uint32")
305 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100306 path = "test-schema:uint32";
307 expectedLeafData = uint32_t{300};
308 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100309 SECTION("test-schema:uint64")
310 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100311 path = "test-schema:uint64";
312 expectedLeafData = uint64_t{999999999999999};
313 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100314 SECTION("test-schema:boolean")
315 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100316 path = "test-schema:boolean";
317 expectedLeafData = true;
318 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100319 SECTION("test-schema:string")
320 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100321 path = "test-schema:string";
322 expectedLeafData = std::string{"AHOJ"};
323 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100324 SECTION("test-schema:enum")
325 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100326 path = "test-schema:enum";
327 expectedLeafData = enum_{"A"};
328 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100329 SECTION("test-schema:identityRef")
330 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100331 path = "test-schema:identityRef";
332 expectedLeafData = identityRef_{"test-schema", "apple"};
333 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100334 SECTION("test-schema:binary")
335 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100336 path = "test-schema:binary";
337 expectedLeafData = binary_{"QUhPSgo="};
338 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100339 SECTION("test-schema:empty")
340 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100341 path = "test-schema:empty";
342 expectedLeafData = empty_{};
343 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100344 SECTION("test-schema:bits")
345 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100346 path = "test-schema:bits";
347 expectedLeafData = bits_{{"a", "AHOJ"}};
348 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100349 SECTION("test-schema:dec64")
350 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100351 path = "test-schema:dec64";
352 expectedLeafData = 43242.43260;
353 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100354 SECTION("test-schema:leafRefPresent")
355 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100356 path = "test-schema:leafRefPresent";
357 expectedLeafData = std::string{"Xaver"};
358 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100359
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100360 auto leaf = dataNode->findPath("/" + path);
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200361 REQUIRE(leafValueFromNode(leaf->asTerm()) == expectedLeafData);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100362 }
363
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100364 SECTION("lyNodesToTree")
365 {
366 DatastoreAccess::Tree expected{
Václav Kubernát61d92d72020-11-06 03:14:18 +0100367 {"/test-schema:int8", int8_t{8}},
368 {"/test-schema:int16", int16_t{300}},
369 {"/test-schema:int32", int32_t{-300}},
370 {"/test-schema:int64", int64_t{-999999999999999}},
371 {"/test-schema:uint8", uint8_t{8}},
372 {"/test-schema:uint16", uint16_t{300}},
373 {"/test-schema:uint32", uint32_t{300}},
374 {"/test-schema:uint64", uint64_t{999999999999999}},
375 {"/test-schema:boolean", true},
376 {"/test-schema:string", std::string{"AHOJ"}},
377 {"/test-schema:enum", enum_{"A"}},
378 {"/test-schema:identityRef", identityRef_{"test-schema", "apple"}},
379 {"/test-schema:binary", binary_{"QUhPSgo="}},
380 {"/test-schema:empty", empty_{}},
381 {"/test-schema:bits", bits_{{"a", "AHOJ"}}},
Václav Kubernátd4800e52020-11-09 10:58:12 +0100382 {"/test-schema:capabilities", bits_{{"switch", "hub"}}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100383 {"/test-schema:dec64", 43242.432600},
384 {"/test-schema:stuff[name='Xaver']", special_{SpecialValue::List}},
385 {"/test-schema:stuff[name='Xaver']/name", std::string{"Xaver"}},
386 {"/test-schema:leafRefPresent", std::string{"Xaver"}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100387 {"/test-schema:users/userList[1]", special_{SpecialValue::List}},
388 {"/test-schema:users/userList[1]/name", std::string{"John"}},
389 {"/test-schema:users/userList[2]", special_{SpecialValue::List}},
390 {"/test-schema:users/userList[2]/name", std::string{"Aneta"}},
391 {"/test-schema:users/userList[3]", special_{SpecialValue::List}},
392 {"/test-schema:users/userList[3]/name", std::string{"Aneta"}},
393 };
394
395 DatastoreAccess::Tree tree;
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200396 lyNodesToTree(tree, dataNode->siblings());
Václav Kubernát61d92d72020-11-06 03:14:18 +0100397 REQUIRE(tree == expected);
398 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100399}