mavtables  0.2.1
MAVLink router and firewall.
test_If.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 <stdexcept>
19 #include <utility>
20 
21 #include <catch.hpp>
22 #include <fakeit.hpp>
23 
24 #include "If.hpp"
25 #include "MAVAddress.hpp"
26 #include "MAVSubnet.hpp"
27 #include "Packet.hpp"
28 #include "utility.hpp"
29 
30 
31 using namespace fakeit;
32 
33 
34 TEST_CASE("If's are constructable.", "[If]")
35 {
36  SECTION("With the default constructor.")
37  {
38  REQUIRE_NOTHROW(If());
39  }
40  SECTION("With ID, source subnet, and destination subnet arguments.")
41  {
42  REQUIRE_NOTHROW(If({}, {}, {}));
43  // ID 4 is PING.
44  REQUIRE_NOTHROW(If(4, {}, {}));
45  REQUIRE_NOTHROW(If({}, MAVSubnet("192.0/8"), {}));
46  REQUIRE_NOTHROW(If({}, {}, MAVSubnet("192.0/8")));
47  REQUIRE_NOTHROW(If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
48  // ID 11 is SET_MODE.
49  REQUIRE_NOTHROW(If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
50  }
51  SECTION("ID as well as source and destination address are optional.")
52  {
53  REQUIRE_NOTHROW(If());
54  REQUIRE_NOTHROW(If(4));
55  REQUIRE_NOTHROW(If(11, MAVSubnet("192.0/8")));
56  }
57  SECTION("Ensures the packet ID is valid.")
58  {
59  // Currently, ID's 255 and 5000 are invalid.
60  REQUIRE_THROWS_AS(If(255), std::invalid_argument);
61  REQUIRE_THROWS_WITH(If(255), "Invalid packet ID (#255).");
62  REQUIRE_THROWS_AS(If(5000), std::invalid_argument);
63  REQUIRE_THROWS_WITH(If(5000), "Invalid packet ID (#5000).");
64  }
65 }
66 
67 
68 TEST_CASE("If's are comparable.", "[If]")
69 {
70  SECTION("with ==")
71  {
72  // This also tests the default arguments.
73  REQUIRE(If() == If());
74  REQUIRE(If({}, {}, {}) == If());
75  REQUIRE(If(4, {}, {}) == If(4));
76  REQUIRE(
77  If({}, MAVSubnet("192.0/8"), {}) ==
78  If({}, MAVSubnet("192.0/8")));
79  REQUIRE(
80  If({}, {}, MAVSubnet("192.0/8")) ==
81  If({}, {}, MAVSubnet("192.0/8")));
82  REQUIRE(
83  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) ==
84  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
85  REQUIRE(
86  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) ==
87  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
88  REQUIRE_FALSE(If(0, {}, {}) == If());
89  REQUIRE_FALSE(If(4, {}, {}) == If(0));
90  REQUIRE_FALSE(
91  If({}, MAVSubnet("192.0/8"), {}) ==
92  If({}, MAVSubnet("192.0/7")));
93  REQUIRE_FALSE(
94  If({}, {}, MAVSubnet("191.0/8")) ==
95  If({}, {}, MAVSubnet("192.0/8")));
96  REQUIRE_FALSE(
97  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) ==
98  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.1/8")));
99  REQUIRE_FALSE(
100  If(1, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) ==
101  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
102  }
103  SECTION("with !=")
104  {
105  // This also tests the default arguments.
106  REQUIRE(If(0, {}, {}) != If());
107  REQUIRE(If(4, {}, {}) != If(0));
108  REQUIRE(
109  If({}, MAVSubnet("192.0/8"), {}) !=
110  If({}, MAVSubnet("192.0/7")));
111  REQUIRE(
112  If({}, {}, MAVSubnet("191.0/8")) !=
113  If({}, {}, MAVSubnet("192.0/8")));
114  REQUIRE(
115  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) !=
116  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.1/8")));
117  REQUIRE(
118  If(1, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) !=
119  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
120  REQUIRE_FALSE(If() != If());
121  REQUIRE_FALSE(If({}, {}, {}) != If());
122  REQUIRE_FALSE(If(4, {}, {}) != If(4));
123  REQUIRE_FALSE(
124  If({}, MAVSubnet("192.0/8"), {}) !=
125  If({}, MAVSubnet("192.0/8")));
126  REQUIRE_FALSE(
127  If({}, {}, MAVSubnet("192.0/8")) !=
128  If({}, {}, MAVSubnet("192.0/8")));
129  REQUIRE_FALSE(
130  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) !=
131  If({}, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
132  REQUIRE_FALSE(
133  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")) !=
134  If(11, MAVSubnet("192.0/8"), MAVSubnet("168.0/8")));
135  }
136 }
137 
138 
139 TEST_CASE("If's are copyable.", "[If]")
140 {
141  If original(4, MAVSubnet("192.168"), MAVSubnet("172.16"));
142  If copy(original);
143  REQUIRE(copy == If(4, MAVSubnet("192.168"), MAVSubnet("172.16")));
144 }
145 
146 
147 TEST_CASE("If's are movable.", "[If]")
148 {
149  If original(4, MAVSubnet("192.168"), MAVSubnet("172.16"));
150  If moved(std::move(original));
151  REQUIRE(moved == If(4, MAVSubnet("192.168"), MAVSubnet("172.16")));
152 }
153 
154 
155 TEST_CASE("If's are assignable.", "[If]")
156 {
157  If if_a(4, {}, MAVSubnet("255.255"));
158  If if_b(11, MAVSubnet("255.255"), {});
159  REQUIRE(if_a == If(4, {}, MAVSubnet("255.255")));
160  if_a = if_b;
161  REQUIRE(if_a == If(11, MAVSubnet("255.255"), {}));
162 }
163 
164 
165 TEST_CASE("If's are assignable (by move semantics.)", "[If]")
166 {
167  If if_a(4, {}, MAVSubnet("255.255"));
168  If if_b(11, MAVSubnet("255.255"), {});
169  REQUIRE(if_a == If(4, {}, MAVSubnet("255.255")));
170  if_a = std::move(if_b);
171  REQUIRE(if_a == If(11, MAVSubnet("255.255"), {}));
172 }
173 
174 
175 TEST_CASE("If's 'check' method determines if a packet and destination"
176  "address matches the conditional.", "[If]")
177 {
178  Mock<Packet> mock;
179  When(Method(mock, id)).AlwaysReturn(4);
180  When(Method(mock, source)).AlwaysReturn(MAVAddress("192.168"));
181  Packet &packet = mock.get();
182  MAVAddress address("172.16");
183  SECTION("Default all matching case.")
184  {
185  REQUIRE(If().check(packet, address));
186  }
187  SECTION("Based on packet ID only.")
188  {
189  REQUIRE_FALSE(If(1).check(packet, address));
190  REQUIRE(If(4).check(packet, address));
191  REQUIRE_FALSE(If(321).check(packet, address));
192  }
193  SECTION("Based on source subnet only.")
194  {
195  REQUIRE(If({}, MAVSubnet("192.168")).check(packet, address));
196  REQUIRE_FALSE(If({}, MAVSubnet("193.168")).check(packet, address));
197  REQUIRE(If({}, MAVSubnet("192.0/8")).check(packet, address));
198  REQUIRE_FALSE(If({}, MAVSubnet("193.0/8")).check(packet, address));
199  }
200  SECTION("Based on destination subnet only.")
201  {
202  REQUIRE(If({}, {}, MAVSubnet("172.16")).check(packet, address));
203  REQUIRE_FALSE(If({}, {}, MAVSubnet("171.16")).check(packet, address));
204  REQUIRE(If({}, {}, MAVSubnet("172.16/8")).check(packet, address));
205  REQUIRE_FALSE(If({}, {}, MAVSubnet("171.16/8")).check(packet, address));
206  }
207  SECTION("Based on packet ID and source subnet only.")
208  {
209  REQUIRE(If(4, MAVSubnet("192.168")).check(packet, address));
210  REQUIRE_FALSE(If(11, MAVSubnet("192.168")).check(packet, address));
211  REQUIRE_FALSE(If(4, MAVSubnet("193.168")).check(packet, address));
212  REQUIRE_FALSE(If(11, MAVSubnet("193.168")).check(packet, address));
213  REQUIRE(If(4, MAVSubnet("192.0/8")).check(packet, address));
214  REQUIRE_FALSE(If(11, MAVSubnet("192.0/8")).check(packet, address));
215  REQUIRE_FALSE(If(4, MAVSubnet("193.0/8")).check(packet, address));
216  REQUIRE_FALSE(If(11, MAVSubnet("193.0/8")).check(packet, address));
217  }
218  SECTION("Based on packet ID and destination subnet only.")
219  {
220  REQUIRE(If(4, {}, MAVSubnet("172.16")).check(packet, address));
221  REQUIRE_FALSE(If(11, {}, MAVSubnet("172.16")).check(packet, address));
222  REQUIRE_FALSE(If(4, {}, MAVSubnet("171.16")).check(packet, address));
223  REQUIRE_FALSE(If(11, {}, MAVSubnet("171.16")).check(packet, address));
224  REQUIRE(If(4, {}, MAVSubnet("172.16/8")).check(packet, address));
225  REQUIRE_FALSE(If(11, {}, MAVSubnet("172.16/8")).check(packet, address));
226  REQUIRE_FALSE(If(4, {}, MAVSubnet("171.16/8")).check(packet, address));
227  REQUIRE_FALSE(If(11, {}, MAVSubnet("171.16/8")).check(packet, address));
228  }
229  SECTION("Based on packet ID, source subnet, and destination subnet.")
230  {
231  REQUIRE(
232  If(4, MAVSubnet("192.168"), MAVSubnet("172.16")).check(
233  packet, address));
234  REQUIRE_FALSE(
235  If(11, MAVSubnet("192.168"), MAVSubnet("172.16")).check(
236  packet, address));
237  REQUIRE_FALSE(
238  If(4, MAVSubnet("193.168"), MAVSubnet("172.16")).check(
239  packet, address));
240  REQUIRE_FALSE(
241  If(11, MAVSubnet("193.168"), MAVSubnet("172.16")).check(
242  packet, address));
243  REQUIRE_FALSE(
244  If(4, MAVSubnet("192.168"), MAVSubnet("171.16")).check(
245  packet, address));
246  REQUIRE_FALSE(
247  If(11, MAVSubnet("192.168"), MAVSubnet("171.16")).check(
248  packet, address));
249  REQUIRE_FALSE(
250  If(4, MAVSubnet("193.168"), MAVSubnet("171.16")).check(
251  packet, address));
252  REQUIRE_FALSE(
253  If(11, MAVSubnet("193.168"), MAVSubnet("171.16")).check(
254  packet, address));
255  }
256 }
257 
258 
259 TEST_CASE("If's 'type' method sets the packet ID for matching.",
260  "[If]")
261 {
262  Mock<Packet> mock;
263  When(Method(mock, id)).AlwaysReturn(4);
264  When(Method(mock, source)).AlwaysReturn(MAVAddress("192.168"));
265  Packet &packet = mock.get();
266  MAVAddress address("172.16");
267  SECTION("When given a numeric ID.")
268  {
269  REQUIRE_FALSE(If().type(0).check(packet, address));
270  REQUIRE(If().type(4).check(packet, address));
271  REQUIRE_FALSE(If().type(11).check(packet, address));
272  }
273  SECTION("And ensures the numeric ID is valid.")
274  {
275  // Note: ID's 255 and 5000 are not currently valid.
276  REQUIRE_THROWS_AS(If().type(255), std::invalid_argument);
277  REQUIRE_THROWS_WITH(
278  If().type(255), "Invalid packet ID (#255).");
279  REQUIRE_THROWS_AS(If().type(5000), std::invalid_argument);
280  REQUIRE_THROWS_WITH(
281  If().type(5000), "Invalid packet ID (#5000).");
282  }
283  SECTION("When given a packet name.")
284  {
285  REQUIRE_FALSE(If().type("HEARTBEAT").check(packet, address));
286  REQUIRE(If().type("PING").check(packet, address));
287  REQUIRE_FALSE(If().type("SET_MODE").check(packet, address));
288  }
289  SECTION("And ensures the packet name is valid.")
290  {
291  REQUIRE_THROWS_AS(
292  If().type("CRAZY_PACKET_NAME"), std::invalid_argument);
293  REQUIRE_THROWS_WITH(
294  If().type("CRAZY_PACKET_NAME"),
295  "Invalid packet name (\"CRAZY_PACKET_NAME\").");
296  }
297 }
298 
299 
300 TEST_CASE("If's 'from' method sets the source subnet to match.",
301  "[If]")
302 {
303  Mock<Packet> mock;
304  When(Method(mock, id)).AlwaysReturn(4);
305  When(Method(mock, source)).AlwaysReturn(MAVAddress("192.168"));
306  Packet &packet = mock.get();
307  MAVAddress address("172.16");
308  SECTION("When a MAVSubnet object is given.")
309  {
310  REQUIRE(If().from(MAVSubnet("192.168")).check(packet, address));
311  REQUIRE_FALSE(If().from(MAVSubnet("193.168")).check(packet, address));
312  REQUIRE(If().from(MAVSubnet("192.0/8")).check(packet, address));
313  REQUIRE_FALSE(If().from(MAVSubnet("193.0/8")).check(packet, address));
314  }
315  SECTION("When a string is given.")
316  {
317  REQUIRE(If().from("192.168").check(packet, address));
318  REQUIRE_FALSE(If().from("193.168").check(packet, address));
319  REQUIRE(If().from("192.0/8").check(packet, address));
320  REQUIRE_FALSE(If().from("193.0/8").check(packet, address));
321  }
322 }
323 
324 
325 TEST_CASE("If's 'to' method sets the source subnet to match.",
326  "[If]")
327 {
328  Mock<Packet> mock;
329  When(Method(mock, id)).AlwaysReturn(4);
330  When(Method(mock, source)).AlwaysReturn(MAVAddress("192.168"));
331  Packet &packet = mock.get();
332  MAVAddress address("172.16");
333  SECTION("When a MAVSubnet object is given.")
334  {
335  REQUIRE(If().to(MAVSubnet("172.16")).check(packet, address));
336  REQUIRE_FALSE(If().to(MAVSubnet("171.16")).check(packet, address));
337  REQUIRE(If().to(MAVSubnet("172.16/8")).check(packet, address));
338  REQUIRE_FALSE(If().to(MAVSubnet("171.16/8")).check(packet, address));
339  }
340  SECTION("When a string is given.")
341  {
342  REQUIRE(If().to("172.16").check(packet, address));
343  REQUIRE_FALSE(If().to("171.16").check(packet, address));
344  REQUIRE(If().to("172.16/8").check(packet, address));
345  REQUIRE_FALSE(If().to("171.16/8").check(packet, address));
346  }
347 }
348 
349 
350 TEST_CASE("If's are printable.", "[If]")
351 {
352  REQUIRE(str(If()) == "if any");
353  REQUIRE(str(If().type("HEARTBEAT")) == "if HEARTBEAT");
354  REQUIRE(str(If().type("PING")) == "if PING");
355  REQUIRE(str(If().type("SET_MODE")) == "if SET_MODE");
356  REQUIRE(str(If().from("192.168")) == "if from 192.168");
357  REQUIRE(str(If().from("192.0/8")) == "if from 192.0/8");
358  REQUIRE(str(If().to("172.16")) == "if to 172.16");
359  REQUIRE(str(If().to("172.0/8")) == "if to 172.0/8");
360  REQUIRE(
361  str(If().type("PING").from("192.168")) == "if PING from 192.168");
362  REQUIRE(
363  str(If().type("PING").to("172.16")) == "if PING to 172.16");
364  REQUIRE(
365  str(If().from("192.168").to("172.16")) == "if from 192.168 to 172.16");
366  REQUIRE(
367  str(If().type("PING").from("192.168").to("172.16")) ==
368  "if PING from 192.168 to 172.16");
369 }
std::string str(const T &object)
Definition: utility.hpp:128
If if_b(11, MAVSubnet("255.255"), {})
Definition: If.hpp:35
if_a
Definition: test_If.cpp:170
TEST_CASE("If's are constructable.", "[If]")
Definition: test_If.cpp:34