blob: fa4ebed0c11d0d75fe94b6daf2a71b3893c217dd [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
Jan Kundrát95c55822023-05-18 17:12:20 +020017using namespace std::literals;
18
Václav Kubernát4108e0d2018-10-29 13:32:22 +010019TEST_CASE("utils")
20{
Václav Kubernáta395d332019-02-13 16:49:20 +010021 SECTION("filterByPrefix")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010022 {
Václav Kubernátcb3af402020-02-12 16:49:17 +010023 std::set<Completion> set{{"ahoj"}, {"coze"}, {"copak"}, {"aha"}, {"polivka"}};
Václav Kubernát4108e0d2018-10-29 13:32:22 +010024
Václav Kubernátcb3af402020-02-12 16:49:17 +010025 REQUIRE((filterByPrefix(set, "a") == std::set<Completion>{{"ahoj"}, {"aha"}}));
26 REQUIRE((filterByPrefix(set, "ah") == std::set<Completion>{{"ahoj"}, {"aha"}}));
27 REQUIRE((filterByPrefix(set, "aho") == std::set<Completion>{{"ahoj"}}));
28 REQUIRE((filterByPrefix(set, "polivka") == std::set<Completion>{{"polivka"}}));
29 REQUIRE((filterByPrefix(set, "polivkax") == std::set<Completion>{}));
30 REQUIRE((filterByPrefix(set, "co") == std::set<Completion>{{"copak"}, {"coze"}}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +010031 }
Václav Kubernáta44bdf22020-01-24 12:15:31 +010032
Václav Kubernátb4e5b182020-11-16 19:55:09 +010033 SECTION("joinPaths")
34 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010035 std::string prefix, suffix, result;
36
Václav Kubernátb4e5b182020-11-16 19:55:09 +010037 SECTION("regular")
38 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010039 prefix = "/example:a";
40 suffix = "leaf";
41 result = "/example:a/leaf";
42 }
43
Václav Kubernátb4e5b182020-11-16 19:55:09 +010044 SECTION("no prefix - absolute path")
45 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010046 suffix = "/example:a/leaf";
47 result = "/example:a/leaf";
48 }
49
Václav Kubernátb4e5b182020-11-16 19:55:09 +010050 SECTION("no prefix - relative path")
51 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010052 suffix = "example:a/leaf";
53 result = "example:a/leaf";
54 }
55
Václav Kubernátb4e5b182020-11-16 19:55:09 +010056 SECTION("no suffix")
57 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010058 prefix = "/example:a/leaf";
59 result = "/example:a/leaf";
60 }
61
Václav Kubernátb4e5b182020-11-16 19:55:09 +010062 SECTION("at root")
63 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010064 prefix = "/";
65 suffix = "example:a";
66 result = "/example:a";
67 }
68
Václav Kubernátb4e5b182020-11-16 19:55:09 +010069 SECTION("trailing slash")
70 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010071 prefix = "/example:a";
72 suffix = "/";
73 result = "/example:a/";
74 }
75
Václav Kubernátb4e5b182020-11-16 19:55:09 +010076 SECTION("prefix ends with slash")
77 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010078 prefix = "/example:a/";
79 suffix = "leaf";
80 result = "/example:a/leaf";
81 }
82
Václav Kubernátb4e5b182020-11-16 19:55:09 +010083 SECTION("suffix starts with slash")
84 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010085 prefix = "/example:a";
86 suffix = "/leaf";
87 result = "/example:a/leaf";
88 }
89
Václav Kubernátb4e5b182020-11-16 19:55:09 +010090 SECTION("slashes all the way to eleven")
91 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010092 prefix = "/example:a/";
93 suffix = "/leaf";
94 result = "/example:a/leaf";
95 }
96
97 REQUIRE(joinPaths(prefix, suffix) == result);
98 }
Václav Kubernát2984f442020-02-20 17:43:35 +010099
100 SECTION("leafDataTypeToString")
101 {
102 yang::LeafDataType type;
103 std::string expected;
104 SECTION("union")
105 {
106 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200107 yang::TypeInfo{yang::String{}},
108 yang::TypeInfo{createEnum({"foo", "bar"})},
109 yang::TypeInfo{yang::Int8{}},
110 yang::TypeInfo{yang::Int64{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100111 }};
112 expected = "a string, an enum, an 8-bit integer, a 64-bit integer";
113 }
114
115 REQUIRE(leafDataTypeToString(type) == expected);
Václav Kubernát2984f442020-02-20 17:43:35 +0100116 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100117}
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100118
119const auto schema = R"(
120module test-schema {
121 namespace "http://example.com/ayyyy";
122 prefix AHOJ;
123
124 leaf int8 {
125 type int8;
126 }
127 leaf int16 {
128 type int16;
129 }
130 leaf int32 {
131 type int32;
132 }
133 leaf int64 {
134 type int64;
135 }
136 leaf uint8 {
137 type uint8;
138 }
139 leaf uint16 {
140 type uint16;
141 }
142 leaf uint32 {
143 type uint32;
144 }
145 leaf uint64 {
146 type uint64;
147 }
148 leaf boolean {
149 type boolean;
150 }
151 leaf string {
152 type string;
153 }
154 leaf enum {
155 type enumeration {
156 enum A;
157 enum B;
158 enum C;
159 }
160 }
161 identity food;
162 identity apple {
163 base "food";
164 }
165 leaf identityRef {
166 type identityref {
167 base "food";
168 }
169 }
170 leaf binary {
171 type binary;
172 }
173 leaf empty {
174 type empty;
175 }
176 leaf bits {
177 type bits {
178 bit a;
179 bit b;
180 bit AHOJ;
181 }
182 }
Václav Kubernátd4800e52020-11-09 10:58:12 +0100183 typedef capabilitiesType {
184 type bits {
185 bit router;
186 bit switch;
187 bit hub;
188 }
189 }
190 leaf capabilities {
191 type capabilitiesType;
192 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100193 leaf dec64 {
194 type decimal64 {
195 fraction-digits 5;
196 }
197 }
198
199 list stuff {
200 key "name";
201 leaf name {
202 type string;
203 }
204 }
205
206 leaf leafRefPresent {
207 type leafref {
208 path ../stuff/name;
209 }
210 }
211
Václav Kubernát61d92d72020-11-06 03:14:18 +0100212 container users {
213 config false;
214 list userList {
215 leaf name {
216 type string;
217 }
218 }
219 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100220}
Jan Kundrát95c55822023-05-18 17:12:20 +0200221)"s;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100222
223const auto data = R"(
224{
225 "test-schema:int8": 8,
226 "test-schema:int16": 300,
227 "test-schema:int32": -300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100228 "test-schema:int64": "-999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100229 "test-schema:uint8": 8,
230 "test-schema:uint16": 300,
231 "test-schema:uint32": 300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100232 "test-schema:uint64": "999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100233 "test-schema:boolean": true,
234 "test-schema:string": "AHOJ",
235 "test-schema:enum": "A",
236 "test-schema:identityRef": "apple",
237 "test-schema:binary": "QUhPSgo=",
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200238 "test-schema:empty": [null],
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100239 "test-schema:bits": "a AHOJ",
Václav Kubernátd4800e52020-11-09 10:58:12 +0100240 "test-schema:capabilities": "switch hub",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100241 "test-schema:dec64": "43242.43260",
242 "test-schema:stuff": [
243 {
244 "name": "Xaver"
245 }
246 ],
247 "test-schema:leafRefPresent": "Xaver",
Václav Kubernát61d92d72020-11-06 03:14:18 +0100248 "test-schema:users": {
249 "userList": [
250 {
251 "name": "John"
252 },
253 {
254 "name": "Aneta"
255 },
256 {
257 "name": "Aneta"
258 }
259 ]
260 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100261}
Jan Kundrát95c55822023-05-18 17:12:20 +0200262)"s;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100263
264
265TEST_CASE("libyang_utils")
266{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200267 libyang::Context ctx;
Jan Kundrát95c55822023-05-18 17:12:20 +0200268 ctx.parseModule(schema, libyang::SchemaFormat::YANG);
269 auto dataNode = ctx.parseData(data, libyang::DataFormat::JSON, std::nullopt, libyang::ValidationOptions::Present);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100270
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100271 SECTION("leafValueFromNode")
272 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100273 std::string path;
274 leaf_data_ expectedLeafData;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100275
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100276 SECTION("test-schema:int8")
277 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100278 path = "test-schema:int8";
279 expectedLeafData = int8_t{8};
280 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100281 SECTION("test-schema:int16")
282 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100283 path = "test-schema:int16";
284 expectedLeafData = int16_t{300};
285 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100286 SECTION("test-schema:int32")
287 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100288 path = "test-schema:int32";
289 expectedLeafData = int32_t{-300};
290 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100291 SECTION("test-schema:int64")
292 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100293 path = "test-schema:int64";
294 expectedLeafData = int64_t{-999999999999999};
295 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100296 SECTION("test-schema:uint8")
297 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100298 path = "test-schema:uint8";
299 expectedLeafData = uint8_t{8};
300 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100301 SECTION("test-schema:uint16")
302 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100303 path = "test-schema:uint16";
304 expectedLeafData = uint16_t{300};
305 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100306 SECTION("test-schema:uint32")
307 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100308 path = "test-schema:uint32";
309 expectedLeafData = uint32_t{300};
310 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100311 SECTION("test-schema:uint64")
312 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100313 path = "test-schema:uint64";
314 expectedLeafData = uint64_t{999999999999999};
315 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100316 SECTION("test-schema:boolean")
317 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100318 path = "test-schema:boolean";
319 expectedLeafData = true;
320 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100321 SECTION("test-schema:string")
322 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100323 path = "test-schema:string";
324 expectedLeafData = std::string{"AHOJ"};
325 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100326 SECTION("test-schema:enum")
327 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100328 path = "test-schema:enum";
329 expectedLeafData = enum_{"A"};
330 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100331 SECTION("test-schema:identityRef")
332 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100333 path = "test-schema:identityRef";
334 expectedLeafData = identityRef_{"test-schema", "apple"};
335 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100336 SECTION("test-schema:binary")
337 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100338 path = "test-schema:binary";
339 expectedLeafData = binary_{"QUhPSgo="};
340 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100341 SECTION("test-schema:empty")
342 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100343 path = "test-schema:empty";
344 expectedLeafData = empty_{};
345 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100346 SECTION("test-schema:bits")
347 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100348 path = "test-schema:bits";
349 expectedLeafData = bits_{{"a", "AHOJ"}};
350 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100351 SECTION("test-schema:dec64")
352 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100353 path = "test-schema:dec64";
354 expectedLeafData = 43242.43260;
355 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100356 SECTION("test-schema:leafRefPresent")
357 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100358 path = "test-schema:leafRefPresent";
359 expectedLeafData = std::string{"Xaver"};
360 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100361
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100362 auto leaf = dataNode->findPath("/" + path);
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200363 REQUIRE(leafValueFromNode(leaf->asTerm()) == expectedLeafData);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100364 }
365
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100366 SECTION("lyNodesToTree")
367 {
368 DatastoreAccess::Tree expected{
Václav Kubernát61d92d72020-11-06 03:14:18 +0100369 {"/test-schema:int8", int8_t{8}},
370 {"/test-schema:int16", int16_t{300}},
371 {"/test-schema:int32", int32_t{-300}},
372 {"/test-schema:int64", int64_t{-999999999999999}},
373 {"/test-schema:uint8", uint8_t{8}},
374 {"/test-schema:uint16", uint16_t{300}},
375 {"/test-schema:uint32", uint32_t{300}},
376 {"/test-schema:uint64", uint64_t{999999999999999}},
377 {"/test-schema:boolean", true},
378 {"/test-schema:string", std::string{"AHOJ"}},
379 {"/test-schema:enum", enum_{"A"}},
380 {"/test-schema:identityRef", identityRef_{"test-schema", "apple"}},
381 {"/test-schema:binary", binary_{"QUhPSgo="}},
382 {"/test-schema:empty", empty_{}},
383 {"/test-schema:bits", bits_{{"a", "AHOJ"}}},
Václav Kubernátd4800e52020-11-09 10:58:12 +0100384 {"/test-schema:capabilities", bits_{{"switch", "hub"}}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100385 {"/test-schema:dec64", 43242.432600},
386 {"/test-schema:stuff[name='Xaver']", special_{SpecialValue::List}},
387 {"/test-schema:stuff[name='Xaver']/name", std::string{"Xaver"}},
388 {"/test-schema:leafRefPresent", std::string{"Xaver"}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100389 {"/test-schema:users/userList[1]", special_{SpecialValue::List}},
390 {"/test-schema:users/userList[1]/name", std::string{"John"}},
391 {"/test-schema:users/userList[2]", special_{SpecialValue::List}},
392 {"/test-schema:users/userList[2]/name", std::string{"Aneta"}},
393 {"/test-schema:users/userList[3]", special_{SpecialValue::List}},
394 {"/test-schema:users/userList[3]/name", std::string{"Aneta"}},
395 };
396
397 DatastoreAccess::Tree tree;
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200398 lyNodesToTree(tree, dataNode->siblings());
Václav Kubernát61d92d72020-11-06 03:14:18 +0100399 REQUIRE(tree == expected);
400 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100401}