blob: 4b336b72a86869621f6212346c7453967500e7f7 [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átcb3af402020-02-12 16:49:17 +010010#include "completion.hpp"
Václav Kubernát2984f442020-02-20 17:43:35 +010011#include "leaf_data_helpers.hpp"
Václav Kubernát2e4cafe2020-11-05 01:53:21 +010012#include "libyang_utils.hpp"
13#include "pretty_printers.hpp"
Václav Kubernát4108e0d2018-10-29 13:32:22 +010014#include "utils.hpp"
15
16TEST_CASE("utils")
17{
Václav Kubernáta395d332019-02-13 16:49:20 +010018 SECTION("filterByPrefix")
Václav Kubernát4108e0d2018-10-29 13:32:22 +010019 {
Václav Kubernátcb3af402020-02-12 16:49:17 +010020 std::set<Completion> set{{"ahoj"}, {"coze"}, {"copak"}, {"aha"}, {"polivka"}};
Václav Kubernát4108e0d2018-10-29 13:32:22 +010021
Václav Kubernátcb3af402020-02-12 16:49:17 +010022 REQUIRE((filterByPrefix(set, "a") == std::set<Completion>{{"ahoj"}, {"aha"}}));
23 REQUIRE((filterByPrefix(set, "ah") == std::set<Completion>{{"ahoj"}, {"aha"}}));
24 REQUIRE((filterByPrefix(set, "aho") == std::set<Completion>{{"ahoj"}}));
25 REQUIRE((filterByPrefix(set, "polivka") == std::set<Completion>{{"polivka"}}));
26 REQUIRE((filterByPrefix(set, "polivkax") == std::set<Completion>{}));
27 REQUIRE((filterByPrefix(set, "co") == std::set<Completion>{{"copak"}, {"coze"}}));
Václav Kubernát4108e0d2018-10-29 13:32:22 +010028 }
Václav Kubernáta44bdf22020-01-24 12:15:31 +010029
Václav Kubernátb4e5b182020-11-16 19:55:09 +010030 SECTION("joinPaths")
31 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010032 std::string prefix, suffix, result;
33
Václav Kubernátb4e5b182020-11-16 19:55:09 +010034 SECTION("regular")
35 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010036 prefix = "/example:a";
37 suffix = "leaf";
38 result = "/example:a/leaf";
39 }
40
Václav Kubernátb4e5b182020-11-16 19:55:09 +010041 SECTION("no prefix - absolute path")
42 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010043 suffix = "/example:a/leaf";
44 result = "/example:a/leaf";
45 }
46
Václav Kubernátb4e5b182020-11-16 19:55:09 +010047 SECTION("no prefix - relative path")
48 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010049 suffix = "example:a/leaf";
50 result = "example:a/leaf";
51 }
52
Václav Kubernátb4e5b182020-11-16 19:55:09 +010053 SECTION("no suffix")
54 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010055 prefix = "/example:a/leaf";
56 result = "/example:a/leaf";
57 }
58
Václav Kubernátb4e5b182020-11-16 19:55:09 +010059 SECTION("at root")
60 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010061 prefix = "/";
62 suffix = "example:a";
63 result = "/example:a";
64 }
65
Václav Kubernátb4e5b182020-11-16 19:55:09 +010066 SECTION("trailing slash")
67 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010068 prefix = "/example:a";
69 suffix = "/";
70 result = "/example:a/";
71 }
72
Václav Kubernátb4e5b182020-11-16 19:55:09 +010073 SECTION("prefix ends with slash")
74 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010075 prefix = "/example:a/";
76 suffix = "leaf";
77 result = "/example:a/leaf";
78 }
79
Václav Kubernátb4e5b182020-11-16 19:55:09 +010080 SECTION("suffix starts with slash")
81 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010082 prefix = "/example:a";
83 suffix = "/leaf";
84 result = "/example:a/leaf";
85 }
86
Václav Kubernátb4e5b182020-11-16 19:55:09 +010087 SECTION("slashes all the way to eleven")
88 {
Václav Kubernáta44bdf22020-01-24 12:15:31 +010089 prefix = "/example:a/";
90 suffix = "/leaf";
91 result = "/example:a/leaf";
92 }
93
94 REQUIRE(joinPaths(prefix, suffix) == result);
95 }
Václav Kubernát2984f442020-02-20 17:43:35 +010096
97 SECTION("leafDataTypeToString")
98 {
99 yang::LeafDataType type;
100 std::string expected;
101 SECTION("union")
102 {
103 type = yang::Union{{
Václav Kubernát13b23d72020-04-16 21:49:51 +0200104 yang::TypeInfo{yang::String{}},
105 yang::TypeInfo{createEnum({"foo", "bar"})},
106 yang::TypeInfo{yang::Int8{}},
107 yang::TypeInfo{yang::Int64{}},
Václav Kubernát2984f442020-02-20 17:43:35 +0100108 }};
109 expected = "a string, an enum, an 8-bit integer, a 64-bit integer";
110 }
111
112 REQUIRE(leafDataTypeToString(type) == expected);
Václav Kubernát2984f442020-02-20 17:43:35 +0100113 }
Václav Kubernát4108e0d2018-10-29 13:32:22 +0100114}
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100115
116const auto schema = R"(
117module test-schema {
118 namespace "http://example.com/ayyyy";
119 prefix AHOJ;
120
121 leaf int8 {
122 type int8;
123 }
124 leaf int16 {
125 type int16;
126 }
127 leaf int32 {
128 type int32;
129 }
130 leaf int64 {
131 type int64;
132 }
133 leaf uint8 {
134 type uint8;
135 }
136 leaf uint16 {
137 type uint16;
138 }
139 leaf uint32 {
140 type uint32;
141 }
142 leaf uint64 {
143 type uint64;
144 }
145 leaf boolean {
146 type boolean;
147 }
148 leaf string {
149 type string;
150 }
151 leaf enum {
152 type enumeration {
153 enum A;
154 enum B;
155 enum C;
156 }
157 }
158 identity food;
159 identity apple {
160 base "food";
161 }
162 leaf identityRef {
163 type identityref {
164 base "food";
165 }
166 }
167 leaf binary {
168 type binary;
169 }
170 leaf empty {
171 type empty;
172 }
173 leaf bits {
174 type bits {
175 bit a;
176 bit b;
177 bit AHOJ;
178 }
179 }
Václav Kubernátd4800e52020-11-09 10:58:12 +0100180 typedef capabilitiesType {
181 type bits {
182 bit router;
183 bit switch;
184 bit hub;
185 }
186 }
187 leaf capabilities {
188 type capabilitiesType;
189 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100190 leaf dec64 {
191 type decimal64 {
192 fraction-digits 5;
193 }
194 }
195
196 list stuff {
197 key "name";
198 leaf name {
199 type string;
200 }
201 }
202
203 leaf leafRefPresent {
204 type leafref {
205 path ../stuff/name;
206 }
207 }
208
209 leaf leafRefNonPresent {
210 type leafref {
211 path ../stuff/name;
212 }
213 }
Václav Kubernát61d92d72020-11-06 03:14:18 +0100214
215 container users {
216 config false;
217 list userList {
218 leaf name {
219 type string;
220 }
221 }
222 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100223}
224)";
225
226const auto data = R"(
227{
228 "test-schema:int8": 8,
229 "test-schema:int16": 300,
230 "test-schema:int32": -300,
231 "test-schema:int64": -999999999999999,
232 "test-schema:uint8": 8,
233 "test-schema:uint16": 300,
234 "test-schema:uint32": 300,
235 "test-schema:uint64": 999999999999999,
236 "test-schema:boolean": true,
237 "test-schema:string": "AHOJ",
238 "test-schema:enum": "A",
239 "test-schema:identityRef": "apple",
240 "test-schema:binary": "QUhPSgo=",
241 "test-schema:empty": "",
242 "test-schema:bits": "a AHOJ",
Václav Kubernátd4800e52020-11-09 10:58:12 +0100243 "test-schema:capabilities": "switch hub",
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100244 "test-schema:dec64": "43242.43260",
245 "test-schema:stuff": [
246 {
247 "name": "Xaver"
248 }
249 ],
250 "test-schema:leafRefPresent": "Xaver",
Václav Kubernát61d92d72020-11-06 03:14:18 +0100251 "test-schema:leafRefNonPresent": "Lucas",
252 "test-schema:users": {
253 "userList": [
254 {
255 "name": "John"
256 },
257 {
258 "name": "Aneta"
259 },
260 {
261 "name": "Aneta"
262 }
263 ]
264 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100265}
266)";
267
268
269TEST_CASE("libyang_utils")
270{
271 auto ctx = std::make_shared<libyang::Context>();
272 ctx->parse_module_mem(schema, LYS_IN_YANG);
Václav Kubernát61d92d72020-11-06 03:14:18 +0100273 auto dataNode = ctx->parse_data_mem(data, LYD_JSON, LYD_OPT_DATA_NO_YANGLIB | LYD_OPT_NOEXTDEPS | LYD_OPT_STRICT);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100274
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100275 SECTION("leafValueFromNode")
276 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100277 std::string path;
278 leaf_data_ expectedLeafData;
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100279
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100280 SECTION("test-schema:int8")
281 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100282 path = "test-schema:int8";
283 expectedLeafData = int8_t{8};
284 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100285 SECTION("test-schema:int16")
286 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100287 path = "test-schema:int16";
288 expectedLeafData = int16_t{300};
289 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100290 SECTION("test-schema:int32")
291 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100292 path = "test-schema:int32";
293 expectedLeafData = int32_t{-300};
294 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100295 SECTION("test-schema:int64")
296 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100297 path = "test-schema:int64";
298 expectedLeafData = int64_t{-999999999999999};
299 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100300 SECTION("test-schema:uint8")
301 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100302 path = "test-schema:uint8";
303 expectedLeafData = uint8_t{8};
304 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100305 SECTION("test-schema:uint16")
306 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100307 path = "test-schema:uint16";
308 expectedLeafData = uint16_t{300};
309 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100310 SECTION("test-schema:uint32")
311 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100312 path = "test-schema:uint32";
313 expectedLeafData = uint32_t{300};
314 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100315 SECTION("test-schema:uint64")
316 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100317 path = "test-schema:uint64";
318 expectedLeafData = uint64_t{999999999999999};
319 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100320 SECTION("test-schema:boolean")
321 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100322 path = "test-schema:boolean";
323 expectedLeafData = true;
324 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100325 SECTION("test-schema:string")
326 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100327 path = "test-schema:string";
328 expectedLeafData = std::string{"AHOJ"};
329 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100330 SECTION("test-schema:enum")
331 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100332 path = "test-schema:enum";
333 expectedLeafData = enum_{"A"};
334 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100335 SECTION("test-schema:identityRef")
336 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100337 path = "test-schema:identityRef";
338 expectedLeafData = identityRef_{"test-schema", "apple"};
339 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100340 SECTION("test-schema:binary")
341 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100342 path = "test-schema:binary";
343 expectedLeafData = binary_{"QUhPSgo="};
344 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100345 SECTION("test-schema:empty")
346 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100347 path = "test-schema:empty";
348 expectedLeafData = empty_{};
349 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100350 SECTION("test-schema:bits")
351 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100352 path = "test-schema:bits";
353 expectedLeafData = bits_{{"a", "AHOJ"}};
354 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100355 SECTION("test-schema:dec64")
356 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100357 path = "test-schema:dec64";
358 expectedLeafData = 43242.43260;
359 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100360 SECTION("test-schema:leafRefPresent")
361 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100362 path = "test-schema:leafRefPresent";
363 expectedLeafData = std::string{"Xaver"};
364 }
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100365 SECTION("test-schema:leafRefNonPresent")
366 {
Václav Kubernát61d92d72020-11-06 03:14:18 +0100367 path = "test-schema:leafRefNonPresent";
368 expectedLeafData = std::string{"Lucas"};
369 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100370
Václav Kubernát61d92d72020-11-06 03:14:18 +0100371 auto leaf = dataNode->find_path(("/" + path).c_str());
372 REQUIRE(leaf->number() == 1);
373 auto firstLeaf = std::make_shared<libyang::Data_Node_Leaf_List>(leaf->data().front());
374 REQUIRE(leafValueFromNode(firstLeaf) == expectedLeafData);
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100375 }
376
Václav Kubernátb4e5b182020-11-16 19:55:09 +0100377 SECTION("lyNodesToTree")
378 {
379 DatastoreAccess::Tree expected{
Václav Kubernát61d92d72020-11-06 03:14:18 +0100380 {"/test-schema:int8", int8_t{8}},
381 {"/test-schema:int16", int16_t{300}},
382 {"/test-schema:int32", int32_t{-300}},
383 {"/test-schema:int64", int64_t{-999999999999999}},
384 {"/test-schema:uint8", uint8_t{8}},
385 {"/test-schema:uint16", uint16_t{300}},
386 {"/test-schema:uint32", uint32_t{300}},
387 {"/test-schema:uint64", uint64_t{999999999999999}},
388 {"/test-schema:boolean", true},
389 {"/test-schema:string", std::string{"AHOJ"}},
390 {"/test-schema:enum", enum_{"A"}},
391 {"/test-schema:identityRef", identityRef_{"test-schema", "apple"}},
392 {"/test-schema:binary", binary_{"QUhPSgo="}},
393 {"/test-schema:empty", empty_{}},
394 {"/test-schema:bits", bits_{{"a", "AHOJ"}}},
Václav Kubernátd4800e52020-11-09 10:58:12 +0100395 {"/test-schema:capabilities", bits_{{"switch", "hub"}}},
Václav Kubernát61d92d72020-11-06 03:14:18 +0100396 {"/test-schema:dec64", 43242.432600},
397 {"/test-schema:stuff[name='Xaver']", special_{SpecialValue::List}},
398 {"/test-schema:stuff[name='Xaver']/name", std::string{"Xaver"}},
399 {"/test-schema:leafRefPresent", std::string{"Xaver"}},
400 {"/test-schema:leafRefNonPresent", std::string{"Lucas"}},
401 {"/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"}},
407 };
408
409 DatastoreAccess::Tree tree;
410 lyNodesToTree(tree, {dataNode->tree_for()});
411 REQUIRE(tree == expected);
412 }
Václav Kubernát2e4cafe2020-11-05 01:53:21 +0100413}