KENSv3
KAIST Educational Network System
testenv.hpp
1 /*
2  * testenv.hpp
3  *
4  * Created on: Mar 7, 2015
5  * Author: leeopop
6  */
7 
8 #ifndef APP_TESTTCP_TESTENV_HPP_
9 #define APP_TESTTCP_TESTENV_HPP_
10 
11 #include <E/E_Common.hpp>
12 #include <E/E_Module.hpp>
13 #include <E/E_TimeUtil.hpp>
14 #include <E/Networking/E_Host.hpp>
15 #include <E/Networking/E_Hub.hpp>
17 #include <E/Networking/E_Switch.hpp>
18 #include <E/Networking/E_Wire.hpp>
19 #include <E/Networking/Ethernet/E_Ethernet.hpp>
20 #include <E/Networking/IPv4/E_IPv4.hpp>
21 #include <E/Networking/TCP/E_TCPApplication.hpp>
22 #include <E/Networking/TCP/E_TCPSolution.hpp>
23 
24 #include "TCPAssignment.hpp"
25 #include <gtest/gtest.h>
26 
27 #define RANDOM_SEED_DEFAULT 1614233283
28 
29 using namespace E;
30 
31 class KensTesting : public ::testing::Test {
32 protected:
33  void setup_env() {
34 
35 #ifdef RUN_SOLUTION
36  const bool run_solution = true;
37 #else
38  const bool run_solution = false;
39 #endif
40 
41 #ifdef UNRELIABLE
42  const bool unreliable = true;
43 #else
44  const bool unreliable = false;
45 #endif
46 
47  int seed = RANDOM_SEED_DEFAULT;
48 
49  const char *random_seed = std::getenv("RANDOM_SEED");
50  if (random_seed) {
51  seed = atoi(random_seed);
52  }
53  srand(seed);
54  RecordProperty("random_seed", seed);
55  RecordProperty("run_solution", run_solution);
56  RecordProperty("unreliable", unreliable);
57  printf("[RANDOM_SEED : %d RUN_SOLUTION : %d UNRELIABLE : %d]\n", seed,
58  run_solution, unreliable);
59  }
60 };
61 
62 template <class Target> class TestEnv1 : public KensTesting {
63 protected:
64  NetworkSystem netSystem;
65  std::shared_ptr<Host> host1;
66  std::shared_ptr<Host> host2;
67  std::shared_ptr<Switch> switchingHub;
68 
69  virtual void SetUp() {
70  setup_env();
71 
72  host1 = netSystem.addModule<Host>("TestHost1", netSystem);
73  host2 = netSystem.addModule<Host>("TestHost2", netSystem);
74  switchingHub = netSystem.addModule<Switch>("Switch1", netSystem);
75 
76  auto host1_port_1 = netSystem
77  .addWire(*host1, *switchingHub,
78  TimeUtil::makeTime(1, TimeUtil::MSEC))
79  .second;
80  auto host1_port_2 = netSystem
81  .addWire(*host1, *switchingHub,
82  TimeUtil::makeTime(1, TimeUtil::MSEC))
83  .second;
84  auto host2_port_1 = netSystem
85  .addWire(*host2, *switchingHub,
86  TimeUtil::makeTime(1, TimeUtil::MSEC))
87  .second;
88  auto host2_port_2 = netSystem
89  .addWire(*host2, *switchingHub,
90  TimeUtil::makeTime(1, TimeUtil::MSEC))
91  .second;
92 
93  mac_t mac1{0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC};
94  mac_t mac1_2{0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB};
95  mac_t mac2{0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD};
96  mac_t mac2_2{0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC};
97  ipv4_t ip1{192, 168, 0, 7};
98  ipv4_t ip1_2{192, 168, 0, 8};
99  ipv4_t ip2{10, 0, 1, 4};
100  ipv4_t ip2_2{10, 0, 1, 5};
101  host1->setMACAddr(mac1, host1_port_1.first);
102  host1->setMACAddr(mac1_2, host1_port_2.first);
103  host1->setARPTable(mac2, ip2);
104  host1->setARPTable(mac2_2, ip2_2);
105  host1->setIPAddr(ip1, host1_port_1.first);
106  host1->setIPAddr(ip1_2, host1_port_2.first);
107  host1->setRoutingTable(ip2, 16, host1_port_1.first);
108  host1->setRoutingTable(ip2_2, 16, host1_port_2.first);
109 
110  host2->setMACAddr(mac2, host2_port_1.first);
111  host2->setMACAddr(mac2_2, host2_port_2.first);
112  host2->setARPTable(mac1, ip1);
113  host2->setARPTable(mac1_2, ip1_2);
114  host2->setIPAddr(ip2, host2_port_1.first);
115  host2->setIPAddr(ip2_2, host2_port_2.first);
116  host2->setRoutingTable(ip1, 16, host2_port_1.first);
117  host2->setRoutingTable(ip1_2, 16, host2_port_2.first);
118 
119  switchingHub->addMACEntry(host1_port_1.second, mac1);
120  switchingHub->addMACEntry(host1_port_2.second, mac1_2);
121  switchingHub->addMACEntry(host2_port_1.second, mac2);
122  switchingHub->addMACEntry(host2_port_2.second, mac2_2);
123 
124  const ::testing::TestInfo *const test_info =
125  ::testing::UnitTest::GetInstance()->current_test_info();
126  std::string file_name(test_info->name());
127  file_name.append(".pcap");
128  switchingHub->enablePCAPLogging(file_name);
129 
130  host1->addHostModule<Ethernet>(*host1);
131  host2->addHostModule<Ethernet>(*host2);
132 
133  host1->addHostModule<IPv4>(*host1);
134  host2->addHostModule<IPv4>(*host2);
135 
136  Target::allocate(*host1);
137  TCPSolutionProvider::allocate(*host2, false, false, false);
138 
139  host1->initializeHostModule("TCP");
140  host2->initializeHostModule("TCP");
141  }
142  virtual void TearDown() {}
143 
144  void runTest() {
145  netSystem.run(TimeUtil::makeTime(1000, TimeUtil::SEC));
146 
147  host1->cleanUp();
148  host2->cleanUp();
149  host1->finalizeHostModule("TCP");
150  host2->finalizeHostModule("TCP");
151  netSystem.run(TimeUtil::makeTime(2000, TimeUtil::SEC));
152  }
153 };
154 
155 template <class Target, class Adversary, bool Unreliable>
156 class TestEnv2 : public KensTesting {
157 protected:
158  NetworkSystem netSystem;
159  std::shared_ptr<Host> host1;
160  std::shared_ptr<Host> host2;
161  std::shared_ptr<Switch> switchingHub;
162 
163  virtual void SetUp() {
164  setup_env();
165 
166  host1 = netSystem.addModule<Host>("TestHost1", netSystem);
167  host2 = netSystem.addModule<Host>("TestHost2", netSystem);
168  switchingHub =
169  netSystem.addModule<Switch>("Switch1", netSystem, Unreliable);
170 
171  auto host1_port_1 = netSystem
172  .addWire(*host1, *switchingHub,
173  TimeUtil::makeTime(1, TimeUtil::MSEC))
174  .second;
175  auto host1_port_2 = netSystem
176  .addWire(*host1, *switchingHub,
177  TimeUtil::makeTime(1, TimeUtil::MSEC))
178  .second;
179  auto host2_port_1 = netSystem
180  .addWire(*host2, *switchingHub,
181  TimeUtil::makeTime(1, TimeUtil::MSEC))
182  .second;
183  auto host2_port_2 = netSystem
184  .addWire(*host2, *switchingHub,
185  TimeUtil::makeTime(1, TimeUtil::MSEC))
186  .second;
187 
188  mac_t mac1{0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC};
189  mac_t mac1_2{0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB};
190  mac_t mac2{0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD};
191  mac_t mac2_2{0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC};
192  ipv4_t ip1{192, 168, 0, 7};
193  ipv4_t ip1_2{192, 168, 0, 8};
194  ipv4_t ip2{10, 0, 1, 4};
195  ipv4_t ip2_2{10, 0, 1, 5};
196 
197  host1->setMACAddr(mac1, host1_port_1.first);
198  host1->setMACAddr(mac1_2, host1_port_2.first);
199  host1->setARPTable(mac2, ip2);
200  host1->setARPTable(mac2_2, ip2_2);
201  host1->setIPAddr(ip1, host1_port_1.first);
202  host1->setIPAddr(ip1_2, host1_port_2.first);
203  host1->setRoutingTable(ip2, 16, host1_port_1.first);
204  host1->setRoutingTable(ip2_2, 16, host1_port_2.first);
205 
206  host2->setMACAddr(mac2, host2_port_1.first);
207  host2->setMACAddr(mac2_2, host2_port_2.first);
208  host2->setARPTable(mac1, ip1);
209  host2->setARPTable(mac1_2, ip1_2);
210  host2->setIPAddr(ip2, host2_port_1.first);
211  host2->setIPAddr(ip2_2, host2_port_2.first);
212  host2->setRoutingTable(ip1, 16, host2_port_1.first);
213  host2->setRoutingTable(ip1_2, 16, host2_port_2.first);
214 
215  switchingHub->setQueueSize(16);
216 
217  switchingHub->addMACEntry(host1_port_1.second, mac1);
218  switchingHub->addMACEntry(host1_port_2.second, mac1_2);
219  switchingHub->addMACEntry(host2_port_1.second, mac2);
220  switchingHub->addMACEntry(host2_port_2.second, mac2_2);
221 
222  const ::testing::TestInfo *const test_info =
223  ::testing::UnitTest::GetInstance()->current_test_info();
224  std::string file_name(test_info->name());
225  file_name.append(".pcap");
226  switchingHub->enablePCAPLogging(file_name);
227 
228  host1->addHostModule<Ethernet>(*host1);
229  host2->addHostModule<Ethernet>(*host2);
230  host1->addHostModule<IPv4>(*host1);
231  host2->addHostModule<IPv4>(*host2);
232 
233  Target::allocate(*host1);
234  Adversary::allocate(*host2);
235 
236  host1->initializeHostModule("TCP");
237  host2->initializeHostModule("TCP");
238  }
239  virtual void TearDown() {}
240 
241  void runTest() {
242  netSystem.run(TimeUtil::makeTime(1000, TimeUtil::SEC));
243 
244  host1->cleanUp();
245  host2->cleanUp();
246  host1->finalizeHostModule("TCP");
247  host2->finalizeHostModule("TCP");
248  netSystem.run(TimeUtil::makeTime(2000, TimeUtil::SEC));
249  }
250 };
251 
252 template <class Target, class Adversary, int CLIENTS, int TIMEOUT>
253 class TestEnv3 : public KensTesting {
254 protected:
255  NetworkSystem netSystem;
256  std::shared_ptr<Host> server_host;
257  std::array<std::shared_ptr<Host>, CLIENTS> client_hosts;
258  std::shared_ptr<Switch> switchingHub;
259 
260  static constexpr int num_client = CLIENTS;
261  Size port_speed = 10000000;
262  Time propagationDelay = TimeUtil::makeTime(10, TimeUtil::MSEC);
263  uint64_t prev_log;
264 
265  virtual void SetUp() {
266 
267  setup_env();
268 
269  prev_log = NetworkLog::defaultLevel;
271  //(1 << NetworkLog::SYSCALL_RAISED) |
272  //(1 << NetworkLog::SYSCALL_FINISHED) |
273  //(1 << NetworkLog::PACKET_ALLOC) |
274  //(1 << NetworkLog::PACKET_CLONE) |
275  //(1 << NetworkLog::PACKET_FREE) |
276  //(1 << NetworkLog::PACKET_TO_MODULE) |
277  //(1 << NetworkLog::PACKET_FROM_MODULE) |
278  //(1 << NetworkLog::PACKET_TO_HOST) |
279  //(1 << NetworkLog::PACKET_FROM_HOST) |
280  //(1 << NetworkLog::PACKET_QUEUE) |
281  //(1 << NetworkLog::TCP_LOG) |
282  0UL);
283 
284  server_host = netSystem.addModule<Host>("CongestionServer", netSystem);
285  switchingHub = netSystem.addModule<Switch>("Switch1", netSystem);
286  auto server_port =
287  netSystem
288  .addWire(*server_host, *switchingHub, propagationDelay, port_speed)
289  .second;
290 
291  mac_t server_mac{0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC};
292  ipv4_t server_ip{192, 168, 1, 7};
293  ipv4_t server_mask{192, 168, 1, 0};
294  ipv4_t client_mask{10, 0, 1, 0};
295 
296  server_host->addHostModule<Ethernet>(*server_host);
297  server_host->addHostModule<IPv4>(*server_host);
298 
299  server_host->setMACAddr(server_mac, server_port.first);
300  server_host->setIPAddr(server_ip, server_port.first);
301  server_host->setRoutingTable(client_mask, 24, server_port.first);
302 
303  Adversary::allocate(*server_host);
304  server_host->initializeHostModule("TCP");
305 
306  switchingHub->addMACEntry(server_port.second, server_mac);
307 
308  char name_buf[128];
309  for (int k = 0; k < num_client; k++) {
310  snprintf(name_buf, sizeof(name_buf), "CongestionClient%d", k);
311  client_hosts[k] = netSystem.addModule<Host>(name_buf, netSystem);
312  auto client_port = netSystem
313  .addWire(*client_hosts[k], *switchingHub,
314  propagationDelay, port_speed)
315  .second;
316  Host &client_host = *client_hosts[k];
317  client_host.addHostModule<Ethernet>(client_host);
318  client_host.addHostModule<IPv4>(client_host);
319  Target::allocate(client_host);
320  client_host.initializeHostModule("TCP");
321 
322  ipv4_t client_ip{10, 0, 1, 10};
323  client_ip[3] += k;
324  mac_t client_mac{0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0x00};
325  client_mac[5] += k;
326 
327  client_host.setMACAddr(client_mac, client_port.first);
328  client_host.setIPAddr(client_ip, client_port.first);
329  client_host.setRoutingTable(server_mask, 24, client_port.first);
330  client_host.setARPTable(server_mac, server_ip);
331 
332  server_host->setARPTable(client_mac, client_ip);
333  switchingHub->addMACEntry(client_port.second, client_mac);
334  }
335 
336  switchingHub->setLinkSpeed(port_speed);
337  switchingHub->setQueueSize(64);
338 
339  const ::testing::TestInfo *const test_info =
340  ::testing::UnitTest::GetInstance()->current_test_info();
341  std::string file_name(test_info->name());
342  file_name.append(".pcap");
343  switchingHub->enablePCAPLogging(file_name, 64);
344  }
345  virtual void TearDown() { NetworkLog::defaultLevel = prev_log; }
346 
347  void runTest() {
348  netSystem.run(TimeUtil::makeTime(TIMEOUT, TimeUtil::SEC));
349 
350  server_host->cleanUp();
351  for (int k = 0; k < num_client; k++)
352  client_hosts[k]->cleanUp();
353 
354  server_host->finalizeHostModule("TCP");
355  for (int k = 0; k < num_client; k++)
356  client_hosts[k]->finalizeHostModule("TCP");
357  netSystem.run(TimeUtil::makeTime(1000 + TIMEOUT, TimeUtil::SEC));
358  }
359 };
360 
361 // #define UNRELIABLE
362 // #define RUN_SOLUTION
363 #ifdef RUN_SOLUTION
365 #ifdef UNRELIABLE
367 #else
369 #endif
378 #else
380 #ifdef UNRELIABLE
382 #else
384 #endif
393 #endif
394 
395 #endif /* APP_TESTTCP_TESTENV_HPP_ */
This header contains standard C++11 headers and compatibility definitions.
Header for E::Host and other interfaces. E::HostModule, E::SystemCallInterface, E::SystemCallApplicat...
Header for E::Module.
Header for E::NetworkSystem.
Header for E::TimeUtil.
Header for E::Wire.
Definition: E_Ethernet.hpp:16
This class abstract a single host machine.
Definition: E_Host.hpp:317
Definition: E_IPv4.hpp:16
static uint64_t defaultLevel
Default log level.
Definition: E_NetworkLog.hpp:117
NetworkSystem is a kind of System which has extensions for handling Packet network.
Definition: E_Networking.hpp:38
virtual void setRoutingTable(const ipv4_t &mask, int prefix, int port) final
Definition: E_RoutingInfo.cpp:50
virtual void setIPAddr(const ipv4_t &ip, int port) final
Definition: E_RoutingInfo.cpp:41
virtual void setARPTable(const mac_t &mac, const ipv4_t &ipv4) final
Add (MAC,IP) entry to its ARP table.
Definition: E_RoutingInfo.cpp:47
virtual void setMACAddr(const mac_t &mac, int port) final
Definition: E_RoutingInfo.cpp:44
Definition: E_Switch.hpp:15
void run(Time till)
Execute all registered Module. Virtual clock will move to the end of the simulation.
Definition: E_System.cpp:78
static Time makeTime(Size time, enum TimeUnit unit)
Produces nanosecond time from a time in given time unit.
Definition: E_TimeUtil.cpp:87
Definition: testenv.hpp:31
Definition: testenv.hpp:62
Definition: testenv.hpp:156
Definition: testenv.hpp:253