blob: 05dfeb2c6019385c6312d0d9ec8567242195b9d7 [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 }
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200220
221 leaf iid-valid {
222 type instance-identifier;
223 }
224
225 leaf iid-relaxed {
226 type instance-identifier {
227 require-instance false;
228 }
229 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100230}
Jan Kundrát95c55822023-05-18 17:12:20 +0200231)"s;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100232
233const auto data = R"(
234{
235 "test-schema:int8": 8,
236 "test-schema:int16": 300,
237 "test-schema:int32": -300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100238 "test-schema:int64": "-999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100239 "test-schema:uint8": 8,
240 "test-schema:uint16": 300,
241 "test-schema:uint32": 300,
Jan Kundrát6c34e9f2021-01-27 12:58:51 +0100242 "test-schema:uint64": "999999999999999",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100243 "test-schema:boolean": true,
244 "test-schema:string": "AHOJ",
245 "test-schema:enum": "A",
246 "test-schema:identityRef": "apple",
247 "test-schema:binary": "QUhPSgo=",
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200248 "test-schema:empty": [null],
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100249 "test-schema:bits": "a AHOJ",
Václav Kubernátd4800e52020-11-09 10:58:12 +0100250 "test-schema:capabilities": "switch hub",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100251 "test-schema:dec64": "43242.43260",
252 "test-schema:stuff": [
253 {
254 "name": "Xaver"
255 }
256 ],
257 "test-schema:leafRefPresent": "Xaver",
Václav Kubernát61d92d72020-11-06 03:14:18 +0100258 "test-schema:users": {
259 "userList": [
260 {
261 "name": "John"
262 },
263 {
264 "name": "Aneta"
265 },
266 {
267 "name": "Aneta"
268 }
269 ]
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200270 },
271 "test-schema:iid-valid": "/test-schema:stuff[name='Xaver']/name",
272 "test-schema:iid-relaxed": "/test-schema:stuff[name='XXX']/name"
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100273}
Jan Kundrát95c55822023-05-18 17:12:20 +0200274)"s;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100275
276
277TEST_CASE("libyang_utils")
278{
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200279 libyang::Context ctx;
Jan Kundrát95c55822023-05-18 17:12:20 +0200280 ctx.parseModule(schema, libyang::SchemaFormat::YANG);
281 auto dataNode = ctx.parseData(data, libyang::DataFormat::JSON, std::nullopt, libyang::ValidationOptions::Present);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100282
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100283 SECTION("leafValueFromNode")
284 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100285 std::string path;
286 leaf_data_ expectedLeafData;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100287
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100288 SECTION("test-schema:int8")
289 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100290 path = "test-schema:int8";
291 expectedLeafData = int8_t{8};
292 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100293 SECTION("test-schema:int16")
294 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100295 path = "test-schema:int16";
296 expectedLeafData = int16_t{300};
297 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100298 SECTION("test-schema:int32")
299 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100300 path = "test-schema:int32";
301 expectedLeafData = int32_t{-300};
302 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100303 SECTION("test-schema:int64")
304 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100305 path = "test-schema:int64";
306 expectedLeafData = int64_t{-999999999999999};
307 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100308 SECTION("test-schema:uint8")
309 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100310 path = "test-schema:uint8";
311 expectedLeafData = uint8_t{8};
312 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100313 SECTION("test-schema:uint16")
314 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100315 path = "test-schema:uint16";
316 expectedLeafData = uint16_t{300};
317 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100318 SECTION("test-schema:uint32")
319 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100320 path = "test-schema:uint32";
321 expectedLeafData = uint32_t{300};
322 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100323 SECTION("test-schema:uint64")
324 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100325 path = "test-schema:uint64";
326 expectedLeafData = uint64_t{999999999999999};
327 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100328 SECTION("test-schema:boolean")
329 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100330 path = "test-schema:boolean";
331 expectedLeafData = true;
332 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100333 SECTION("test-schema:string")
334 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100335 path = "test-schema:string";
336 expectedLeafData = std::string{"AHOJ"};
337 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100338 SECTION("test-schema:enum")
339 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100340 path = "test-schema:enum";
341 expectedLeafData = enum_{"A"};
342 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100343 SECTION("test-schema:identityRef")
344 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100345 path = "test-schema:identityRef";
346 expectedLeafData = identityRef_{"test-schema", "apple"};
347 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100348 SECTION("test-schema:binary")
349 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100350 path = "test-schema:binary";
351 expectedLeafData = binary_{"QUhPSgo="};
352 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100353 SECTION("test-schema:empty")
354 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100355 path = "test-schema:empty";
356 expectedLeafData = empty_{};
357 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100358 SECTION("test-schema:bits")
359 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100360 path = "test-schema:bits";
361 expectedLeafData = bits_{{"a", "AHOJ"}};
362 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100363 SECTION("test-schema:dec64")
364 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100365 path = "test-schema:dec64";
366 expectedLeafData = 43242.43260;
367 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100368 SECTION("test-schema:leafRefPresent")
369 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100370 path = "test-schema:leafRefPresent";
371 expectedLeafData = std::string{"Xaver"};
372 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100373
Jan Kundrátf59b83c2022-03-18 18:12:08 +0100374 auto leaf = dataNode->findPath("/" + path);
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200375 REQUIRE(leafValueFromNode(leaf->asTerm()) == expectedLeafData);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100376 }
377
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100378 SECTION("lyNodesToTree")
379 {
380 DatastoreAccess::Tree expected{
Václav Kubernát61d92d72020-11-06 03:14:18 +0100381 {"/test-schema:int8", int8_t{8}},
382 {"/test-schema:int16", int16_t{300}},
383 {"/test-schema:int32", int32_t{-300}},
384 {"/test-schema:int64", int64_t{-999999999999999}},
385 {"/test-schema:uint8", uint8_t{8}},
386 {"/test-schema:uint16", uint16_t{300}},
387 {"/test-schema:uint32", uint32_t{300}},
388 {"/test-schema:uint64", uint64_t{999999999999999}},
389 {"/test-schema:boolean", true},
390 {"/test-schema:string", std::string{"AHOJ"}},
391 {"/test-schema:enum", enum_{"A"}},
392 {"/test-schema:identityRef", identityRef_{"test-schema", "apple"}},
393 {"/test-schema:binary", binary_{"QUhPSgo="}},
394 {"/test-schema:empty", empty_{}},
395 {"/test-schema:bits", bits_{{"a", "AHOJ"}}},
Václav Kubernátd4800e52020-11-09 10:58:12 +0100396 {"/test-schema:capabilities", bits_{{"switch", "hub"}}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100397 {"/test-schema:dec64", 43242.432600},
398 {"/test-schema:stuff[name='Xaver']", special_{SpecialValue::List}},
399 {"/test-schema:stuff[name='Xaver']/name", std::string{"Xaver"}},
400 {"/test-schema:leafRefPresent", std::string{"Xaver"}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100401 {"/test-schema:users/userList[1]", special_{SpecialValue::List}},
402 {"/test-schema:users/userList[1]/name", std::string{"John"}},
403 {"/test-schema:users/userList[2]", special_{SpecialValue::List}},
404 {"/test-schema:users/userList[2]/name", std::string{"Aneta"}},
405 {"/test-schema:users/userList[3]", special_{SpecialValue::List}},
406 {"/test-schema:users/userList[3]/name", std::string{"Aneta"}},
Jan Kundrátbb7aa852023-08-30 11:51:43 +0200407 {"/test-schema:iid-valid", instanceIdentifier_{"/test-schema:stuff[name='Xaver']/name"}},
408 {"/test-schema:iid-relaxed", instanceIdentifier_{"/test-schema:stuff[name='XXX']/name"}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100409 };
410
411 DatastoreAccess::Tree tree;
Václav Kubernátcfdb9222021-07-07 22:36:24 +0200412 lyNodesToTree(tree, dataNode->siblings());
Václav Kubernát61d92d72020-11-06 03:14:18 +0100413 REQUIRE(tree == expected);
414 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100415}