35 TEST_CASE(
"'init_chains' initializes a map of chain names to empty chains" 38 SECTION(
"default chain listed first")
40 tao::pegtl::string_input<> in(
42 "chain first_chain {}\n" 43 "chain second_chain {}\n" 44 "chain third_chain {}\n",
"");
46 REQUIRE(root !=
nullptr);
48 REQUIRE(chains.count(
"default") == 0);
49 REQUIRE(chains.count(
"first_chain") == 1);
50 REQUIRE(chains.count(
"second_chain") == 1);
51 REQUIRE(chains.count(
"third_chain") == 1);
52 REQUIRE(chains[
"first_chain"] !=
nullptr);
53 REQUIRE(chains[
"second_chain"] !=
nullptr);
54 REQUIRE(chains[
"third_chain"] !=
nullptr);
56 str(*chains[
"first_chain"]) ==
57 "chain first_chain {\n" 60 str(*chains[
"second_chain"]) ==
61 "chain second_chain {\n" 64 str(*chains[
"third_chain"]) ==
65 "chain third_chain {\n" 68 SECTION(
"default chain listed last")
70 tao::pegtl::string_input<> in(
71 "chain first_chain {}\n" 72 "chain second_chain {}\n" 73 "chain third_chain {}\n" 74 "chain default {}\n",
"");
76 REQUIRE(root !=
nullptr);
78 REQUIRE(chains.count(
"default") == 0);
79 REQUIRE(chains.count(
"first_chain") == 1);
80 REQUIRE(chains.count(
"second_chain") == 1);
81 REQUIRE(chains.count(
"third_chain") == 1);
82 REQUIRE(chains[
"first_chain"] !=
nullptr);
83 REQUIRE(chains[
"second_chain"] !=
nullptr);
84 REQUIRE(chains[
"third_chain"] !=
nullptr);
86 str(*chains[
"first_chain"]) ==
87 "chain first_chain {\n" 90 str(*chains[
"second_chain"]) ==
91 "chain second_chain {\n" 94 str(*chains[
"third_chain"]) ==
95 "chain third_chain {\n" 101 TEST_CASE(
"'parse_action' parses an action from the given AST node.",
104 std::map<std::string, std::shared_ptr<Chain>> chains;
105 chains[
"some_chain"] = std::make_shared<Chain>(
"some_chain");
106 SECTION(
"Accept action.")
108 tao::pegtl::string_input<> in(
113 REQUIRE(root !=
nullptr);
114 REQUIRE_FALSE(root->children.empty());
115 REQUIRE(root->children[0] !=
nullptr);
116 REQUIRE_FALSE(root->children[0]->children.empty());
117 REQUIRE(root->children[0]->children[0] !=
nullptr);
119 *root->children[0]->children[0], {}, {}, chains);
120 REQUIRE(
str(*action) ==
"accept");
122 SECTION(
"Accept action, with priority.")
124 tao::pegtl::string_input<> in(
126 " accept with priority -1;\n" 129 REQUIRE(root !=
nullptr);
130 REQUIRE_FALSE(root->children.empty());
131 REQUIRE(root->children[0] !=
nullptr);
132 REQUIRE_FALSE(root->children[0]->children.empty());
133 REQUIRE(root->children[0]->children[0] !=
nullptr);
135 *root->children[0]->children[0], -1, {}, chains);
136 REQUIRE(
str(*action) ==
"accept with priority -1");
138 SECTION(
"Accept action, with condition.")
140 tao::pegtl::string_input<> in(
142 " accept if PING from 192.168 to 127.0/8;\n" 145 REQUIRE(root !=
nullptr);
146 REQUIRE_FALSE(root->children.empty());
147 REQUIRE(root->children[0] !=
nullptr);
148 REQUIRE_FALSE(root->children[0]->children.empty());
149 REQUIRE(root->children[0]->children[0] !=
nullptr);
152 *root->children[0]->children[0], {},
153 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
154 REQUIRE(
str(*action) ==
"accept if PING from 192.168 to 127.0/8");
156 SECTION(
"Accept action, with priority and condition.")
158 tao::pegtl::string_input<> in(
160 " accept with priority -1 if PING from 192.168 to 127.0/8;\n" 163 REQUIRE(root !=
nullptr);
164 REQUIRE_FALSE(root->children.empty());
165 REQUIRE(root->children[0] !=
nullptr);
166 REQUIRE_FALSE(root->children[0]->children.empty());
167 REQUIRE(root->children[0]->children[0] !=
nullptr);
170 *root->children[0]->children[0], -1,
171 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
174 "accept with priority -1 if PING from 192.168 to 127.0/8");
176 SECTION(
"Reject action.")
178 tao::pegtl::string_input<> in(
183 REQUIRE(root !=
nullptr);
184 REQUIRE_FALSE(root->children.empty());
185 REQUIRE(root->children[0] !=
nullptr);
186 REQUIRE_FALSE(root->children[0]->children.empty());
187 REQUIRE(root->children[0]->children[0] !=
nullptr);
189 *root->children[0]->children[0], {}, {}, chains);
190 REQUIRE(
str(*action) ==
"reject");
192 SECTION(
"Reject action, with priority (priority ignored for reject).")
194 tao::pegtl::string_input<> in(
196 " reject with priority -1;\n" 199 REQUIRE(root !=
nullptr);
200 REQUIRE_FALSE(root->children.empty());
201 REQUIRE(root->children[0] !=
nullptr);
202 REQUIRE_FALSE(root->children[0]->children.empty());
203 REQUIRE(root->children[0]->children[0] !=
nullptr);
205 *root->children[0]->children[0], -1, {}, chains);
206 REQUIRE(
str(*action) ==
"reject");
208 SECTION(
"Reject action, with condition.")
210 tao::pegtl::string_input<> in(
212 " reject if PING from 192.168 to 127.0/8;\n" 215 REQUIRE(root !=
nullptr);
216 REQUIRE_FALSE(root->children.empty());
217 REQUIRE(root->children[0] !=
nullptr);
218 REQUIRE_FALSE(root->children[0]->children.empty());
219 REQUIRE(root->children[0]->children[0] !=
nullptr);
222 *root->children[0]->children[0], {},
223 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
224 REQUIRE(
str(*action) ==
"reject if PING from 192.168 to 127.0/8");
226 SECTION(
"Reject action, with priority and condition " 227 "(priority ignored for reject).")
229 tao::pegtl::string_input<> in(
231 " reject if PING from 192.168 to 127.0/8;\n" 234 REQUIRE(root !=
nullptr);
235 REQUIRE_FALSE(root->children.empty());
236 REQUIRE(root->children[0] !=
nullptr);
237 REQUIRE_FALSE(root->children[0]->children.empty());
238 REQUIRE(root->children[0]->children[0] !=
nullptr);
241 *root->children[0]->children[0], -1,
242 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
245 "reject if PING from 192.168 to 127.0/8");
247 SECTION(
"Call action.")
249 tao::pegtl::string_input<> in(
251 " call some_chain;\n" 254 REQUIRE(root !=
nullptr);
255 REQUIRE_FALSE(root->children.empty());
256 REQUIRE(root->children[0] !=
nullptr);
257 REQUIRE_FALSE(root->children[0]->children.empty());
258 REQUIRE(root->children[0]->children[0] !=
nullptr);
260 *root->children[0]->children[0], {}, {}, chains);
261 REQUIRE(
str(*action) ==
"call some_chain");
263 SECTION(
"Call action, throws and error if calling the default chain.")
265 tao::pegtl::string_input<> in(
266 "chain some_chain {\n" 270 REQUIRE(root !=
nullptr);
271 REQUIRE_FALSE(root->children.empty());
272 REQUIRE(root->children[0] !=
nullptr);
273 REQUIRE_FALSE(root->children[0]->children.empty());
274 REQUIRE(root->children[0]->children[0] !=
nullptr);
276 parse_action(*root->children[0]->children[0], {}, {}, chains),
277 std::invalid_argument);
279 parse_action(*root->children[0]->children[0], {}, {}, chains),
280 "cannot 'call' the default chain");
282 SECTION(
"Call action, with priority.")
284 tao::pegtl::string_input<> in(
286 " call some_chain with priority -1;\n" 289 REQUIRE(root !=
nullptr);
290 REQUIRE_FALSE(root->children.empty());
291 REQUIRE(root->children[0] !=
nullptr);
292 REQUIRE_FALSE(root->children[0]->children.empty());
293 REQUIRE(root->children[0]->children[0] !=
nullptr);
295 *root->children[0]->children[0], -1, {}, chains);
296 REQUIRE(
str(*action) ==
"call some_chain with priority -1");
298 SECTION(
"Call action, with condition.")
300 tao::pegtl::string_input<> in(
302 " call some_chain if PING from 192.168 to 127.0/8;\n" 305 REQUIRE(root !=
nullptr);
306 REQUIRE_FALSE(root->children.empty());
307 REQUIRE(root->children[0] !=
nullptr);
308 REQUIRE_FALSE(root->children[0]->children.empty());
309 REQUIRE(root->children[0]->children[0] !=
nullptr);
312 *root->children[0]->children[0], {},
313 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
315 str(*action) ==
"call some_chain if PING from 192.168 to 127.0/8");
317 SECTION(
"Call action, with priority and condition.")
319 tao::pegtl::string_input<> in(
321 " call some_chain with priority -1 " 322 "if PING from 192.168 to 127.0/8;\n" 325 REQUIRE(root !=
nullptr);
326 REQUIRE_FALSE(root->children.empty());
327 REQUIRE(root->children[0] !=
nullptr);
328 REQUIRE_FALSE(root->children[0]->children.empty());
329 REQUIRE(root->children[0]->children[0] !=
nullptr);
332 *root->children[0]->children[0], -1,
333 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
336 "call some_chain with priority -1 if PING from 192.168 to 127.0/8");
338 SECTION(
"GoTo action.")
340 tao::pegtl::string_input<> in(
342 " goto some_chain;\n" 345 REQUIRE(root !=
nullptr);
346 REQUIRE_FALSE(root->children.empty());
347 REQUIRE(root->children[0] !=
nullptr);
348 REQUIRE_FALSE(root->children[0]->children.empty());
349 REQUIRE(root->children[0]->children[0] !=
nullptr);
351 *root->children[0]->children[0], {}, {}, chains);
352 REQUIRE(
str(*action) ==
"goto some_chain");
354 SECTION(
"GoTo action, throws and error if going to the default chain.")
356 tao::pegtl::string_input<> in(
357 "chain some_chain {\n" 361 REQUIRE(root !=
nullptr);
362 REQUIRE_FALSE(root->children.empty());
363 REQUIRE(root->children[0] !=
nullptr);
364 REQUIRE_FALSE(root->children[0]->children.empty());
365 REQUIRE(root->children[0]->children[0] !=
nullptr);
367 parse_action(*root->children[0]->children[0], {}, {}, chains),
368 std::invalid_argument);
370 parse_action(*root->children[0]->children[0], {}, {}, chains),
371 "cannot 'goto' the default chain");
373 SECTION(
"GoTo action, with priority.")
375 tao::pegtl::string_input<> in(
377 " goto some_chain with priority -1;\n" 380 REQUIRE(root !=
nullptr);
381 REQUIRE_FALSE(root->children.empty());
382 REQUIRE(root->children[0] !=
nullptr);
383 REQUIRE_FALSE(root->children[0]->children.empty());
384 REQUIRE(root->children[0]->children[0] !=
nullptr);
386 parse_action(*root->children[0]->children[0], -1, {}, chains);
387 REQUIRE(
str(*action) ==
"goto some_chain with priority -1");
389 SECTION(
"GoTo action, with condition.")
391 tao::pegtl::string_input<> in(
393 " goto some_chain if PING from 192.168 to 127.0/8;\n" 396 REQUIRE(root !=
nullptr);
397 REQUIRE_FALSE(root->children.empty());
398 REQUIRE(root->children[0] !=
nullptr);
399 REQUIRE_FALSE(root->children[0]->children.empty());
400 REQUIRE(root->children[0]->children[0] !=
nullptr);
403 *root->children[0]->children[0], {},
404 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
406 str(*action) ==
"goto some_chain if PING from 192.168 to 127.0/8");
408 SECTION(
"GoTo action, with priority and condition.")
410 tao::pegtl::string_input<> in(
412 " goto some_chain with priority -1 " 413 "if PING from 192.168 to 127.0/8;\n" 416 REQUIRE(root !=
nullptr);
417 REQUIRE_FALSE(root->children.empty());
418 REQUIRE(root->children[0] !=
nullptr);
419 REQUIRE_FALSE(root->children[0]->children.empty());
420 REQUIRE(root->children[0]->children[0] !=
nullptr);
423 *root->children[0]->children[0], -1,
424 If().type(
"PING").from(
"192.168").to(
"127.0/8"), chains);
427 "goto some_chain with priority -1 if PING from 192.168 to 127.0/8");
432 TEST_CASE(
"'parse_condition' parses a condition from the given AST node.",
435 SECTION(
"Condition with type.")
437 tao::pegtl::string_input<> in(
442 REQUIRE(root !=
nullptr);
443 REQUIRE_FALSE(root->children.empty());
444 REQUIRE(root->children[0] !=
nullptr);
445 REQUIRE_FALSE(root->children[0]->children.empty());
446 REQUIRE(root->children[0]->children[0] !=
nullptr);
447 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
448 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
450 *root->children[0]->children[0]->children[0]);
451 REQUIRE(
str(condition) ==
"if PING");
453 SECTION(
"Condition source.")
455 tao::pegtl::string_input<> in(
457 " accept if from 192.168;\n" 460 REQUIRE(root !=
nullptr);
461 REQUIRE_FALSE(root->children.empty());
462 REQUIRE(root->children[0] !=
nullptr);
463 REQUIRE_FALSE(root->children[0]->children.empty());
464 REQUIRE(root->children[0]->children[0] !=
nullptr);
465 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
466 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
468 *root->children[0]->children[0]->children[0]);
469 REQUIRE(
str(condition) ==
"if from 192.168");
471 SECTION(
"Condition destination.")
473 tao::pegtl::string_input<> in(
475 " accept if to 128.0/8;\n" 478 REQUIRE(root !=
nullptr);
479 REQUIRE_FALSE(root->children.empty());
480 REQUIRE(root->children[0] !=
nullptr);
481 REQUIRE_FALSE(root->children[0]->children.empty());
482 REQUIRE(root->children[0]->children[0] !=
nullptr);
483 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
484 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
486 *root->children[0]->children[0]->children[0]);
487 REQUIRE(
str(condition) ==
"if to 128.0/8");
489 SECTION(
"Condition source and destination.")
491 tao::pegtl::string_input<> in(
493 " accept if from 192.168 to 127.0/8;\n" 496 REQUIRE(root !=
nullptr);
497 REQUIRE_FALSE(root->children.empty());
498 REQUIRE(root->children[0] !=
nullptr);
499 REQUIRE_FALSE(root->children[0]->children.empty());
500 REQUIRE(root->children[0]->children[0] !=
nullptr);
501 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
502 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
504 *root->children[0]->children[0]->children[0]);
505 REQUIRE(
str(condition) ==
"if from 192.168 to 127.0/8");
507 SECTION(
"Condition type and source.")
509 tao::pegtl::string_input<> in(
511 " accept if PING from 192.168;\n" 514 REQUIRE(root !=
nullptr);
515 REQUIRE_FALSE(root->children.empty());
516 REQUIRE(root->children[0] !=
nullptr);
517 REQUIRE_FALSE(root->children[0]->children.empty());
518 REQUIRE(root->children[0]->children[0] !=
nullptr);
519 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
520 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
522 *root->children[0]->children[0]->children[0]);
523 REQUIRE(
str(condition) ==
"if PING from 192.168");
525 SECTION(
"Condition type and destination.")
527 tao::pegtl::string_input<> in(
529 " accept if PING to 127.0/8;\n" 532 REQUIRE(root !=
nullptr);
533 REQUIRE_FALSE(root->children.empty());
534 REQUIRE(root->children[0] !=
nullptr);
535 REQUIRE_FALSE(root->children[0]->children.empty());
536 REQUIRE(root->children[0]->children[0] !=
nullptr);
537 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
538 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
540 *root->children[0]->children[0]->children[0]);
541 REQUIRE(
str(condition) ==
"if PING to 127.0/8");
543 SECTION(
"Condition type, source, and destination.")
545 tao::pegtl::string_input<> in(
547 " accept if PING from 192.168 to 127.0/8;\n" 550 REQUIRE(root !=
nullptr);
551 REQUIRE_FALSE(root->children.empty());
552 REQUIRE(root->children[0] !=
nullptr);
553 REQUIRE_FALSE(root->children[0]->children.empty());
554 REQUIRE(root->children[0]->children[0] !=
nullptr);
555 REQUIRE_FALSE(root->children[0]->children[0]->children.empty());
556 REQUIRE(root->children[0]->children[0]->children[0] !=
nullptr);
558 *root->children[0]->children[0]->children[0]);
559 REQUIRE(
str(condition) ==
"if PING from 192.168 to 127.0/8");
564 TEST_CASE(
"'parse_chain' parses an action from the given AST node.",
567 Chain default_chain(
"default");
568 std::map<std::string, std::shared_ptr<Chain>> chains;
569 chains[
"some_chain"] = std::make_shared<Chain>(
"some_chain");
570 SECTION(
"Accept action.")
572 tao::pegtl::string_input<> in(
575 " accept with priority -1;\n" 576 " accept if PING from 192.168 to 127.0/8;\n" 577 " accept with priority -1 if PING from 192.168 to 127.0/8;\n" 580 REQUIRE(root !=
nullptr);
581 REQUIRE_FALSE(root->children.empty());
582 REQUIRE(root->children[0] !=
nullptr);
583 parse_chain(default_chain, *root->children[0], chains);
584 REQUIRE(
str(default_chain) ==
587 " accept with priority -1;\n" 588 " accept if PING from 192.168 to 127.0/8;\n" 589 " accept with priority -1 if PING from 192.168 to 127.0/8;\n" 592 SECTION(
"Reject action.")
594 tao::pegtl::string_input<> in(
597 " reject if PING from 192.168 to 127.0/8;\n" 600 REQUIRE(root !=
nullptr);
601 REQUIRE_FALSE(root->children.empty());
602 REQUIRE(root->children[0] !=
nullptr);
603 parse_chain(default_chain, *root->children[0], chains);
604 REQUIRE(
str(default_chain) ==
607 " reject if PING from 192.168 to 127.0/8;\n" 610 SECTION(
"Call action.")
612 tao::pegtl::string_input<> in(
614 " call some_chain;\n" 615 " call some_chain with priority -1;\n" 616 " call some_chain if PING from 192.168 to 127.0/8;\n" 617 " call some_chain with priority -1" 618 "if PING from 192.168 to 127.0/8;\n" 621 REQUIRE(root !=
nullptr);
622 REQUIRE_FALSE(root->children.empty());
623 REQUIRE(root->children[0] !=
nullptr);
624 parse_chain(default_chain, *root->children[0], chains);
625 REQUIRE(
str(default_chain) ==
627 " call some_chain;\n" 628 " call some_chain with priority -1;\n" 629 " call some_chain if PING from 192.168 to 127.0/8;\n" 630 " call some_chain with priority -1 " 631 "if PING from 192.168 to 127.0/8;\n" 634 SECTION(
"GoTo action.")
636 tao::pegtl::string_input<> in(
638 " goto some_chain;\n" 639 " goto some_chain with priority -1;\n" 640 " goto some_chain if PING from 192.168 to 127.0/8;\n" 641 " goto some_chain with priority -1" 642 "if PING from 192.168 to 127.0/8;\n" 645 REQUIRE(root !=
nullptr);
646 REQUIRE_FALSE(root->children.empty());
647 REQUIRE(root->children[0] !=
nullptr);
648 parse_chain(default_chain, *root->children[0], chains);
649 REQUIRE(
str(default_chain) ==
651 " goto some_chain;\n" 652 " goto some_chain with priority -1;\n" 653 " goto some_chain if PING from 192.168 to 127.0/8;\n" 654 " goto some_chain with priority -1 " 655 "if PING from 192.168 to 127.0/8;\n" 661 TEST_CASE(
"'parse_filter' parses the filter from the given AST root node.",
666 auto encapsulated_data =
668 SECTION(
"Successful parse.")
670 tao::pegtl::string_input<> in(
672 " call first_chain if PING;\n" 673 " goto second_chain if HEARTBEAT;\n" 677 "chain first_chain {\n" 678 " accept with priority 1;\n" 681 "chain second_chain {\n" 682 " accept with priority 2;\n" 685 REQUIRE(root !=
nullptr);
687 REQUIRE(filter !=
nullptr);
688 auto ping_result = filter->will_accept(
ping,
MAVAddress(
"127.1"));
689 REQUIRE(ping_result.first ==
true);
690 REQUIRE(ping_result.second == 1);
691 auto heartbeat_result =
693 REQUIRE(heartbeat_result.first ==
true);
694 REQUIRE(heartbeat_result.second == 2);
695 auto encapsulated_result =
696 filter->will_accept(encapsulated_data,
MAVAddress(
"127.1"));
697 REQUIRE(encapsulated_result.first ==
false);
699 SECTION(
"Default filter action is 'accept'")
701 tao::pegtl::string_input<> in(
702 "default_action accept;\n" 706 REQUIRE(root !=
nullptr);
708 REQUIRE(filter !=
nullptr);
710 REQUIRE(result.first ==
true);
711 REQUIRE(result.second == 0);
713 SECTION(
"Default filter action is 'reject'")
715 tao::pegtl::string_input<> in(
716 "default_action reject;\n" 720 REQUIRE(root !=
nullptr);
722 REQUIRE(filter !=
nullptr);
724 REQUIRE(result.first ==
false);
726 SECTION(
"The default, default filter action is 'reject'")
728 tao::pegtl::string_input<> in(
732 REQUIRE(root !=
nullptr);
734 REQUIRE(filter !=
nullptr);
736 REQUIRE(result.first ==
false);
741 TEST_CASE(
"'parse_serial' parses a serial interface from a serial interface " 742 "AST node.",
"[ConfigParser]")
744 SECTION(
"With flow control.")
746 tao::pegtl::string_input<> in(
749 " baudrate 115200;\n" 750 " flow_control yes;\n" 753 REQUIRE(root !=
nullptr);
754 REQUIRE_FALSE(root->children.empty());
755 REQUIRE(root->children[0] !=
nullptr);
756 auto filter = std::make_shared<Filter>(
Chain(
"default"));
757 auto connection_pool = std::make_shared<ConnectionPool>();
759 parse_serial(*root->children[0], filter, connection_pool);
764 " baudrate 115200;\n" 765 " flow_control yes;\n" 768 SECTION(
"Without flow control.")
770 tao::pegtl::string_input<> in(
773 " baudrate 115200;\n" 774 " flow_control no;\n" 777 REQUIRE(root !=
nullptr);
778 REQUIRE_FALSE(root->children.empty());
779 REQUIRE(root->children[0] !=
nullptr);
780 auto filter = std::make_shared<Filter>(
Chain(
"default"));
781 auto connection_pool = std::make_shared<ConnectionPool>();
783 parse_serial(*root->children[0], filter, connection_pool);
788 " baudrate 115200;\n" 789 " flow_control no;\n" 792 SECTION(
"Default flow control is off.")
794 tao::pegtl::string_input<> in(
797 " baudrate 115200;\n" 800 REQUIRE(root !=
nullptr);
801 REQUIRE_FALSE(root->children.empty());
802 REQUIRE(root->children[0] !=
nullptr);
803 auto filter = std::make_shared<Filter>(
Chain(
"default"));
804 auto connection_pool = std::make_shared<ConnectionPool>();
806 parse_serial(*root->children[0], filter, connection_pool);
811 " baudrate 115200;\n" 812 " flow_control no;\n" 815 SECTION(
"Default baud rate is 9600.")
817 tao::pegtl::string_input<> in(
822 REQUIRE(root !=
nullptr);
823 REQUIRE_FALSE(root->children.empty());
824 REQUIRE(root->children[0] !=
nullptr);
825 auto filter = std::make_shared<Filter>(
Chain(
"default"));
826 auto connection_pool = std::make_shared<ConnectionPool>();
828 parse_serial(*root->children[0], filter, connection_pool);
834 " flow_control no;\n" 837 SECTION(
"Throw error if device string is missing.")
839 tao::pegtl::string_input<> in(
843 REQUIRE(root !=
nullptr);
844 REQUIRE_FALSE(root->children.empty());
845 REQUIRE(root->children[0] !=
nullptr);
846 auto filter = std::make_shared<Filter>(
Chain(
"default"));
847 auto connection_pool = std::make_shared<ConnectionPool>();
849 parse_serial(*root->children[0], filter, connection_pool),
850 std::invalid_argument);
852 parse_serial(*root->children[0], filter, connection_pool),
853 "missing device string");
855 SECTION(
"With flow control.")
857 auto ping = std::make_shared<packet_v2::Packet>(to_vector(PingV2()));
858 auto set_mode = std::make_shared<packet_v2::Packet>(
859 to_vector(SetModeV2()));
860 auto param_ext_request_list =
861 std::make_shared<packet_v2::Packet>(
862 to_vector(ParamExtRequestListV2()));
863 fakeit::Mock<ConnectionPool> mock_pool;
864 std::shared_ptr<Connection> connection;
865 fakeit::When(Method(mock_pool, add)).AlwaysDo([&](
auto conn)
867 connection = conn.lock();
869 tao::pegtl::string_input<> in(
876 REQUIRE(root !=
nullptr);
877 REQUIRE_FALSE(root->children.empty());
878 REQUIRE(root->children[0] !=
nullptr);
879 auto filter = std::make_shared<Filter>(
Chain(
"default"),
true);
882 parse_serial(*root->children[0], filter, connection_pool);
883 REQUIRE(serial_port !=
nullptr);
884 fakeit::Verify(Method(mock_pool, add)).Exactly(1);
885 connection->send(
ping);
886 connection->send(set_mode);
887 connection->send(param_ext_request_list);
889 auto packet = connection->next_packet();
890 REQUIRE(packet !=
nullptr);
891 REQUIRE(*packet == *
ping);
893 packet = connection->next_packet();
894 REQUIRE(packet !=
nullptr);
895 REQUIRE(*packet == *param_ext_request_list);
897 packet = connection->next_packet();
898 REQUIRE(packet ==
nullptr);
903 TEST_CASE(
"'parse_udp' parses a UDP interface from a UDP interface AST node.",
906 SECTION(
"Without specific IP address.")
908 tao::pegtl::string_input<> in(
913 REQUIRE(root !=
nullptr);
914 REQUIRE_FALSE(root->children.empty());
915 REQUIRE(root->children[0] !=
nullptr);
916 auto filter = std::make_shared<Filter>(
Chain(
"default"));
917 auto connection_pool = std::make_shared<ConnectionPool>();
919 parse_udp(*root->children[0], filter, connection_pool);
926 SECTION(
"With specific IP address.")
928 tao::pegtl::string_input<> in(
931 " address 127.0.0.1;\n" 934 REQUIRE(root !=
nullptr);
935 REQUIRE_FALSE(root->children.empty());
936 REQUIRE(root->children[0] !=
nullptr);
937 auto filter = std::make_shared<Filter>(
Chain(
"default"));
938 auto connection_pool = std::make_shared<ConnectionPool>();
940 parse_udp(*root->children[0], filter, connection_pool);
945 " address 127.0.0.1;\n" 948 SECTION(
"Without specific IP address (with bitrate limit).")
950 tao::pegtl::string_input<> in(
953 " max_bitrate 8192;\n" 956 REQUIRE(root !=
nullptr);
957 REQUIRE_FALSE(root->children.empty());
958 REQUIRE(root->children[0] !=
nullptr);
959 auto filter = std::make_shared<Filter>(
Chain(
"default"));
960 auto connection_pool = std::make_shared<ConnectionPool>();
962 parse_udp(*root->children[0], filter, connection_pool);
967 " max_bitrate 8192;\n" 970 SECTION(
"With specific IP address (with bitrate limit).")
972 tao::pegtl::string_input<> in(
975 " address 127.0.0.1;\n" 976 " max_bitrate 8192;\n" 979 REQUIRE(root !=
nullptr);
980 REQUIRE_FALSE(root->children.empty());
981 REQUIRE(root->children[0] !=
nullptr);
982 auto filter = std::make_shared<Filter>(
Chain(
"default"));
983 auto connection_pool = std::make_shared<ConnectionPool>();
985 parse_udp(*root->children[0], filter, connection_pool);
990 " address 127.0.0.1;\n" 991 " max_bitrate 8192;\n" 997 TEST_CASE(
"'parse_interfaces' parses serial port and UDP interfaces from " 998 "the root node.",
"[ConfigParser]")
1000 tao::pegtl::string_input<> in(
1002 " device ./ttyS0;\n" 1003 " baudrate 115200;\n" 1004 " flow_control yes;\n" 1008 " device ./ttyS1;\n" 1010 " flow_control no;\n" 1019 " address 127.0.0.1;\n" 1024 " max_bitrate 8192;\n" 1029 " address 127.0.0.1;\n" 1030 " max_bitrate 8192;\n" 1033 REQUIRE(root !=
nullptr);
1034 auto filter = std::make_unique<Filter>(
Chain(
"default"));
1036 REQUIRE(interfaces.size() == 6);
1037 REQUIRE(interfaces[0] !=
nullptr);
1039 str(*interfaces[0]) ==
1041 " device ./ttyS0;\n" 1042 " baudrate 115200;\n" 1043 " flow_control yes;\n" 1045 REQUIRE(interfaces[1] !=
nullptr);
1047 str(*interfaces[1]) ==
1049 " device ./ttyS1;\n" 1051 " flow_control no;\n" 1053 REQUIRE(interfaces[2] !=
nullptr);
1055 str(*interfaces[2]) ==
1059 REQUIRE(interfaces[3] !=
nullptr);
1061 str(*interfaces[3]) ==
1064 " address 127.0.0.1;\n" 1066 REQUIRE(interfaces[4] !=
nullptr);
1068 str(*interfaces[4]) ==
1071 " max_bitrate 8192;\n" 1073 REQUIRE(interfaces[5] !=
nullptr);
1075 str(*interfaces[5]) ==
1078 " address 127.0.0.1;\n" 1079 " max_bitrate 8192;\n" 1084 TEST_CASE(
"ConfigParser can parse a file.",
"[ConfigParser]")
1086 SECTION(
"When the file exists and is valid.")
1090 SECTION(
"Throws an error if the file does not exist.")
1103 ":001: default_action\n" 1106 ":005: | port 14500\n" 1107 ":006: | address 127.0.0.1\n" 1108 ":007: | max_bitrate 8388608\n" 1110 ":012: | device ./ttyS0\n" 1111 ":013: | baudrate 115200\n" 1112 ":014: | flow_control yes\n" 1113 ":015: | preload 1.1\n" 1114 ":016: | preload 62.34\n" 1115 ":020: chain default\n" 1116 ":022: | call some_chain10\n" 1117 ":022: | | condition\n" 1118 ":022: | | | source 127.1\n" 1119 ":022: | | | dest 192.0\n" 1121 ":027: chain some_chain10\n" 1123 ":029: | | priority 99\n" 1124 ":029: | | condition\n" 1125 ":029: | | | dest 192.0\n" 1127 ":030: | | condition\n" 1128 ":030: | | | packet_type PING\n" 1129 ":031: | accept\n");
1133 TEST_CASE(
"ConfigParser's 'make_app' method returns an application object.",
1137 std::unique_ptr<App> app;
1138 REQUIRE_NOTHROW(app =
config.make_app());
1139 REQUIRE(app !=
nullptr);
std::string str(const T &object)
std::unique_ptr< config::parse_tree::node > parse(Input &in)
If parse_condition(const config::parse_tree::node &root)
std::unique_ptr< Filter > parse_filter(const config::parse_tree::node &root)
std::unique_ptr< UDPInterface > parse_udp(const config::parse_tree::node &root, std::shared_ptr< Filter > filter, std::shared_ptr< ConnectionPool > pool)
std::unique_ptr< SerialInterface > parse_serial(const config::parse_tree::node &root, std::shared_ptr< Filter > filter, std::shared_ptr< ConnectionPool > pool)
std::vector< std::unique_ptr< Interface > > parse_interfaces(const config::parse_tree::node &root, std::unique_ptr< Filter > filter)
void parse_chain(Chain &chain, const config::parse_tree::node &root, const std::map< std::string, std::shared_ptr< Chain >> &chains)
std::shared_ptr< T > mock_shared(fakeit::Mock< T > &mock)
std::map< std::string, std::shared_ptr< Chain > > init_chains(const config::parse_tree::node &root)
std::unique_ptr< Rule > parse_action(const config::parse_tree::node &root, std::optional< int > priority, std::optional< If > condition, const std::map< std::string, std::shared_ptr< Chain >> &chains)
TEST_CASE("'init_chains' initializes a map of chain names to empty chains" "[ConfigParser]")