blob: bcf06aaba4bb6593293b08d4026c93200b69c3aa [file] [log] [blame]
Václav Kubernát07204242018-06-04 18:12:09 +02001/*
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
Jan Kundráta33cf082019-03-28 11:55:57 +01009#include "trompeloeil_doctest.h"
Jan Kundrát76b3ddc2019-07-03 10:31:27 +020010#include <boost/core/demangle.hpp>
Václav Kubernát24df80e2018-06-06 15:18:03 +020011#include "ast_commands.hpp"
Václav Kubernát07204242018-06-04 18:12:09 +020012#include "parser.hpp"
Václav Kubernátbddbb172018-06-13 16:27:39 +020013#include "static_schema.hpp"
Václav Kubernát509ce652019-05-29 19:46:44 +020014#include "utils.hpp"
Václav Kubernát07204242018-06-04 18:12:09 +020015
Jan Kundrát76b3ddc2019-07-03 10:31:27 +020016std::ostream& operator<<(std::ostream& s, const set_ cmd)
17{
18 return s << "Command SET {path: " << pathToAbsoluteSchemaString(cmd.m_path) << ", type " << boost::core::demangle(cmd.m_data.type().name()) << ", data: " << leafDataToString(cmd.m_data) << "}";
19}
20
Václav Kubernát07204242018-06-04 18:12:09 +020021TEST_CASE("leaf editing")
22{
Václav Kubernátbddbb172018-06-13 16:27:39 +020023 auto schema = std::make_shared<StaticSchema>();
Václav Kubernát744f57f2018-06-29 22:46:26 +020024 schema->addModule("mod");
Václav Kubernáteeb38842019-03-20 19:46:05 +010025 schema->addModule("pizza-module");
Václav Kubernát744f57f2018-06-29 22:46:26 +020026 schema->addContainer("", "mod:contA");
27 schema->addLeaf("", "mod:leafString", yang::LeafDataTypes::String);
28 schema->addLeaf("", "mod:leafDecimal", yang::LeafDataTypes::Decimal);
29 schema->addLeaf("", "mod:leafBool", yang::LeafDataTypes::Bool);
Ivona Oboňová88c78ca2019-07-02 18:40:07 +020030 schema->addLeaf("", "mod:leafInt8", yang::LeafDataTypes::Int8);
31 schema->addLeaf("", "mod:leafInt16", yang::LeafDataTypes::Int16);
32 schema->addLeaf("", "mod:leafInt32", yang::LeafDataTypes::Int32);
33 schema->addLeaf("", "mod:leafInt64", yang::LeafDataTypes::Int64);
34 schema->addLeaf("", "mod:leafUint8", yang::LeafDataTypes::Uint8);
35 schema->addLeaf("", "mod:leafUint16", yang::LeafDataTypes::Uint16);
36 schema->addLeaf("", "mod:leafUint32", yang::LeafDataTypes::Uint32);
37 schema->addLeaf("", "mod:leafUint64", yang::LeafDataTypes::Uint64);
Václav Kubernátab538992019-03-06 15:30:50 +010038 schema->addLeaf("", "mod:leafBinary", yang::LeafDataTypes::Binary);
Václav Kubernáteeb38842019-03-20 19:46:05 +010039 schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "food"});
40 schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "vehicle"});
41 schema->addIdentity(ModuleValuePair{"mod", "food"}, ModuleValuePair{"mod", "pizza"});
42 schema->addIdentity(ModuleValuePair{"mod", "food"}, ModuleValuePair{"mod", "spaghetti"});
43 schema->addIdentity(ModuleValuePair{"mod", "pizza"}, ModuleValuePair{"pizza-module", "hawaii"});
44 schema->addLeafIdentityRef("", "mod:foodIdentRef", ModuleValuePair{"mod", "food"});
45 schema->addLeafIdentityRef("", "mod:pizzaIdentRef", ModuleValuePair{"mod", "pizza"});
46 schema->addLeafIdentityRef("mod:contA", "mod:identInCont", ModuleValuePair{"mod", "pizza"});
Václav Kubernát744f57f2018-06-29 22:46:26 +020047 schema->addLeafEnum("", "mod:leafEnum", {"lol", "data", "coze"});
48 schema->addLeaf("mod:contA", "mod:leafInCont", yang::LeafDataTypes::String);
49 schema->addList("", "mod:list", {"number"});
50 schema->addLeaf("mod:list", "mod:leafInList", yang::LeafDataTypes::String);
Václav Kubernát6a8d1d92019-04-24 20:30:36 +020051 schema->addLeafRef("", "mod:refToString", "mod:leafString");
52 schema->addLeafRef("", "mod:refToInt8", "mod:leafInt8");
Václav Kubernát07204242018-06-04 18:12:09 +020053 Parser parser(schema);
54 std::string input;
55 std::ostringstream errorStream;
56
57 SECTION("valid input")
58 {
59 set_ expected;
60
Václav Kubernátab538992019-03-06 15:30:50 +010061 SECTION("set mod:leafString some_data")
Václav Kubernát07204242018-06-04 18:12:09 +020062 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020063 input = "set mod:leafString some_data";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020064 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
Václav Kubernátebca2552018-06-08 19:06:02 +020065 expected.m_data = std::string("some_data");
Václav Kubernát07204242018-06-04 18:12:09 +020066 }
67
Václav Kubernát744f57f2018-06-29 22:46:26 +020068 SECTION("set mod:contA/leafInCont more_data")
Václav Kubernát07204242018-06-04 18:12:09 +020069 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020070 input = "set mod:contA/leafInCont more_data";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020071 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
72 expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
Václav Kubernátebca2552018-06-08 19:06:02 +020073 expected.m_data = std::string("more_data");
74 }
75
Václav Kubernátab538992019-03-06 15:30:50 +010076 SECTION("set mod:list[number=1]/leafInList another_data")
Václav Kubernátebca2552018-06-08 19:06:02 +020077 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020078 input = "set mod:list[number=1]/leafInList another_data";
Václav Kubernátebca2552018-06-08 19:06:02 +020079 auto keys = std::map<std::string, std::string>{
80 {"number", "1"}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +020081 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
82 expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInList")});
Václav Kubernátebca2552018-06-08 19:06:02 +020083 expected.m_data = std::string("another_data");
84 }
85
86 SECTION("data types")
87 {
88 SECTION("string")
89 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020090 input = "set mod:leafString somedata";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020091 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
Václav Kubernátebca2552018-06-08 19:06:02 +020092 expected.m_data = std::string("somedata");
93 }
94
Ivona Oboňová88c78ca2019-07-02 18:40:07 +020095 SECTION("int8")
Václav Kubernátebca2552018-06-08 19:06:02 +020096 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +020097 input = "set mod:leafInt8 2";
98 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
99 expected.m_data = int8_t{2};
100 }
101
102 SECTION("negative int8")
103 {
104 input = "set mod:leafInt8 -10";
105 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
106 expected.m_data = int8_t{-10};
107 }
108
109 SECTION("uint8")
110 {
111 input = "set mod:leafUint8 2";
112 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint8")});
113 expected.m_data = uint8_t{2};
114 }
115
116 SECTION("int16")
117 {
118 input = "set mod:leafInt16 30000";
119 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt16")});
120 expected.m_data = int16_t{30'000};
121 }
122
123 SECTION("uint16")
124 {
125 input = "set mod:leafUint16 30000";
126 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint16")});
127 expected.m_data = uint16_t{30'000};
128 }
129
130 SECTION("int32")
131 {
132 input = "set mod:leafInt32 30000";
133 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
134 expected.m_data = int32_t{30'000};
135 }
136
137 SECTION("uint32")
138 {
139 input = "set mod:leafUint32 30000";
140 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint32")});
141 expected.m_data = uint32_t{30'000};
142 }
143
144 SECTION("int32")
145 {
146 input = "set mod:leafInt32 30000";
147 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
148 expected.m_data = int32_t{30'000};
149 }
150
151 SECTION("uint64")
152 {
153 input = "set mod:leafUint64 30000";
154 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint64")});
155 expected.m_data = uint64_t{30'000};
Václav Kubernátebca2552018-06-08 19:06:02 +0200156 }
157
158 SECTION("decimal")
159 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200160 input = "set mod:leafDecimal 3.14159";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200161 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafDecimal")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200162 expected.m_data = 3.14159;
163 }
164
165 SECTION("enum")
166 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200167 input = "set mod:leafEnum coze";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200168 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafEnum")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200169 expected.m_data = enum_("coze");
170 }
171
172 SECTION("bool")
173 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200174 input = "set mod:leafBool true";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200175 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafBool")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200176 expected.m_data = true;
177 }
Václav Kubernátab538992019-03-06 15:30:50 +0100178
179 SECTION("binary")
180 {
181 SECTION("zero ending '='")
182 {
183 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++";
184 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++"};
185 }
186
187 SECTION("one ending '='")
188 {
189 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++=";
190 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++="};
191 }
192
193 SECTION("two ending '='")
194 {
195 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++==";
196 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++=="};
197 }
198 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafBinary")});
199 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100200
201 SECTION("identityRef")
202 {
203 SECTION("foodIdentRef")
204 {
205 input = "set mod:foodIdentRef ";
206 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("foodIdentRef")});
207
208 SECTION("food")
209 {
210 input += "food";
211 expected.m_data = identityRef_("food");
212 }
213 SECTION("mod:food")
214 {
215 input += "mod:food";
216 expected.m_data = identityRef_("mod", "food");
217 }
218 SECTION("pizza")
219 {
220 input += "pizza";
221 expected.m_data = identityRef_("pizza");
222 }
223 SECTION("mod:pizza")
224 {
225 input += "mod:pizza";
226 expected.m_data = identityRef_("mod", "pizza");
227 }
228 SECTION("pizza-module:hawaii")
229 {
230 input += "pizza-module:hawaii";
231 expected.m_data = identityRef_("pizza-module", "hawaii");
232 }
233 }
234 SECTION("pizzaIdentRef")
235 {
236 input = "set mod:pizzaIdentRef ";
237 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("pizzaIdentRef")});
238 SECTION("pizza")
239 {
240 input += "pizza";
241 expected.m_data = identityRef_("pizza");
242 }
243 SECTION("mod:pizza")
244 {
245 input += "mod:pizza";
246 expected.m_data = identityRef_("mod", "pizza");
247 }
248 SECTION("pizza-module:hawaii")
249 {
250 input += "pizza-module:hawaii";
251 expected.m_data = identityRef_("pizza-module", "hawaii");
252 }
253 }
254 SECTION("mod:contA/identInCont")
255 {
256 input = "set mod:contA/identInCont ";
257 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
258 expected.m_path.m_nodes.push_back(dataNode_(leaf_("identInCont")));
259 SECTION("pizza")
260 {
261 input += "pizza";
262 expected.m_data = identityRef_("pizza");
263 }
264 SECTION("mod:pizza")
265 {
266 input += "mod:pizza";
267 expected.m_data = identityRef_("mod", "pizza");
268 }
269 SECTION("pizza-module:hawaii")
270 {
271 input += "pizza-module:hawaii";
272 expected.m_data = identityRef_("pizza-module", "hawaii");
273 }
274 }
275 }
Václav Kubernát6a8d1d92019-04-24 20:30:36 +0200276 SECTION("leafRef")
277 {
278 SECTION("refToString")
279 {
280 input = "set mod:refToString blabal";
281 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("refToString")});
282 expected.m_data = std::string("blabal");
283 }
284
285 SECTION("refToInt8")
286 {
287 input = "set mod:refToInt8 42";
288 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("refToInt8")});
289 expected.m_data = int8_t{42};
290 }
291 }
Václav Kubernát07204242018-06-04 18:12:09 +0200292 }
293
294 command_ command = parser.parseCommand(input, errorStream);
295 REQUIRE(command.type() == typeid(set_));
296 REQUIRE(boost::get<set_>(command) == expected);
297 }
298
299 SECTION("invalid input")
300 {
301 SECTION("missing space between a command and its arguments")
302 {
303 SECTION("setleaf some_data")
304 {
305 input = "setleaf some_data";
306 }
307 }
308
309 SECTION("missing space between arguments")
310 {
311 SECTION("set leaflol")
312 {
313 input = "set leaflol";
314 }
315 }
316
317 SECTION("non-leaf identifiers")
318 {
319 SECTION("set nonexistent blabla")
320 {
321 input = "set nonexistent blabla";
322 }
323
324 SECTION("set contA abde")
325 {
326 input = "set contA abde";
327 }
328 }
329
Václav Kubernátebca2552018-06-08 19:06:02 +0200330 SECTION("wrong types")
331 {
332 SECTION("set leafBool blabla")
333 {
334 input = "set leafBool blabla";
335 }
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200336 SECTION("set leafUint8 blabla")
Václav Kubernátebca2552018-06-08 19:06:02 +0200337 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200338 input = "set leafUint8 blabla";
Václav Kubernátebca2552018-06-08 19:06:02 +0200339 }
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200340 SECTION("set leafUint8 -5")
Václav Kubernátebca2552018-06-08 19:06:02 +0200341 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200342 input = "set leafUint8 -5";
343 }
344 SECTION("set leafInt8 blabla")
345 {
346 input = "set leafInt8 blabla";
347 }
348 SECTION("set leafInt8 130")
349 {
350 input = "set leafInt8 130";
351 }
352 SECTION("set leafUint16 blabla")
353 {
354 input = "set leafUint16 blabla";
355 }
356 SECTION("set leafInt16 blabla")
357 {
358 input = "set leafInt16 blabla";
359 }
360 SECTION("set leafUint32 blabla")
361 {
362 input = "set leafUint32 blabla";
363 }
364 SECTION("set leafInt32 blabla")
365 {
366 input = "set leafInt32 blabla";
367 }
368 SECTION("set leafUint64 blabla")
369 {
370 input = "set leafUint64 blabla";
371 }
372 SECTION("set leafInt64 blabla")
373 {
374 input = "set leafInt64 blabla";
Václav Kubernátebca2552018-06-08 19:06:02 +0200375 }
376 SECTION("set leafEnum blabla")
377 {
378 input = "set leafEnum blabla";
379 }
Václav Kubernát6a8d1d92019-04-24 20:30:36 +0200380 SECTION("set mod:refToInt8 blabla")
381 {
382 input = "set mod:refToInt8 blabla";
383 }
Václav Kubernátebca2552018-06-08 19:06:02 +0200384 }
385
Václav Kubernátab538992019-03-06 15:30:50 +0100386 SECTION("wrong base64 strings")
387 {
388 SECTION("invalid character")
389 input = "set leafBinary dbahj-";
390 SECTION("equal sign in the middle")
391 input = "set leafBinary db=ahj";
392 }
393
Václav Kubernáteeb38842019-03-20 19:46:05 +0100394 SECTION("non-existing identity")
395 {
396 input = "set mod:foodIdentRef identityBLABLA";
397 }
398
399 SECTION("setting identities with wrong bases")
400 {
401 SECTION("set mod:foodIdentRef mod:vehicle")
402 {
403 input = "set mod:foodIdentRef mod:vehicle";
404 }
405 SECTION("set mod:pizzaIdentRef mod:food")
406 {
407 input = "set mod:pizzaIdentRef mod:food";
408 }
409 }
410 SECTION("setting different module identities without prefix")
411 {
412 input = "set mod:pizzaIdentRef hawaii";
413 }
414 SECTION("identity prefix without name")
415 {
416 input = "set mod:contA/identInCont pizza-module:";
417 }
418
Jan Kundrátc381e632019-03-14 13:39:11 +0100419 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernát07204242018-06-04 18:12:09 +0200420 }
421}