mavtables  0.2.1
MAVLink router and firewall.
test_Connection.cpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #include <chrono>
19 #include <memory>
20 #include <set>
21 #include <stdexcept>
22 #include <utility>
23 #include <vector>
24 
25 #include <catch.hpp>
26 #include <fakeit.hpp>
27 
28 #include "AddressPool.hpp"
29 #include "Connection.hpp"
30 #include "Filter.hpp"
31 #include "Logger.hpp"
32 #include "MAVAddress.hpp"
33 #include "Packet.hpp"
34 #include "PacketQueue.hpp"
35 #include "PacketVersion2.hpp"
36 #include "utility.hpp"
37 
38 #include "common.hpp"
39 #include "common_Packet.hpp"
40 
41 
42 using namespace std::chrono_literals;
43 
44 
45 // NOTE: This testing file is not the best at not testing the implementation.
46 // If a better solution is found it should be rewritten.
47 
48 
49 TEST_CASE("Connection's can be constructed.", "[Connection]")
50 {
51  fakeit::Mock<Filter> mock_filter;
52  fakeit::Mock<AddressPool<>> mock_pool;
53  fakeit::Mock<PacketQueue> mock_queue;
54  auto filter = mock_shared(mock_filter);
55  auto pool = mock_unique(mock_pool);
56  auto queue = mock_unique(mock_queue);
57  SECTION("With default arguments.")
58  {
59  REQUIRE_NOTHROW(Connection("name", filter));
60  }
61  SECTION("As a regular connection.")
62  {
63  REQUIRE_NOTHROW(
64  Connection(
65  "name", filter, false, std::move(pool), std::move(queue)));
66  }
67  SECTION("As a mirror connection.")
68  {
69  REQUIRE_NOTHROW(
70  Connection(
71  "name", filter, true, std::move(pool), std::move(queue)));
72  }
73  SECTION("Ensures the filter pointer is not null.")
74  {
75  REQUIRE_THROWS_AS(
76  Connection(
77  "name", nullptr, false, std::move(pool), std::move(queue)),
78  std::invalid_argument);
79  pool = mock_unique(mock_pool);
80  queue = mock_unique(mock_queue);
81  REQUIRE_THROWS_WITH(
82  Connection(
83  "name", nullptr, false, std::move(pool), std::move(queue)),
84  "Given filter pointer is null.");
85  }
86  SECTION("Ensures the pool pointer is not null.")
87  {
88  REQUIRE_THROWS_AS(
89  Connection("name", filter, false, nullptr, std::move(queue)),
90  std::invalid_argument);
91  queue = mock_unique(mock_queue);
92  REQUIRE_THROWS_WITH(
93  Connection("name", filter, false, nullptr, std::move(queue)),
94  "Given pool pointer is null.");
95  }
96  SECTION("Ensures the queue pointer is not null.")
97  {
98  REQUIRE_THROWS_AS(
99  Connection("name", filter, false, std::move(pool), nullptr),
100  std::invalid_argument);
101  pool = mock_unique(mock_pool);
102  REQUIRE_THROWS_WITH(
103  Connection("name", filter, false, std::move(pool), nullptr),
104  "Given queue pointer is null.");
105  }
106 }
107 
108 
109 TEST_CASE("Connection's are printable", "[Connection]")
110 {
111  fakeit::Mock<Filter> mock_filter;
112  auto filter = mock_shared(mock_filter);
113  REQUIRE(str(Connection("some_name", filter)) == "some_name");
114  REQUIRE(str(Connection("/dev/ttyUSB0", filter)) == "/dev/ttyUSB0");
115  REQUIRE(str(Connection("127.0.0.1:14555", filter)) == "127.0.0.1:14555");
116 }
117 
118 
119 TEST_CASE("Connection's 'add_address' method adds/updates addresses.",
120  "[Connection]")
121 {
122  Logger::level(0);
123  fakeit::Mock<Filter> mock_filter;
124  fakeit::Mock<AddressPool<>> mock_pool;
125  fakeit::Mock<PacketQueue> mock_queue;
126  fakeit::Fake(Method(mock_pool, add));
127  auto filter = mock_shared(mock_filter);
128  auto pool = mock_unique(mock_pool);
129  auto queue = mock_unique(mock_queue);
130  Connection conn("DEVICE", filter, false, std::move(pool), std::move(queue));
131  SECTION("does not contain address (with logging)")
132  {
133  Logger::level(1);
134  MockCOut mock_cout;
135  fakeit::When(Method(mock_pool, contains)).AlwaysReturn(false);
136  conn.add_address(MAVAddress("192.168"));
137  fakeit::Verify(Method(mock_pool, add).Matching([](auto a)
138  {
139  return a == MAVAddress("192.168");
140  })).Once();
141  REQUIRE(
142  mock_cout.buffer().substr(21) ==
143  "new component 192.168 on DEVICE\n");
144  }
145  SECTION("does not contain address (without logging)")
146  {
147  MockCOut mock_cout;
148  fakeit::When(Method(mock_pool, contains)).AlwaysReturn(false);
149  conn.add_address(MAVAddress("192.168"));
150  fakeit::Verify(Method(mock_pool, add).Matching([](auto a)
151  {
152  return a == MAVAddress("192.168");
153  })).Once();
154  REQUIRE(mock_cout.buffer().empty());
155  }
156  SECTION("already contains address (with logging)")
157  {
158  Logger::level(1);
159  MockCOut mock_cout;
160  fakeit::When(Method(mock_pool, contains)).AlwaysReturn(true);
161  conn.add_address(MAVAddress("192.168"));
162  fakeit::Verify(Method(mock_pool, add).Matching([](auto a)
163  {
164  return a == MAVAddress("192.168");
165  })).Once();
166  REQUIRE(mock_cout.buffer().empty());
167  }
168  SECTION("already contains address (without logging)")
169  {
170  MockCOut mock_cout;
171  fakeit::When(Method(mock_pool, contains)).AlwaysReturn(true);
172  conn.add_address(MAVAddress("192.168"));
173  fakeit::Verify(Method(mock_pool, add).Matching([](auto a)
174  {
175  return a == MAVAddress("192.168");
176  })).Once();
177  REQUIRE(mock_cout.buffer().empty());
178  }
179  Logger::level(0);
180 }
181 
182 
183 TEST_CASE("Connection's 'next_packet' method.", "[Connection]")
184 {
185  auto ping = std::make_shared<packet_v2::Packet>(to_vector(PingV2()));
186  fakeit::Mock<Filter> mock_filter;
187  fakeit::Mock<AddressPool<>> mock_pool;
188  fakeit::Mock<PacketQueue> mock_queue;
189  auto filter = mock_shared(mock_filter);
190  auto pool = mock_unique(mock_pool);
191  auto queue = mock_unique(mock_queue);
192  Connection conn("name", filter, false, std::move(pool), std::move(queue));
193  SECTION("Returns the next packet.")
194  {
195  fakeit::When(
196  OverloadedMethod(
197  mock_queue, pop,
198  std::shared_ptr<const Packet>(
199  const std::chrono::nanoseconds &))).Return(ping);
200  std::chrono::nanoseconds timeout = 1ms;
201  auto packet = conn.next_packet(timeout);
202  REQUIRE(packet != nullptr);
203  REQUIRE(*packet == *ping);
204  fakeit::Verify(
205  OverloadedMethod(
206  mock_queue, pop,
207  std::shared_ptr<const Packet>(
208  const std::chrono::nanoseconds &)).Matching([](auto a)
209  {
210  return a == 1ms;
211  })).Once();
212  }
213  SECTION("Or times out and returns nullptr.")
214  {
215  fakeit::When(
216  OverloadedMethod(
217  mock_queue, pop,
218  std::shared_ptr<const Packet>(
219  const std::chrono::nanoseconds &))).Return(nullptr);
220  std::chrono::nanoseconds timeout = 0ms;
221  REQUIRE(conn.next_packet(timeout) == nullptr);
222  fakeit::Verify(
223  OverloadedMethod(
224  mock_queue, pop,
225  std::shared_ptr<const Packet>(
226  const std::chrono::nanoseconds &)).Matching([](auto a)
227  {
228  return a == 0ms;
229  })).Once();
230  }
231 }
232 
233 
234 TEST_CASE("Connection's 'send' method ensures the given packet is not "
235  "nullptr.", "[Connection]")
236 {
237  fakeit::Mock<Filter> mock_filter;
238  fakeit::Mock<AddressPool<>> mock_pool;
239  fakeit::Mock<PacketQueue> mock_queue;
240  auto filter = mock_shared(mock_filter);
241  auto pool = mock_unique(mock_pool);
242  auto queue = mock_unique(mock_queue);
243  Connection conn("name", filter, false, std::move(pool), std::move(queue));
244  SECTION("Ensures the given packet is not nullptr.")
245  {
246  REQUIRE_THROWS_AS(conn.send(nullptr), std::invalid_argument);
247  REQUIRE_THROWS_WITH(
248  conn.send(nullptr), "Given packet pointer is null.");
249  }
250 }
251 
252 
253 TEST_CASE("Connection's 'send' method (with destination address).",
254  "[Connection]")
255 {
256  Logger::level(2);
257  // Mocked objects.
258  fakeit::Mock<Filter> mock_filter;
259  fakeit::Mock<AddressPool<>> mock_pool;
260  fakeit::Mock<PacketQueue> mock_queue;
261  fakeit::Fake(Method(mock_queue, push));
262  auto filter = mock_shared(mock_filter);
263  auto pool = mock_unique(mock_pool);
264  auto queue = mock_unique(mock_queue);
265  // Packets for testing.
266  auto source_connection = std::make_shared<Connection>("SOURCE", filter);
267  auto ping = std::make_shared<packet_v2::Packet>(to_vector(PingV2()));
268  ping->connection(source_connection);
269  // Connection for testing.
270  Connection conn("DEST", filter, false, std::move(pool), std::move(queue));
271  SECTION("Adds the packet to the PacketQueue if the destination can be "
272  "reached on this connection and the filter allows it "
273  "(with logging).")
274  {
275  Logger::level(3);
276  MockCOut mock_cout;
277  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
278  [&](auto & a, auto & b)
279  {
280  (void)a;
281  (void)b;
282  return std::pair<bool, int>(true, 2);
283  });
284  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
285  {
286  return a != MAVAddress("192.168");
287  });
288  conn.send(ping);
289  fakeit::Verify(Method(mock_queue, push)).Once();
290  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
291  {
292  return a != nullptr && *a == *ping && b == 2;
293  })).Once();
294  REQUIRE(
295  mock_cout.buffer().substr(21) ==
296  "accepted PING (#4) from 192.168 to 127.1 (v2.0) "
297  "source SOURCE dest DEST\n");
298  }
299  SECTION("Adds the packet to the PacketQueue if the destination can be "
300  "reached on this connection and the filter allows it "
301  "(without logging).")
302  {
303  MockCOut mock_cout;
304  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
305  [&](auto & a, auto & b)
306  {
307  (void)a;
308  (void)b;
309  return std::pair<bool, int>(true, 2);
310  });
311  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
312  {
313  return a != MAVAddress("192.168");
314  });
315  conn.send(ping);
316  fakeit::Verify(Method(mock_queue, push)).Once();
317  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
318  {
319  return a != nullptr && *a == *ping && b == 2;
320  })).Once();
321  REQUIRE(mock_cout.buffer().empty());
322  }
323  SECTION("Silently drops the packet if the filter rejects it "
324  "(with logging).")
325  {
326  Logger::level(3);
327  MockCOut mock_cout;
328  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
329  [&](auto & a, auto & b)
330  {
331  (void)a;
332  (void)b;
333  return std::pair<bool, int>(false, 0);
334  });
335  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
336  {
337  return a != MAVAddress("192.168");
338  });
339  conn.send(ping);
340  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
341  REQUIRE(
342  mock_cout.buffer().substr(21) ==
343  "rejected PING (#4) from 192.168 to 127.1 (v2.0) "
344  "source SOURCE dest DEST\n");
345  }
346  SECTION("Silently drops the packet if the filter rejects it "
347  "(without logging).")
348  {
349  MockCOut mock_cout;
350  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
351  [&](auto & a, auto & b)
352  {
353  (void)a;
354  (void)b;
355  return std::pair<bool, int>(false, 0);
356  });
357  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
358  {
359  return a != MAVAddress("192.168");
360  });
361  conn.send(ping);
362  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
363  REQUIRE(mock_cout.buffer().empty());
364  }
365  SECTION("Silently drops the packet if the destination cannot be "
366  "reached on this connection (with logging).")
367  {
368  Logger::level(3);
369  MockCOut mock_cout;
370  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
371  [&](auto & a, auto & b)
372  {
373  (void)a;
374  (void)b;
375  return std::pair<bool, int>(true, 0);
376  });
377  fakeit::When(Method(mock_pool, addresses)).AlwaysReturn(
378  std::vector<MAVAddress>());
379  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
380  {
381  (void)a;
382  return false;
383  });
384  conn.send(ping);
385  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
386  REQUIRE(mock_cout.buffer().empty());
387  }
388  SECTION("Silently drops the packet if the destination cannot be "
389  "reached on this connection (without logging).")
390  {
391  MockCOut mock_cout;
392  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
393  [&](auto & a, auto & b)
394  {
395  (void)a;
396  (void)b;
397  return std::pair<bool, int>(true, 0);
398  });
399  fakeit::When(Method(mock_pool, addresses)).AlwaysReturn(
400  std::vector<MAVAddress>());
401  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
402  {
403  (void)a;
404  return false;
405  });
406  conn.send(ping);
407  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
408  REQUIRE(mock_cout.buffer().empty());
409  }
410  Logger::level(0);
411 }
412 
413 
414 TEST_CASE("Connection's 'send' method (without destination address).",
415  "[Connection]")
416 {
417  Logger::level(2);
418  // Mocked objects.
419  fakeit::Mock<Filter> mock_filter;
420  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
421  [&](auto & a, auto & b)
422  {
423  (void)a;
424 
425  if (b == MAVAddress("192.168"))
426  {
427  return std::pair<bool, int>(true, 2);
428  }
429 
430  if (b == MAVAddress("172.16"))
431  {
432  return std::pair<bool, int>(true, -3);
433  }
434 
435  return std::pair<bool, int>(false, 0);
436  });
437  fakeit::Mock<AddressPool<>> mock_pool;
438  fakeit::When(Method(mock_pool, contains)).AlwaysDo([](MAVAddress addr)
439  {
440  if (addr == MAVAddress("10.10"))
441  {
442  return true;
443  }
444 
445  if (addr == MAVAddress("172.16"))
446  {
447  return true;
448  }
449 
450  if (addr == MAVAddress("192.168"))
451  {
452  return true;
453  }
454 
455  return false;
456  });
457  fakeit::Mock<PacketQueue> mock_queue;
458  fakeit::Fake(Method(mock_queue, push));
459  auto filter = mock_shared(mock_filter);
460  auto pool = mock_unique(mock_pool);
461  auto queue = mock_unique(mock_queue);
462  // Packets for testing.
463  auto source_connection = std::make_shared<Connection>("SOURCE", filter);
464  auto heartbeat =
465  std::make_shared<packet_v2::Packet>(to_vector(HeartbeatV2()));
466  heartbeat->connection(source_connection);
467  // Connection for testing.
468  Connection conn("DEST", filter, false, std::move(pool), std::move(queue));
469  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
470  "any of the reachable addresses and favors the higher priority "
471  "(increasing priority) (with logging).")
472  {
473  Logger::level(3);
474  MockCOut mock_cout;
475  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
476  {
477  std::vector<MAVAddress> addr =
478  {
479  MAVAddress("10.10"),
480  MAVAddress("172.16"),
481  MAVAddress("192.168")
482  };
483  return addr;
484  });
485  conn.send(heartbeat);
486  fakeit::Verify(Method(mock_queue, push)).Once();
487  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
488  {
489  return a != nullptr && *a == *heartbeat && b == 2;
490  })).Once();
491  REQUIRE(
492  mock_cout.buffer().substr(21) ==
493  "accepted HEARTBEAT (#0) from 127.1 (v2.0) "
494  "source SOURCE dest DEST\n");
495  }
496  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
497  "any of the reachable addresses and favors the higher priority "
498  "(increasing priority) (without logging).")
499  {
500  MockCOut mock_cout;
501  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
502  {
503  std::vector<MAVAddress> addr =
504  {
505  MAVAddress("10.10"),
506  MAVAddress("172.16"),
507  MAVAddress("192.168")
508  };
509  return addr;
510  });
511  conn.send(heartbeat);
512  fakeit::Verify(Method(mock_queue, push)).Once();
513  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
514  {
515  return a != nullptr && *a == *heartbeat && b == 2;
516  })).Once();
517  REQUIRE(mock_cout.buffer().empty());
518  }
519  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
520  "any of the reachable addresses and favors the higher priority "
521  "(decreasing priority) (with logging).")
522  {
523  Logger::level(3);
524  MockCOut mock_cout;
525  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
526  {
527  std::vector<MAVAddress> addr =
528  {
529  MAVAddress("192.168"),
530  MAVAddress("172.16"),
531  MAVAddress("10.10")
532  };
533  return addr;
534  });
535  conn.send(heartbeat);
536  fakeit::Verify(Method(mock_queue, push)).Once();
537  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
538  {
539  return a != nullptr && *a == *heartbeat && b == 2;
540  })).Once();
541  REQUIRE(
542  mock_cout.buffer().substr(21) ==
543  "accepted HEARTBEAT (#0) from 127.1 (v2.0) "
544  "source SOURCE dest DEST\n");
545  }
546  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
547  "any of the reachable addresses and favors the higher priority "
548  "(decreasing priority) (without logging).")
549  {
550  MockCOut mock_cout;
551  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
552  {
553  std::vector<MAVAddress> addr =
554  {
555  MAVAddress("192.168"),
556  MAVAddress("172.16"),
557  MAVAddress("10.10")
558  };
559  return addr;
560  });
561  conn.send(heartbeat);
562  fakeit::Verify(Method(mock_queue, push)).Once();
563  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
564  {
565  return a != nullptr && *a == *heartbeat && b == 2;
566  })).Once();
567  REQUIRE(mock_cout.buffer().empty());
568  }
569  SECTION("Silently drops the packet if the filter rejects it for all "
570  "reachable addresses (with logging).")
571  {
572  Logger::level(3);
573  MockCOut mock_cout;
574  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
575  [&](auto & a, auto & b)
576  {
577  (void)a;
578  (void)b;
579  return std::pair<bool, int>(false, 0);
580  });
581  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
582  {
583  std::vector<MAVAddress> addr =
584  {
585  MAVAddress("10.10"),
586  MAVAddress("172.16"),
587  MAVAddress("192.168")
588  };
589  return addr;
590  });
591  conn.send(heartbeat);
592  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
593  REQUIRE(
594  mock_cout.buffer().substr(21) ==
595  "rejected HEARTBEAT (#0) from 127.1 (v2.0) "
596  "source SOURCE dest DEST\n");
597  }
598  SECTION("Silently drops the packet if the filter rejects it for all "
599  "reachable addresses (without logging).")
600  {
601  MockCOut mock_cout;
602  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
603  [&](auto & a, auto & b)
604  {
605  (void)a;
606  (void)b;
607  return std::pair<bool, int>(false, 0);
608  });
609  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
610  {
611  std::vector<MAVAddress> addr =
612  {
613  MAVAddress("10.10"),
614  MAVAddress("172.16"),
615  MAVAddress("192.168")
616  };
617  return addr;
618  });
619  conn.send(heartbeat);
620  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
621  REQUIRE(mock_cout.buffer().empty());
622  }
623  Logger::level(0);
624 }
625 
626 
627 TEST_CASE("Connection's 'send' method (with broadcast address 0.0).",
628  "[Connection]")
629 {
630  Logger::level(2);
631  // Mocked objects.
632  fakeit::Mock<Filter> mock_filter;
633  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
634  [&](auto & a, auto & b)
635  {
636  (void)a;
637 
638  if (b == MAVAddress("192.168"))
639  {
640  return std::pair<bool, int>(true, 2);
641  }
642 
643  if (b == MAVAddress("172.16"))
644  {
645  return std::pair<bool, int>(true, -3);
646  }
647 
648  return std::pair<bool, int>(false, 0);
649  });
650  fakeit::Mock<AddressPool<>> mock_pool;
651  fakeit::When(Method(mock_pool, contains)).AlwaysDo([](MAVAddress addr)
652  {
653  if (addr == MAVAddress("10.10"))
654  {
655  return true;
656  }
657 
658  if (addr == MAVAddress("172.16"))
659  {
660  return true;
661  }
662 
663  if (addr == MAVAddress("192.168"))
664  {
665  return true;
666  }
667 
668  return false;
669  });
670  fakeit::Mock<PacketQueue> mock_queue;
671  fakeit::Fake(Method(mock_queue, push));
672  auto filter = mock_shared(mock_filter);
673  auto pool = mock_unique(mock_pool);
674  auto queue = mock_unique(mock_queue);
675  // Packets for testing.
676  auto source_connection = std::make_shared<Connection>("SOURCE", filter);
677  auto mission_set_current =
678  std::make_shared<packet_v2::Packet>(to_vector(MissionSetCurrentV2()));
679  mission_set_current->connection(source_connection);
680  // Connection for testing.
681  Connection conn("DEST", filter, false, std::move(pool), std::move(queue));
682  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
683  "any of the reachable addresses and favors the higher priority "
684  "(increasing priority) (with logging).")
685  {
686  Logger::level(3);
687  MockCOut mock_cout;
688  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
689  {
690  std::vector<MAVAddress> addr =
691  {
692  MAVAddress("10.10"),
693  MAVAddress("172.16"),
694  MAVAddress("192.168")
695  };
696  return addr;
697  });
698  conn.send(mission_set_current);
699  fakeit::Verify(Method(mock_queue, push)).Once();
700  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
701  {
702  return a != nullptr && *a == *mission_set_current && b == 2;
703  })).Once();
704  REQUIRE(
705  mock_cout.buffer().substr(21) ==
706  "accepted MISSION_SET_CURRENT (#41) from 255.0 to 0.0 (v2.0) "
707  "source SOURCE dest DEST\n");
708  }
709  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
710  "any of the reachable addresses and favors the higher priority "
711  "(increasing priority) (without logging).")
712  {
713  MockCOut mock_cout;
714  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
715  {
716  std::vector<MAVAddress> addr =
717  {
718  MAVAddress("10.10"),
719  MAVAddress("172.16"),
720  MAVAddress("192.168")
721  };
722  return addr;
723  });
724  conn.send(mission_set_current);
725  fakeit::Verify(Method(mock_queue, push)).Once();
726  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
727  {
728  return a != nullptr && *a == *mission_set_current && b == 2;
729  })).Once();
730  REQUIRE(mock_cout.buffer().empty());
731  }
732  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
733  "any of the reachable addresses and favors the higher priority "
734  "(decreasing priority) (with logging).")
735  {
736  Logger::level(3);
737  MockCOut mock_cout;
738  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
739  {
740  std::vector<MAVAddress> addr =
741  {
742  MAVAddress("192.168"),
743  MAVAddress("172.16"),
744  MAVAddress("10.10")
745  };
746  return addr;
747  });
748  conn.send(mission_set_current);
749  fakeit::Verify(Method(mock_queue, push)).Once();
750  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
751  {
752  return a != nullptr && *a == *mission_set_current && b == 2;
753  })).Once();
754  REQUIRE(
755  mock_cout.buffer().substr(21) ==
756  "accepted MISSION_SET_CURRENT (#41) from 255.0 to 0.0 (v2.0) "
757  "source SOURCE dest DEST\n");
758  }
759  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
760  "any of the reachable addresses and favors the higher priority "
761  "(decreasing priority) (without logging).")
762  {
763  MockCOut mock_cout;
764  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
765  {
766  std::vector<MAVAddress> addr =
767  {
768  MAVAddress("192.168"),
769  MAVAddress("172.16"),
770  MAVAddress("10.10")
771  };
772  return addr;
773  });
774  conn.send(mission_set_current);
775  fakeit::Verify(Method(mock_queue, push)).Once();
776  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
777  {
778  return a != nullptr && *a == *mission_set_current && b == 2;
779  })).Once();
780  REQUIRE(mock_cout.buffer().empty());
781  }
782  SECTION("Silently drops the packet if the filter rejects it for all "
783  "reachable addresses (with logging).")
784  {
785  Logger::level(3);
786  MockCOut mock_cout;
787  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
788  [&](auto & a, auto & b)
789  {
790  (void)a;
791  (void)b;
792  return std::pair<bool, int>(false, 0);
793  });
794  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
795  {
796  std::vector<MAVAddress> addr =
797  {
798  MAVAddress("10.10"),
799  MAVAddress("192.168"),
800  MAVAddress("172.16")
801  };
802  return addr;
803  });
804  conn.send(mission_set_current);
805  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
806  REQUIRE(
807  mock_cout.buffer().substr(21) ==
808  "rejected MISSION_SET_CURRENT (#41) from 255.0 to 0.0 (v2.0) "
809  "source SOURCE dest DEST\n");
810  }
811  SECTION("Silently drops the packet if the filter rejects it for all "
812  "reachable addresses (without logging).")
813  {
814  MockCOut mock_cout;
815  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
816  [&](auto & a, auto & b)
817  {
818  (void)a;
819  (void)b;
820  return std::pair<bool, int>(false, 0);
821  });
822  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
823  {
824  std::vector<MAVAddress> addr =
825  {
826  MAVAddress("10.10"),
827  MAVAddress("192.168"),
828  MAVAddress("172.16")
829  };
830  return addr;
831  });
832  conn.send(mission_set_current);
833  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
834  REQUIRE(mock_cout.buffer().empty());
835  }
836  Logger::level(0);
837 }
838 
839 
840 TEST_CASE("Connection's 'send' method (with component broadcast address x.0).",
841  "[Connection]")
842 {
843  Logger::level(2);
844  // Mocked objects.
845  fakeit::Mock<Filter> mock_filter;
846  fakeit::Mock<AddressPool<>> mock_pool;
847  fakeit::When(Method(mock_pool, contains)).AlwaysDo([](MAVAddress addr)
848  {
849  if (addr == MAVAddress("10.10"))
850  {
851  return true;
852  }
853 
854  if (addr == MAVAddress("123.16"))
855  {
856  return true;
857  }
858 
859  if (addr == MAVAddress("123.17"))
860  {
861  return true;
862  }
863 
864  if (addr == MAVAddress("123.168"))
865  {
866  return true;
867  }
868 
869  return false;
870  });
871  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
872  [&](auto & a, auto & b)
873  {
874  (void)a;
875 
876  if (b == MAVAddress("123.168"))
877  {
878  return std::pair<bool, int>(true, 2);
879  }
880 
881  if (b == MAVAddress("123.16"))
882  {
883  return std::pair<bool, int>(true, -3);
884  }
885 
886  return std::pair<bool, int>(false, 0);
887  });
888  fakeit::Mock<PacketQueue> mock_queue;
889  fakeit::Fake(Method(mock_queue, push));
890  auto filter = mock_shared(mock_filter);
891  auto pool = mock_unique(mock_pool);
892  auto queue = mock_unique(mock_queue);
893  // Packets for testing.
894  auto set_mode = std::make_shared<packet_v2::Packet>(to_vector(SetModeV2()));
895  auto source_connection = std::make_shared<Connection>("SOURCE", filter);
896  set_mode->connection(source_connection);
897  // Connection for testing.
898  Connection conn("DEST", filter, false, std::move(pool), std::move(queue));
899  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
900  "any reachable component address of the given system address and "
901  "favors the higher priority (increasing priority) (with logging).")
902  {
903  Logger::level(3);
904  MockCOut mock_cout;
905  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
906  {
907  std::vector<MAVAddress> addr =
908  {
909  MAVAddress("10.10"),
910  MAVAddress("123.16"),
911  MAVAddress("123.17"),
912  MAVAddress("123.168")
913  };
914  return addr;
915  });
916  conn.send(set_mode);
917  fakeit::Verify(Method(mock_queue, push)).Once();
918  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
919  {
920  return a != nullptr && *a == *set_mode && b == 2;
921  })).Once();
922  REQUIRE(
923  mock_cout.buffer().substr(21) ==
924  "accepted SET_MODE (#11) from 172.0 to 123.0 (v2.0) "
925  "source SOURCE dest DEST\n");
926  }
927  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
928  "any reachable component address of the given system address and "
929  "favors the higher priority (increasing priority) "
930  "(without logging).")
931  {
932  MockCOut mock_cout;
933  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
934  {
935  std::vector<MAVAddress> addr =
936  {
937  MAVAddress("10.10"),
938  MAVAddress("123.16"),
939  MAVAddress("123.17"),
940  MAVAddress("123.168")
941  };
942  return addr;
943  });
944  conn.send(set_mode);
945  fakeit::Verify(Method(mock_queue, push)).Once();
946  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
947  {
948  return a != nullptr && *a == *set_mode && b == 2;
949  })).Once();
950  REQUIRE(mock_cout.buffer().empty());
951  }
952  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
953  "any reachable component address of the given system address and "
954  "favors the higher priority (decreasing priority) (with logging).")
955  {
956  Logger::level(3);
957  MockCOut mock_cout;
958  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
959  {
960  std::vector<MAVAddress> addr =
961  {
962  MAVAddress("123.168"),
963  MAVAddress("123.17"),
964  MAVAddress("123.16"),
965  MAVAddress("10.10")
966  };
967  return addr;
968  });
969  conn.send(set_mode);
970  fakeit::Verify(Method(mock_queue, push)).Once();
971  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
972  {
973  return a != nullptr && *a == *set_mode && b == 2;
974  })).Once();
975  REQUIRE(
976  mock_cout.buffer().substr(21) ==
977  "accepted SET_MODE (#11) from 172.0 to 123.0 (v2.0) "
978  "source SOURCE dest DEST\n");
979  }
980  SECTION("Adds the packet to the PacketQueue if the filter allows it for "
981  "any reachable component address of the given system address and "
982  "favors the higher priority (decreasing priority) "
983  "(without logging).")
984  {
985  MockCOut mock_cout;
986  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
987  {
988  std::vector<MAVAddress> addr =
989  {
990  MAVAddress("123.168"),
991  MAVAddress("123.17"),
992  MAVAddress("123.16"),
993  MAVAddress("10.10")
994  };
995  return addr;
996  });
997  conn.send(set_mode);
998  fakeit::Verify(Method(mock_queue, push)).Once();
999  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
1000  {
1001  return a != nullptr && *a == *set_mode && b == 2;
1002  })).Once();
1003  REQUIRE(mock_cout.buffer().empty());
1004  }
1005  SECTION("Silently drops the packet if the filter rejects it for all "
1006  "matching addresses (with logging).")
1007  {
1008  Logger::level(3);
1009  MockCOut mock_cout;
1010  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1011  [&](auto & a, auto & b)
1012  {
1013  (void)a;
1014  (void)b;
1015  return std::pair<bool, int>(false, 0);
1016  });
1017  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
1018  {
1019  std::vector<MAVAddress> addr =
1020  {
1021  MAVAddress("10.10"),
1022  MAVAddress("123.16"),
1023  MAVAddress("123.17"),
1024  MAVAddress("123.168")
1025  };
1026  return addr;
1027  });
1028  conn.send(set_mode);
1029  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1030  REQUIRE(
1031  mock_cout.buffer().substr(21) ==
1032  "rejected SET_MODE (#11) from 172.0 to 123.0 (v2.0) "
1033  "source SOURCE dest DEST\n");
1034  }
1035  SECTION("Silently drops the packet if the filter rejects it for all "
1036  "matching addresses (without logging).")
1037  {
1038  MockCOut mock_cout;
1039  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1040  [&](auto & a, auto & b)
1041  {
1042  (void)a;
1043  (void)b;
1044  return std::pair<bool, int>(false, 0);
1045  });
1046  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
1047  {
1048  std::vector<MAVAddress> addr =
1049  {
1050  MAVAddress("10.10"),
1051  MAVAddress("123.16"),
1052  MAVAddress("123.17"),
1053  MAVAddress("123.168")
1054  };
1055  return addr;
1056  });
1057  conn.send(set_mode);
1058  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1059  REQUIRE(mock_cout.buffer().empty());
1060  }
1061  SECTION("Silently drops the packet if the destination system cannot be "
1062  "reached on this connection (with logging).")
1063  {
1064  Logger::level(3);
1065  MockCOut mock_cout;
1066  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1067  [&](auto & a, auto & b)
1068  {
1069  (void)a;
1070  (void)b;
1071  return std::pair<bool, int>(true, 0);
1072  });
1073  fakeit::When(Method(mock_pool, addresses)).AlwaysReturn(
1074  std::vector<MAVAddress>());
1075  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
1076  {
1077  (void)a;
1078  return false;
1079  });
1080  conn.send(set_mode);
1081  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1082  REQUIRE(mock_cout.buffer().empty());
1083  }
1084  SECTION("Silently drops the packet if the destination system cannot be "
1085  "reached on this connection (without logging).")
1086  {
1087  MockCOut mock_cout;
1088  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1089  [&](auto & a, auto & b)
1090  {
1091  (void)a;
1092  (void)b;
1093  return std::pair<bool, int>(true, 0);
1094  });
1095  fakeit::When(Method(mock_pool, addresses)).AlwaysReturn(
1096  std::vector<MAVAddress>());
1097  fakeit::When(Method(mock_pool, contains)).AlwaysDo([&](auto & a)
1098  {
1099  (void)a;
1100  return false;
1101  });
1102  conn.send(set_mode);
1103  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1104  REQUIRE(mock_cout.buffer().empty());
1105  }
1106  Logger::level(0);
1107 }
1108 
1109 
1110 TEST_CASE("Connection's 'send' method (destination address, system reachable, "
1111  "component unreachable.", "[Connection]")
1112 {
1113  Logger::level(2);
1114  // Mocked objects.
1115  fakeit::Mock<Filter> mock_filter;
1116  fakeit::Mock<AddressPool<>> mock_pool;
1117  fakeit::When(Method(mock_pool, addresses)).AlwaysDo([]()
1118  {
1119  std::vector<MAVAddress> addr =
1120  {
1121  MAVAddress("10.10"),
1122  MAVAddress("127.16"),
1123  MAVAddress("127.17"),
1124  MAVAddress("127.168")
1125  };
1126  return addr;
1127  });
1128  fakeit::When(Method(mock_pool, contains)).AlwaysDo([](MAVAddress addr)
1129  {
1130  if (addr == MAVAddress("10.10"))
1131  {
1132  return true;
1133  }
1134 
1135  if (addr == MAVAddress("127.16"))
1136  {
1137  return true;
1138  }
1139 
1140  if (addr == MAVAddress("127.17"))
1141  {
1142  return true;
1143  }
1144 
1145  if (addr == MAVAddress("127.168"))
1146  {
1147  return true;
1148  }
1149 
1150  return false;
1151  });
1152  fakeit::Mock<PacketQueue> mock_queue;
1153  auto filter = mock_shared(mock_filter);
1154  auto pool = mock_unique(mock_pool);
1155  auto queue = mock_unique(mock_queue);
1156  // Packets for testing.
1157  auto ping = std::make_shared<packet_v2::Packet>(to_vector(PingV2()));
1158  auto source_connection = std::make_shared<Connection>("SOURCE", filter);
1159  ping->connection(source_connection);
1160  // Connection for testing.
1161  Connection conn("DEST", filter, false, std::move(pool), std::move(queue));
1162  SECTION("Adds the packet to the PacketQueue if any component of the "
1163  "system is reachable on the connection and the filter allows it "
1164  "to the original component (with logging).")
1165  {
1166  Logger::level(3);
1167  MockCOut mock_cout;
1168  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1169  [&](auto & a, auto & b)
1170  {
1171  (void)a;
1172 
1173  if (b == MAVAddress("127.1"))
1174  {
1175  return std::pair<bool, int>(true, 2);
1176  }
1177 
1178  return std::pair<bool, int>(false, 0);
1179  });
1180  fakeit::Fake(Method(mock_queue, push));
1181  conn.send(ping);
1182  fakeit::Verify(Method(mock_queue, push)).Once();
1183  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
1184  {
1185  return a != nullptr && *a == *ping && b == 2;
1186  })).Once();
1187  REQUIRE(
1188  mock_cout.buffer().substr(21) ==
1189  "accepted PING (#4) from 192.168 to 127.1 (v2.0) "
1190  "source SOURCE dest DEST\n");
1191  }
1192  SECTION("Adds the packet to the PacketQueue if any component of the "
1193  "system is reachable on the connection and the filter allows it "
1194  "to the original component (without logging).")
1195  {
1196  MockCOut mock_cout;
1197  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1198  [&](auto & a, auto & b)
1199  {
1200  (void)a;
1201 
1202  if (b == MAVAddress("127.1"))
1203  {
1204  return std::pair<bool, int>(true, 2);
1205  }
1206 
1207  return std::pair<bool, int>(false, 0);
1208  });
1209  fakeit::Fake(Method(mock_queue, push));
1210  conn.send(ping);
1211  fakeit::Verify(Method(mock_queue, push)).Once();
1212  fakeit::Verify(Method(mock_queue, push).Matching([&](auto a, auto b)
1213  {
1214  return a != nullptr && *a == *ping && b == 2;
1215  })).Once();
1216  REQUIRE(mock_cout.buffer().empty());
1217  }
1218  SECTION("Silently drops the packet if the filter rejects it (using "
1219  "it's original address) (with logging).")
1220  {
1221  Logger::level(3);
1222  MockCOut mock_cout;
1223  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1224  [&](auto & a, auto & b)
1225  {
1226  (void)a;
1227 
1228  if (b == MAVAddress("127.1"))
1229  {
1230  return std::pair<bool, int>(false, 0);
1231  }
1232 
1233  return std::pair<bool, int>(true, 2);
1234  });
1235  fakeit::Fake(Method(mock_queue, push));
1236  conn.send(ping);
1237  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1238  REQUIRE(
1239  mock_cout.buffer().substr(21) ==
1240  "rejected PING (#4) from 192.168 to 127.1 (v2.0) "
1241  "source SOURCE dest DEST\n");
1242  }
1243  SECTION("Silently drops the packet if the filter rejects it (using "
1244  "it's original address) (without logging).")
1245  {
1246  MockCOut mock_cout;
1247  fakeit::When(Method(mock_filter, will_accept)).AlwaysDo(
1248  [&](auto & a, auto & b)
1249  {
1250  (void)a;
1251 
1252  if (b == MAVAddress("127.1"))
1253  {
1254  return std::pair<bool, int>(false, 0);
1255  }
1256 
1257  return std::pair<bool, int>(true, 2);
1258  });
1259  fakeit::Fake(Method(mock_queue, push));
1260  conn.send(ping);
1261  fakeit::Verify(Method(mock_queue, push)).Exactly(0);
1262  REQUIRE(mock_cout.buffer().empty());
1263  }
1264  Logger::level(0);
1265 }
std::string str(const T &object)
Definition: utility.hpp:128
TEST_CASE("Connection's can be constructed.", "[Connection]")
static unsigned int level()
Definition: Logger.cpp:96
std::string buffer()
Definition: common.hpp:75
def heartbeat(mav)
Definition: logger.py:42
TEST_VIRTUAL std::shared_ptr< const Packet > next_packet(const std::chrono::nanoseconds &timeout=std::chrono::nanoseconds(0))
Definition: Connection.cpp:303
std::shared_ptr< T > mock_shared(fakeit::Mock< T > &mock)
Definition: common.hpp:33
auto ping
Definition: test_Call.cpp:229
TEST_VIRTUAL void add_address(MAVAddress address)
Definition: Connection.cpp:281
std::unique_ptr< T > mock_unique(fakeit::Mock< T > &mock)
Definition: common.hpp:46
TEST_VIRTUAL void send(std::shared_ptr< const Packet > packet)
Definition: Connection.cpp:327