blob: b119442a10891bf3b42b4f70ddd2596faae88e66 [file] [log] [blame]
Artem Titov0774bd92019-01-30 15:26:05 +01001/*
2 * Copyright 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "test/network/network_emulation.h"
12
Artem Titovff393122019-04-05 11:19:52 +020013#include <atomic>
Artem Titov0774bd92019-01-30 15:26:05 +010014#include <memory>
Artem Titov386802e2019-07-05 10:48:17 +020015#include <set>
Artem Titov0774bd92019-01-30 15:26:05 +010016
Artem Titov0774bd92019-01-30 15:26:05 +010017#include "api/test/simulated_network.h"
Artem Titova7683452019-05-15 12:26:38 +020018#include "api/units/time_delta.h"
Artem Titov0774bd92019-01-30 15:26:05 +010019#include "call/simulated_network.h"
20#include "rtc_base/event.h"
Artem Titovff393122019-04-05 11:19:52 +020021#include "rtc_base/gunit.h"
Artem Titovff393122019-04-05 11:19:52 +020022#include "system_wrappers/include/sleep.h"
Artem Titov0774bd92019-01-30 15:26:05 +010023#include "test/gmock.h"
24#include "test/gtest.h"
Artem Titov386802e2019-07-05 10:48:17 +020025#include "test/network/network_emulation_manager.h"
Artem Titov0774bd92019-01-30 15:26:05 +010026
27namespace webrtc {
28namespace test {
Artem Titovff393122019-04-05 11:19:52 +020029namespace {
30
31constexpr int kNetworkPacketWaitTimeoutMs = 100;
Artem Titov806299e2019-04-12 12:17:19 +020032constexpr int kStatsWaitTimeoutMs = 1000;
Artem Titov0774bd92019-01-30 15:26:05 +010033
34class SocketReader : public sigslot::has_slots<> {
35 public:
Artem Titov519d74a2019-05-17 12:01:00 +020036 explicit SocketReader(rtc::AsyncSocket* socket, rtc::Thread* network_thread)
37 : socket_(socket), network_thread_(network_thread) {
Artem Titov0774bd92019-01-30 15:26:05 +010038 socket_->SignalReadEvent.connect(this, &SocketReader::OnReadEvent);
39 size_ = 128 * 1024;
40 buf_ = new char[size_];
41 }
42 ~SocketReader() override { delete[] buf_; }
43
44 void OnReadEvent(rtc::AsyncSocket* socket) {
45 RTC_DCHECK(socket_ == socket);
Artem Titov519d74a2019-05-17 12:01:00 +020046 network_thread_->PostTask(RTC_FROM_HERE, [this]() {
47 int64_t timestamp;
48 len_ = socket_->Recv(buf_, size_, &timestamp);
49
Artem Titov0774bd92019-01-30 15:26:05 +010050 rtc::CritScope crit(&lock_);
51 received_count_++;
Artem Titov519d74a2019-05-17 12:01:00 +020052 });
Artem Titov0774bd92019-01-30 15:26:05 +010053 }
54
55 int ReceivedCount() {
56 rtc::CritScope crit(&lock_);
57 return received_count_;
58 }
59
60 private:
Artem Titov519d74a2019-05-17 12:01:00 +020061 rtc::AsyncSocket* const socket_;
62 rtc::Thread* const network_thread_;
Artem Titov0774bd92019-01-30 15:26:05 +010063 char* buf_;
64 size_t size_;
65 int len_;
66
67 rtc::CriticalSection lock_;
68 int received_count_ RTC_GUARDED_BY(lock_) = 0;
69};
70
Artem Titovff393122019-04-05 11:19:52 +020071class MockReceiver : public EmulatedNetworkReceiverInterface {
72 public:
73 MOCK_METHOD1(OnPacketReceived, void(EmulatedIpPacket packet));
74};
75
76class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
77 public:
78 NetworkEmulationManagerThreeNodesRoutingTest() {
79 e1_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
80 e2_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
81 e3_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
82 }
83
84 void SetupRouting(
85 std::function<void(EmulatedEndpoint*,
86 EmulatedEndpoint*,
87 EmulatedEndpoint*,
88 NetworkEmulationManager*)> create_routing_func) {
89 create_routing_func(e1_, e2_, e3_, &emulation_);
90 }
91
92 void SendPacketsAndValidateDelivery() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020093 EXPECT_CALL(r_e1_e2_, OnPacketReceived(::testing::_)).Times(1);
94 EXPECT_CALL(r_e2_e1_, OnPacketReceived(::testing::_)).Times(1);
95 EXPECT_CALL(r_e1_e3_, OnPacketReceived(::testing::_)).Times(1);
96 EXPECT_CALL(r_e3_e1_, OnPacketReceived(::testing::_)).Times(1);
Artem Titovff393122019-04-05 11:19:52 +020097
98 uint16_t common_send_port = 80;
99 uint16_t r_e1_e2_port = e2_->BindReceiver(0, &r_e1_e2_).value();
100 uint16_t r_e2_e1_port = e1_->BindReceiver(0, &r_e2_e1_).value();
101 uint16_t r_e1_e3_port = e3_->BindReceiver(0, &r_e1_e3_).value();
102 uint16_t r_e3_e1_port = e1_->BindReceiver(0, &r_e3_e1_).value();
103
104 // Next code is using API of EmulatedEndpoint, that is visible only for
105 // internals of network emulation layer. Don't use this API in other tests.
106 // Send packet from e1 to e2.
107 e1_->SendPacket(
108 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
109 rtc::SocketAddress(e2_->GetPeerLocalAddress(), r_e1_e2_port),
110 rtc::CopyOnWriteBuffer(10));
111
112 // Send packet from e2 to e1.
113 e2_->SendPacket(
114 rtc::SocketAddress(e2_->GetPeerLocalAddress(), common_send_port),
115 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e2_e1_port),
116 rtc::CopyOnWriteBuffer(10));
117
118 // Send packet from e1 to e3.
119 e1_->SendPacket(
120 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
121 rtc::SocketAddress(e3_->GetPeerLocalAddress(), r_e1_e3_port),
122 rtc::CopyOnWriteBuffer(10));
123
124 // Send packet from e3 to e1.
125 e3_->SendPacket(
126 rtc::SocketAddress(e3_->GetPeerLocalAddress(), common_send_port),
127 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e3_e1_port),
128 rtc::CopyOnWriteBuffer(10));
129
130 // Sleep at the end to wait for async packets delivery.
131 SleepMs(kNetworkPacketWaitTimeoutMs);
132 }
133
134 private:
135 // Receivers: r_<source endpoint>_<destination endpoint>
136 // They must be destroyed after emulation, so they should be declared before.
137 MockReceiver r_e1_e2_;
138 MockReceiver r_e2_e1_;
139 MockReceiver r_e1_e3_;
140 MockReceiver r_e3_e1_;
141
142 NetworkEmulationManagerImpl emulation_;
143 EmulatedEndpoint* e1_;
144 EmulatedEndpoint* e2_;
145 EmulatedEndpoint* e3_;
146};
147
148EmulatedNetworkNode* CreateEmulatedNodeWithDefaultBuiltInConfig(
149 NetworkEmulationManager* emulation) {
150 return emulation->CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200151 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovff393122019-04-05 11:19:52 +0200152}
153
154} // namespace
155
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200156using ::testing::_;
Artem Titovff393122019-04-05 11:19:52 +0200157
Artem Titov0bf4c292019-02-26 10:00:07 +0100158TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100159 NetworkEmulationManagerImpl network_manager;
Artem Titov0bf4c292019-02-26 10:00:07 +0100160 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100161 EmulatedEndpointConfig config;
162 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv4;
Artem Titov0bf4c292019-02-26 10:00:07 +0100163 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100164 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100165 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET);
166 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
167 ASSERT_TRUE(result);
168 }
169}
170
171TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100172 NetworkEmulationManagerImpl network_manager;
Artem Titov0bf4c292019-02-26 10:00:07 +0100173 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100174 EmulatedEndpointConfig config;
175 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv6;
Artem Titov0bf4c292019-02-26 10:00:07 +0100176 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100177 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100178 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET6);
179 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
180 ASSERT_TRUE(result);
181 }
182}
183
Artem Titov0774bd92019-01-30 15:26:05 +0100184TEST(NetworkEmulationManagerTest, Run) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100185 NetworkEmulationManagerImpl network_manager;
Artem Titov0774bd92019-01-30 15:26:05 +0100186
187 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200188 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov0774bd92019-01-30 15:26:05 +0100189 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200190 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovaba8dc22019-03-11 10:08:40 +0100191 EmulatedEndpoint* alice_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100192 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titovaba8dc22019-03-11 10:08:40 +0100193 EmulatedEndpoint* bob_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100194 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titov0774bd92019-01-30 15:26:05 +0100195 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
196 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
197
Artem Titove5cc85b2019-03-28 12:11:09 +0100198 EmulatedNetworkManagerInterface* nt1 =
199 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
200 EmulatedNetworkManagerInterface* nt2 =
201 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
Artem Titov0774bd92019-01-30 15:26:05 +0100202
Artem Titov806299e2019-04-12 12:17:19 +0200203 rtc::CopyOnWriteBuffer data("Hello");
Artem Titov0774bd92019-01-30 15:26:05 +0100204 for (uint64_t j = 0; j < 2; j++) {
Artem Titove5cc85b2019-03-28 12:11:09 +0100205 auto* s1 = nt1->network_thread()->socketserver()->CreateAsyncSocket(
206 AF_INET, SOCK_DGRAM);
207 auto* s2 = nt2->network_thread()->socketserver()->CreateAsyncSocket(
208 AF_INET, SOCK_DGRAM);
Artem Titov0774bd92019-01-30 15:26:05 +0100209
Artem Titov519d74a2019-05-17 12:01:00 +0200210 SocketReader r1(s1, nt1->network_thread());
211 SocketReader r2(s2, nt2->network_thread());
Artem Titov0774bd92019-01-30 15:26:05 +0100212
213 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
214 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
215
216 s1->Bind(a1);
217 s2->Bind(a2);
218
Artem Titove5cc85b2019-03-28 12:11:09 +0100219 s1->Connect(s2->GetLocalAddress());
220 s2->Connect(s1->GetLocalAddress());
Artem Titov0774bd92019-01-30 15:26:05 +0100221
Artem Titov0774bd92019-01-30 15:26:05 +0100222 for (uint64_t i = 0; i < 1000; i++) {
Artem Titov519d74a2019-05-17 12:01:00 +0200223 nt1->network_thread()->PostTask(
224 RTC_FROM_HERE, [&]() { s1->Send(data.data(), data.size()); });
225 nt2->network_thread()->PostTask(
226 RTC_FROM_HERE, [&]() { s2->Send(data.data(), data.size()); });
Artem Titov0774bd92019-01-30 15:26:05 +0100227 }
228
229 rtc::Event wait;
230 wait.Wait(1000);
Artem Titov806299e2019-04-12 12:17:19 +0200231 EXPECT_EQ(r1.ReceivedCount(), 1000);
232 EXPECT_EQ(r2.ReceivedCount(), 1000);
Artem Titov0774bd92019-01-30 15:26:05 +0100233
234 delete s1;
235 delete s2;
236 }
Artem Titov806299e2019-04-12 12:17:19 +0200237
238 int64_t single_packet_size = data.size();
239 std::atomic<int> received_stats_count{0};
240 nt1->GetStats([&](EmulatedNetworkStats st) {
241 EXPECT_EQ(st.packets_sent, 2000l);
242 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
243 EXPECT_EQ(st.packets_received, 2000l);
244 EXPECT_EQ(st.bytes_received.bytes(), single_packet_size * 2000l);
245 EXPECT_EQ(st.packets_dropped, 0l);
246 EXPECT_EQ(st.bytes_dropped.bytes(), 0l);
247 received_stats_count++;
248 });
249 nt2->GetStats([&](EmulatedNetworkStats st) {
250 EXPECT_EQ(st.packets_sent, 2000l);
251 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
252 EXPECT_EQ(st.packets_received, 2000l);
253 EXPECT_EQ(st.bytes_received.bytes(), single_packet_size * 2000l);
254 EXPECT_EQ(st.packets_dropped, 0l);
255 EXPECT_EQ(st.bytes_dropped.bytes(), 0l);
256 received_stats_count++;
257 });
258 ASSERT_EQ_WAIT(received_stats_count.load(), 2, kStatsWaitTimeoutMs);
259}
260
Artem Titova7683452019-05-15 12:26:38 +0200261TEST(NetworkEmulationManagerTest, ThroughputStats) {
Artem Titov806299e2019-04-12 12:17:19 +0200262 NetworkEmulationManagerImpl network_manager;
263
264 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200265 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200266 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200267 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200268 EmulatedEndpoint* alice_endpoint =
269 network_manager.CreateEndpoint(EmulatedEndpointConfig());
270 EmulatedEndpoint* bob_endpoint =
271 network_manager.CreateEndpoint(EmulatedEndpointConfig());
272 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
273 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
274
275 EmulatedNetworkManagerInterface* nt1 =
276 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
277 EmulatedNetworkManagerInterface* nt2 =
278 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
279
280 int64_t single_packet_size = 100;
281 rtc::CopyOnWriteBuffer data(single_packet_size);
282 auto* s1 = nt1->network_thread()->socketserver()->CreateAsyncSocket(
283 AF_INET, SOCK_DGRAM);
284 auto* s2 = nt2->network_thread()->socketserver()->CreateAsyncSocket(
285 AF_INET, SOCK_DGRAM);
286
Artem Titov519d74a2019-05-17 12:01:00 +0200287 SocketReader r1(s1, nt1->network_thread());
288 SocketReader r2(s2, nt2->network_thread());
Artem Titov806299e2019-04-12 12:17:19 +0200289
290 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
291 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
292
293 s1->Bind(a1);
294 s2->Bind(a2);
295
296 s1->Connect(s2->GetLocalAddress());
297 s2->Connect(s1->GetLocalAddress());
298
Yves Gereyb64d65e2019-09-06 16:35:20 +0200299 // Send 11 packets, totalizing 1 second between the first and the last.
300 const int kNumPacketsSent = 11;
301 const int kDelayMs = 100;
Artem Titov806299e2019-04-12 12:17:19 +0200302 rtc::Event wait;
Yves Gereyb64d65e2019-09-06 16:35:20 +0200303 for (int i = 0; i < kNumPacketsSent; i++) {
Artem Titov519d74a2019-05-17 12:01:00 +0200304 nt1->network_thread()->PostTask(
305 RTC_FROM_HERE, [&]() { s1->Send(data.data(), data.size()); });
306 nt2->network_thread()->PostTask(
307 RTC_FROM_HERE, [&]() { s2->Send(data.data(), data.size()); });
Yves Gereyb64d65e2019-09-06 16:35:20 +0200308 wait.Wait(kDelayMs);
Artem Titov806299e2019-04-12 12:17:19 +0200309 }
Artem Titov806299e2019-04-12 12:17:19 +0200310
Artem Titov806299e2019-04-12 12:17:19 +0200311 std::atomic<int> received_stats_count{0};
312 nt1->GetStats([&](EmulatedNetworkStats st) {
Yves Gereyb64d65e2019-09-06 16:35:20 +0200313 EXPECT_EQ(st.packets_sent, kNumPacketsSent);
314 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * kNumPacketsSent);
315
316 const double tolerance = 0.99; // Accept 1% tolerance for timing.
Artem Titova7683452019-05-15 12:26:38 +0200317 EXPECT_GE(st.last_packet_sent_time - st.first_packet_sent_time,
Yves Gereyb64d65e2019-09-06 16:35:20 +0200318 TimeDelta::ms((kNumPacketsSent - 1) * kDelayMs * tolerance));
Artem Titova7683452019-05-15 12:26:38 +0200319 EXPECT_GT(st.AverageSendRate().bps(), 0);
Artem Titov806299e2019-04-12 12:17:19 +0200320 received_stats_count++;
321 });
322 ASSERT_EQ_WAIT(received_stats_count.load(), 1, kStatsWaitTimeoutMs);
Artem Titova7683452019-05-15 12:26:38 +0200323 EXPECT_EQ(r1.ReceivedCount(), 11);
324 EXPECT_EQ(r2.ReceivedCount(), 11);
Artem Titov519d74a2019-05-17 12:01:00 +0200325
326 delete s1;
327 delete s2;
Artem Titov0774bd92019-01-30 15:26:05 +0100328}
329
Artem Titovff393122019-04-05 11:19:52 +0200330// Testing that packets are delivered via all routes using a routing scheme as
331// follows:
332// * e1 -> n1 -> e2
333// * e2 -> n2 -> e1
334// * e1 -> n3 -> e3
335// * e3 -> n4 -> e1
336TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
337 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeers) {
338 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
339 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
340 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
341 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
342 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
343 auto* node4 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
344
345 emulation->CreateRoute(e1, {node1}, e2);
346 emulation->CreateRoute(e2, {node2}, e1);
347
348 emulation->CreateRoute(e1, {node3}, e3);
349 emulation->CreateRoute(e3, {node4}, e1);
350 });
351 SendPacketsAndValidateDelivery();
352}
353
354// Testing that packets are delivered via all routes using a routing scheme as
355// follows:
356// * e1 -> n1 -> e2
357// * e2 -> n2 -> e1
358// * e1 -> n1 -> e3
359// * e3 -> n4 -> e1
360TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
361 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeersOverSameSendLink) {
362 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
363 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
364 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
365 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
366 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
367
368 emulation->CreateRoute(e1, {node1}, e2);
369 emulation->CreateRoute(e2, {node2}, e1);
370
371 emulation->CreateRoute(e1, {node1}, e3);
372 emulation->CreateRoute(e3, {node3}, e1);
373 });
374 SendPacketsAndValidateDelivery();
375}
376
Artem Titov0774bd92019-01-30 15:26:05 +0100377} // namespace test
378} // namespace webrtc