blob: b0db59408f62d013acf64fdef436d34d019bfc38 [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át07204242018-06-04 18:12:09 +020051 Parser parser(schema);
52 std::string input;
53 std::ostringstream errorStream;
54
55 SECTION("valid input")
56 {
57 set_ expected;
58
Václav Kubernátab538992019-03-06 15:30:50 +010059 SECTION("set mod:leafString some_data")
Václav Kubernát07204242018-06-04 18:12:09 +020060 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020061 input = "set mod:leafString some_data";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020062 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
Václav Kubernátebca2552018-06-08 19:06:02 +020063 expected.m_data = std::string("some_data");
Václav Kubernát07204242018-06-04 18:12:09 +020064 }
65
Václav Kubernát744f57f2018-06-29 22:46:26 +020066 SECTION("set mod:contA/leafInCont more_data")
Václav Kubernát07204242018-06-04 18:12:09 +020067 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020068 input = "set mod:contA/leafInCont more_data";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020069 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
70 expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInCont")});
Václav Kubernátebca2552018-06-08 19:06:02 +020071 expected.m_data = std::string("more_data");
72 }
73
Václav Kubernátab538992019-03-06 15:30:50 +010074 SECTION("set mod:list[number=1]/leafInList another_data")
Václav Kubernátebca2552018-06-08 19:06:02 +020075 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020076 input = "set mod:list[number=1]/leafInList another_data";
Václav Kubernátebca2552018-06-08 19:06:02 +020077 auto keys = std::map<std::string, std::string>{
78 {"number", "1"}};
Václav Kubernát2eaceb82018-10-08 19:56:30 +020079 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, listElement_("list", keys)});
80 expected.m_path.m_nodes.push_back(dataNode_{leaf_("leafInList")});
Václav Kubernátebca2552018-06-08 19:06:02 +020081 expected.m_data = std::string("another_data");
82 }
83
84 SECTION("data types")
85 {
86 SECTION("string")
87 {
Václav Kubernát744f57f2018-06-29 22:46:26 +020088 input = "set mod:leafString somedata";
Václav Kubernát2eaceb82018-10-08 19:56:30 +020089 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafString")});
Václav Kubernátebca2552018-06-08 19:06:02 +020090 expected.m_data = std::string("somedata");
91 }
92
Ivona Oboňová88c78ca2019-07-02 18:40:07 +020093 SECTION("int8")
Václav Kubernátebca2552018-06-08 19:06:02 +020094 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +020095 input = "set mod:leafInt8 2";
96 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
97 expected.m_data = int8_t{2};
98 }
99
100 SECTION("negative int8")
101 {
102 input = "set mod:leafInt8 -10";
103 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
104 expected.m_data = int8_t{-10};
105 }
106
107 SECTION("uint8")
108 {
109 input = "set mod:leafUint8 2";
110 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint8")});
111 expected.m_data = uint8_t{2};
112 }
113
114 SECTION("int16")
115 {
116 input = "set mod:leafInt16 30000";
117 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt16")});
118 expected.m_data = int16_t{30'000};
119 }
120
121 SECTION("uint16")
122 {
123 input = "set mod:leafUint16 30000";
124 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint16")});
125 expected.m_data = uint16_t{30'000};
126 }
127
128 SECTION("int32")
129 {
130 input = "set mod:leafInt32 30000";
131 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
132 expected.m_data = int32_t{30'000};
133 }
134
135 SECTION("uint32")
136 {
137 input = "set mod:leafUint32 30000";
138 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint32")});
139 expected.m_data = uint32_t{30'000};
140 }
141
142 SECTION("int32")
143 {
144 input = "set mod:leafInt32 30000";
145 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
146 expected.m_data = int32_t{30'000};
147 }
148
149 SECTION("uint64")
150 {
151 input = "set mod:leafUint64 30000";
152 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint64")});
153 expected.m_data = uint64_t{30'000};
Václav Kubernátebca2552018-06-08 19:06:02 +0200154 }
155
156 SECTION("decimal")
157 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200158 input = "set mod:leafDecimal 3.14159";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200159 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafDecimal")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200160 expected.m_data = 3.14159;
161 }
162
163 SECTION("enum")
164 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200165 input = "set mod:leafEnum coze";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200166 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafEnum")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200167 expected.m_data = enum_("coze");
168 }
169
170 SECTION("bool")
171 {
Václav Kubernát744f57f2018-06-29 22:46:26 +0200172 input = "set mod:leafBool true";
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200173 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafBool")});
Václav Kubernátebca2552018-06-08 19:06:02 +0200174 expected.m_data = true;
175 }
Václav Kubernátab538992019-03-06 15:30:50 +0100176
177 SECTION("binary")
178 {
179 SECTION("zero ending '='")
180 {
181 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++";
182 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++"};
183 }
184
185 SECTION("one ending '='")
186 {
187 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++=";
188 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++="};
189 }
190
191 SECTION("two ending '='")
192 {
193 input = "set mod:leafBinary This/IsABase64EncodedSomething++/342431++==";
194 expected.m_data = binary_{"This/IsABase64EncodedSomething++/342431++=="};
195 }
196 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafBinary")});
197 }
Václav Kubernáteeb38842019-03-20 19:46:05 +0100198
199 SECTION("identityRef")
200 {
201 SECTION("foodIdentRef")
202 {
203 input = "set mod:foodIdentRef ";
204 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("foodIdentRef")});
205
206 SECTION("food")
207 {
208 input += "food";
209 expected.m_data = identityRef_("food");
210 }
211 SECTION("mod:food")
212 {
213 input += "mod:food";
214 expected.m_data = identityRef_("mod", "food");
215 }
216 SECTION("pizza")
217 {
218 input += "pizza";
219 expected.m_data = identityRef_("pizza");
220 }
221 SECTION("mod:pizza")
222 {
223 input += "mod:pizza";
224 expected.m_data = identityRef_("mod", "pizza");
225 }
226 SECTION("pizza-module:hawaii")
227 {
228 input += "pizza-module:hawaii";
229 expected.m_data = identityRef_("pizza-module", "hawaii");
230 }
231 }
232 SECTION("pizzaIdentRef")
233 {
234 input = "set mod:pizzaIdentRef ";
235 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("pizzaIdentRef")});
236 SECTION("pizza")
237 {
238 input += "pizza";
239 expected.m_data = identityRef_("pizza");
240 }
241 SECTION("mod:pizza")
242 {
243 input += "mod:pizza";
244 expected.m_data = identityRef_("mod", "pizza");
245 }
246 SECTION("pizza-module:hawaii")
247 {
248 input += "pizza-module:hawaii";
249 expected.m_data = identityRef_("pizza-module", "hawaii");
250 }
251 }
252 SECTION("mod:contA/identInCont")
253 {
254 input = "set mod:contA/identInCont ";
255 expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, container_("contA")});
256 expected.m_path.m_nodes.push_back(dataNode_(leaf_("identInCont")));
257 SECTION("pizza")
258 {
259 input += "pizza";
260 expected.m_data = identityRef_("pizza");
261 }
262 SECTION("mod:pizza")
263 {
264 input += "mod:pizza";
265 expected.m_data = identityRef_("mod", "pizza");
266 }
267 SECTION("pizza-module:hawaii")
268 {
269 input += "pizza-module:hawaii";
270 expected.m_data = identityRef_("pizza-module", "hawaii");
271 }
272 }
273 }
Václav Kubernát07204242018-06-04 18:12:09 +0200274 }
275
276 command_ command = parser.parseCommand(input, errorStream);
277 REQUIRE(command.type() == typeid(set_));
278 REQUIRE(boost::get<set_>(command) == expected);
279 }
280
281 SECTION("invalid input")
282 {
283 SECTION("missing space between a command and its arguments")
284 {
285 SECTION("setleaf some_data")
286 {
287 input = "setleaf some_data";
288 }
289 }
290
291 SECTION("missing space between arguments")
292 {
293 SECTION("set leaflol")
294 {
295 input = "set leaflol";
296 }
297 }
298
299 SECTION("non-leaf identifiers")
300 {
301 SECTION("set nonexistent blabla")
302 {
303 input = "set nonexistent blabla";
304 }
305
306 SECTION("set contA abde")
307 {
308 input = "set contA abde";
309 }
310 }
311
Václav Kubernátebca2552018-06-08 19:06:02 +0200312 SECTION("wrong types")
313 {
314 SECTION("set leafBool blabla")
315 {
316 input = "set leafBool blabla";
317 }
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200318 SECTION("set leafUint8 blabla")
Václav Kubernátebca2552018-06-08 19:06:02 +0200319 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200320 input = "set leafUint8 blabla";
Václav Kubernátebca2552018-06-08 19:06:02 +0200321 }
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200322 SECTION("set leafUint8 -5")
Václav Kubernátebca2552018-06-08 19:06:02 +0200323 {
Ivona Oboňová88c78ca2019-07-02 18:40:07 +0200324 input = "set leafUint8 -5";
325 }
326 SECTION("set leafInt8 blabla")
327 {
328 input = "set leafInt8 blabla";
329 }
330 SECTION("set leafInt8 130")
331 {
332 input = "set leafInt8 130";
333 }
334 SECTION("set leafUint16 blabla")
335 {
336 input = "set leafUint16 blabla";
337 }
338 SECTION("set leafInt16 blabla")
339 {
340 input = "set leafInt16 blabla";
341 }
342 SECTION("set leafUint32 blabla")
343 {
344 input = "set leafUint32 blabla";
345 }
346 SECTION("set leafInt32 blabla")
347 {
348 input = "set leafInt32 blabla";
349 }
350 SECTION("set leafUint64 blabla")
351 {
352 input = "set leafUint64 blabla";
353 }
354 SECTION("set leafInt64 blabla")
355 {
356 input = "set leafInt64 blabla";
Václav Kubernátebca2552018-06-08 19:06:02 +0200357 }
358 SECTION("set leafEnum blabla")
359 {
360 input = "set leafEnum blabla";
361 }
362 }
363
Václav Kubernátab538992019-03-06 15:30:50 +0100364 SECTION("wrong base64 strings")
365 {
366 SECTION("invalid character")
367 input = "set leafBinary dbahj-";
368 SECTION("equal sign in the middle")
369 input = "set leafBinary db=ahj";
370 }
371
Václav Kubernáteeb38842019-03-20 19:46:05 +0100372 SECTION("non-existing identity")
373 {
374 input = "set mod:foodIdentRef identityBLABLA";
375 }
376
377 SECTION("setting identities with wrong bases")
378 {
379 SECTION("set mod:foodIdentRef mod:vehicle")
380 {
381 input = "set mod:foodIdentRef mod:vehicle";
382 }
383 SECTION("set mod:pizzaIdentRef mod:food")
384 {
385 input = "set mod:pizzaIdentRef mod:food";
386 }
387 }
388 SECTION("setting different module identities without prefix")
389 {
390 input = "set mod:pizzaIdentRef hawaii";
391 }
392 SECTION("identity prefix without name")
393 {
394 input = "set mod:contA/identInCont pizza-module:";
395 }
396
Jan Kundrátc381e632019-03-14 13:39:11 +0100397 REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
Václav Kubernát07204242018-06-04 18:12:09 +0200398 }
399}