mavtables  0.2.1
MAVLink router and firewall.
test_UDPSocket.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 <algorithm>
19 #include <chrono>
20 #include <iterator>
21 #include <optional>
22 #include <utility>
23 
24 #include <catch.hpp>
25 #include <fakeit.hpp>
26 
27 #include "IPAddress.hpp"
28 #include "UDPSocket.hpp"
29 #include <utility.hpp>
30 
31 
32 using namespace std::chrono_literals;
33 
34 
35 TEST_CASE("UDPSocket's 'send' method accepts a vector of bytes and an address.",
36  "[UDPSocket]")
37 {
38  // This test ensures that one send method calls the other.
39  UDPSocket udp;
40  fakeit::Mock<UDPSocket> mock_socket(udp);
41  fakeit::Fake(
42  OverloadedMethod(
43  mock_socket, send,
44  void(std::vector<uint8_t>::const_iterator,
45  std::vector<uint8_t>::const_iterator,
46  const IPAddress & address)));
47  UDPSocket &socket = mock_socket.get();
48  std::vector<uint8_t> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
49  IPAddress addr("192.168.0.0");
50  socket.send(vec, addr);
51  fakeit::Verify(
52  OverloadedMethod(
53  mock_socket, send,
54  void(std::vector<uint8_t>::const_iterator,
55  std::vector<uint8_t>::const_iterator,
56  const IPAddress & address)).Matching(
57  [&](auto a, auto b, auto c)
58  {
59  return a == vec.begin() && b == vec.end() && c == addr;
60  })).Once();
61 }
62 
63 
64 TEST_CASE("UDPSocket's 'send' method accepts two vector iterators and an "
65  "address.", "[UDPSocket]")
66 {
67  // This test ensures that one send method calls the other.
68  UDPSocket udp;
69  fakeit::Mock<UDPSocket> mock_socket(udp);
70  std::vector<uint8_t> send_vec;
71  fakeit::When(
72  OverloadedMethod(
73  mock_socket, send,
74  void(const std::vector<uint8_t> &, const IPAddress &))).AlwaysDo(
75  [&](auto a, auto b)
76  {
77  (void)b;
78  send_vec = a;
79  });
80  UDPSocket &socket = mock_socket.get();
81  std::vector<uint8_t> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
82  IPAddress addr("192.168.0.0");
83  socket.send(vec.begin(), vec.end(), addr);
84  fakeit::Verify(
85  OverloadedMethod(
86  mock_socket, send,
87  void(const std::vector<uint8_t> &, const IPAddress &))).Once();
88  REQUIRE(vec == send_vec);
89 }
90 
91 
92 TEST_CASE("UDPSocket's 'receive' method takes a timeout and returns a vector "
93  "of bytes and the IP address that sent them.", "[UDPSocket]")
94 {
95  // This test ensures that one receive method calls the other.
96  UDPSocket udp;
97  fakeit::Mock<UDPSocket> mock_socket(udp);
98  fakeit::When(
99  OverloadedMethod(
100  mock_socket, receive,
101  IPAddress(std::back_insert_iterator<std::vector<uint8_t>>,
102  const std::chrono::nanoseconds &))).AlwaysDo(
103  [](auto a, auto b)
104  {
105  (void)b;
106  std::vector<uint8_t> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
107  std::copy(vec.begin(), vec.end(), a);
108  return IPAddress("192.168.0.0");
109  });
110  UDPSocket &socket = mock_socket.get();
111  std::vector<uint8_t> vec_compare = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
112  std::chrono::nanoseconds timeout = 1ms;
113  auto [data, addr] = socket.receive(timeout);
114  REQUIRE(data == vec_compare);
115  REQUIRE(addr == IPAddress("192.168.0.0"));
116  fakeit::Verify(
117  OverloadedMethod(
118  mock_socket, receive,
119  IPAddress(std::back_insert_iterator<std::vector<uint8_t>>,
120  const std::chrono::nanoseconds &)).Matching(
121  [](auto a, auto b)
122  {
123  (void)a;
124  return b == 1ms;
125  })).Once();
126 }
127 
128 
129 TEST_CASE("UDPSocket's 'receive' method takes a back inserter and a timeout "
130  "and returns the IP address that sent the bytes written to the "
131  "back inserter.", "[UDPSocket]")
132 {
133  // This test ensures that one receive method calls the other.
134  using receive_type = std::pair<std::vector<uint8_t>, IPAddress>(
135  const std::chrono::nanoseconds &);
136  UDPSocket udp;
137  fakeit::Mock<UDPSocket> mock_socket(udp);
138  fakeit::When(
139  OverloadedMethod(
140  mock_socket, receive, receive_type)).AlwaysDo([](auto a)
141  {
142  (void)a;
143  std::vector<uint8_t> vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
144  return std::pair<std::vector<uint8_t>, IPAddress>(
145  vec, IPAddress("192.168.0.0"));
146  });
147  UDPSocket &socket = mock_socket.get();
148  std::vector<uint8_t> vec_compare = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
149  std::chrono::nanoseconds timeout = 1ms;
150  std::vector<uint8_t> data;
151  auto addr = socket.receive(std::back_inserter(data), timeout);
152  REQUIRE(data == vec_compare);
153  REQUIRE(addr == IPAddress("192.168.0.0"));
154  fakeit::Verify(
155  OverloadedMethod(
156  mock_socket, receive, receive_type).Matching([](auto a)
157  {
158  return a == 1ms;
159  })).Once();
160 }
161 
162 
163 TEST_CASE("UDPSocket's are printable.", "UDPSocket")
164 {
165  REQUIRE(str(UDPSocket()) == "unknown UDP socket");
166 }
std::string str(const T &object)
Definition: utility.hpp:128
virtual std::pair< std::vector< uint8_t >, IPAddress > receive(const std::chrono::nanoseconds &timeout=std::chrono::nanoseconds::zero())
Definition: UDPSocket.cpp:77
virtual void send(const std::vector< uint8_t > &data, const IPAddress &address)
Definition: UDPSocket.cpp:43
TEST_CASE("UDPSocket's 'send' method accepts a vector of bytes and an address.", "[UDPSocket]")