1 /*
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
11 #include "test/network/network_emulation.h"
12
13 #include <atomic>
14 #include <memory>
15 #include <set>
16
17 #include "api/test/simulated_network.h"
18 #include "api/units/time_delta.h"
19 #include "call/simulated_network.h"
20 #include "rtc_base/event.h"
21 #include "rtc_base/gunit.h"
22 #include "rtc_base/synchronization/mutex.h"
23 #include "system_wrappers/include/sleep.h"
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26 #include "test/network/network_emulation_manager.h"
27
28 namespace webrtc {
29 namespace test {
30 namespace {
31
32 using ::testing::ElementsAreArray;
33
34 constexpr TimeDelta kNetworkPacketWaitTimeout = TimeDelta::Millis(100);
35 constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1);
36 constexpr int kOverheadIpv4Udp = 20 + 8;
37
38 class SocketReader : public sigslot::has_slots<> {
39 public:
SocketReader(rtc::AsyncSocket * socket,rtc::Thread * network_thread)40 explicit SocketReader(rtc::AsyncSocket* socket, rtc::Thread* network_thread)
41 : socket_(socket), network_thread_(network_thread) {
42 socket_->SignalReadEvent.connect(this, &SocketReader::OnReadEvent);
43 size_ = 128 * 1024;
44 buf_ = new char[size_];
45 }
~SocketReader()46 ~SocketReader() override { delete[] buf_; }
47
OnReadEvent(rtc::AsyncSocket * socket)48 void OnReadEvent(rtc::AsyncSocket* socket) {
49 RTC_DCHECK(socket_ == socket);
50 RTC_DCHECK(network_thread_->IsCurrent());
51 int64_t timestamp;
52 len_ = socket_->Recv(buf_, size_, ×tamp);
53
54 MutexLock lock(&lock_);
55 received_count_++;
56 }
57
ReceivedCount()58 int ReceivedCount() {
59 MutexLock lock(&lock_);
60 return received_count_;
61 }
62
63 private:
64 rtc::AsyncSocket* const socket_;
65 rtc::Thread* const network_thread_;
66 char* buf_;
67 size_t size_;
68 int len_;
69
70 Mutex lock_;
71 int received_count_ RTC_GUARDED_BY(lock_) = 0;
72 };
73
74 class MockReceiver : public EmulatedNetworkReceiverInterface {
75 public:
76 MOCK_METHOD(void, OnPacketReceived, (EmulatedIpPacket packet), (override));
77 };
78
79 class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
80 public:
NetworkEmulationManagerThreeNodesRoutingTest()81 NetworkEmulationManagerThreeNodesRoutingTest() {
82 e1_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
83 e2_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
84 e3_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
85 }
86
SetupRouting(std::function<void (EmulatedEndpoint *,EmulatedEndpoint *,EmulatedEndpoint *,NetworkEmulationManager *)> create_routing_func)87 void SetupRouting(
88 std::function<void(EmulatedEndpoint*,
89 EmulatedEndpoint*,
90 EmulatedEndpoint*,
91 NetworkEmulationManager*)> create_routing_func) {
92 create_routing_func(e1_, e2_, e3_, &emulation_);
93 }
94
SendPacketsAndValidateDelivery()95 void SendPacketsAndValidateDelivery() {
96 EXPECT_CALL(r_e1_e2_, OnPacketReceived(::testing::_)).Times(1);
97 EXPECT_CALL(r_e2_e1_, OnPacketReceived(::testing::_)).Times(1);
98 EXPECT_CALL(r_e1_e3_, OnPacketReceived(::testing::_)).Times(1);
99 EXPECT_CALL(r_e3_e1_, OnPacketReceived(::testing::_)).Times(1);
100
101 uint16_t common_send_port = 80;
102 uint16_t r_e1_e2_port = e2_->BindReceiver(0, &r_e1_e2_).value();
103 uint16_t r_e2_e1_port = e1_->BindReceiver(0, &r_e2_e1_).value();
104 uint16_t r_e1_e3_port = e3_->BindReceiver(0, &r_e1_e3_).value();
105 uint16_t r_e3_e1_port = e1_->BindReceiver(0, &r_e3_e1_).value();
106
107 // Next code is using API of EmulatedEndpoint, that is visible only for
108 // internals of network emulation layer. Don't use this API in other tests.
109 // Send packet from e1 to e2.
110 e1_->SendPacket(
111 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
112 rtc::SocketAddress(e2_->GetPeerLocalAddress(), r_e1_e2_port),
113 rtc::CopyOnWriteBuffer(10));
114
115 // Send packet from e2 to e1.
116 e2_->SendPacket(
117 rtc::SocketAddress(e2_->GetPeerLocalAddress(), common_send_port),
118 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e2_e1_port),
119 rtc::CopyOnWriteBuffer(10));
120
121 // Send packet from e1 to e3.
122 e1_->SendPacket(
123 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
124 rtc::SocketAddress(e3_->GetPeerLocalAddress(), r_e1_e3_port),
125 rtc::CopyOnWriteBuffer(10));
126
127 // Send packet from e3 to e1.
128 e3_->SendPacket(
129 rtc::SocketAddress(e3_->GetPeerLocalAddress(), common_send_port),
130 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e3_e1_port),
131 rtc::CopyOnWriteBuffer(10));
132
133 // Sleep at the end to wait for async packets delivery.
134 emulation_.time_controller()->AdvanceTime(kNetworkPacketWaitTimeout);
135 }
136
137 private:
138 // Receivers: r_<source endpoint>_<destination endpoint>
139 // They must be destroyed after emulation, so they should be declared before.
140 MockReceiver r_e1_e2_;
141 MockReceiver r_e2_e1_;
142 MockReceiver r_e1_e3_;
143 MockReceiver r_e3_e1_;
144
145 NetworkEmulationManagerImpl emulation_{TimeMode::kRealTime};
146 EmulatedEndpoint* e1_;
147 EmulatedEndpoint* e2_;
148 EmulatedEndpoint* e3_;
149 };
150
CreateEmulatedNodeWithDefaultBuiltInConfig(NetworkEmulationManager * emulation)151 EmulatedNetworkNode* CreateEmulatedNodeWithDefaultBuiltInConfig(
152 NetworkEmulationManager* emulation) {
153 return emulation->CreateEmulatedNode(
154 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
155 }
156
157 } // namespace
158
159 using ::testing::_;
160
TEST(NetworkEmulationManagerTest,GeneratedIpv4AddressDoesNotCollide)161 TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
162 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
163 std::set<rtc::IPAddress> ips;
164 EmulatedEndpointConfig config;
165 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv4;
166 for (int i = 0; i < 1000; i++) {
167 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
168 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET);
169 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
170 ASSERT_TRUE(result);
171 }
172 }
173
TEST(NetworkEmulationManagerTest,GeneratedIpv6AddressDoesNotCollide)174 TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
175 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
176 std::set<rtc::IPAddress> ips;
177 EmulatedEndpointConfig config;
178 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv6;
179 for (int i = 0; i < 1000; i++) {
180 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
181 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET6);
182 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
183 ASSERT_TRUE(result);
184 }
185 }
186
TEST(NetworkEmulationManagerTest,Run)187 TEST(NetworkEmulationManagerTest, Run) {
188 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
189
190 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
191 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
192 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
193 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
194 EmulatedEndpoint* alice_endpoint =
195 network_manager.CreateEndpoint(EmulatedEndpointConfig());
196 EmulatedEndpoint* bob_endpoint =
197 network_manager.CreateEndpoint(EmulatedEndpointConfig());
198 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
199 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
200
201 EmulatedNetworkManagerInterface* nt1 =
202 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
203 EmulatedNetworkManagerInterface* nt2 =
204 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
205
206 rtc::Thread* t1 = nt1->network_thread();
207 rtc::Thread* t2 = nt2->network_thread();
208
209 rtc::CopyOnWriteBuffer data("Hello");
210 for (uint64_t j = 0; j < 2; j++) {
211 auto* s1 = t1->socketserver()->CreateAsyncSocket(AF_INET, SOCK_DGRAM);
212 auto* s2 = t2->socketserver()->CreateAsyncSocket(AF_INET, SOCK_DGRAM);
213
214 SocketReader r1(s1, t1);
215 SocketReader r2(s2, t2);
216
217 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
218 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
219
220 t1->Invoke<void>(RTC_FROM_HERE, [&] {
221 s1->Bind(a1);
222 a1 = s1->GetLocalAddress();
223 });
224 t2->Invoke<void>(RTC_FROM_HERE, [&] {
225 s2->Bind(a2);
226 a2 = s2->GetLocalAddress();
227 });
228
229 t1->Invoke<void>(RTC_FROM_HERE, [&] { s1->Connect(a2); });
230 t2->Invoke<void>(RTC_FROM_HERE, [&] { s2->Connect(a1); });
231
232 for (uint64_t i = 0; i < 1000; i++) {
233 t1->PostTask(RTC_FROM_HERE,
234 [&]() { s1->Send(data.data(), data.size()); });
235 t2->PostTask(RTC_FROM_HERE,
236 [&]() { s2->Send(data.data(), data.size()); });
237 }
238
239 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
240
241 EXPECT_EQ(r1.ReceivedCount(), 1000);
242 EXPECT_EQ(r2.ReceivedCount(), 1000);
243
244 t1->Invoke<void>(RTC_FROM_HERE, [&] { delete s1; });
245 t2->Invoke<void>(RTC_FROM_HERE, [&] { delete s2; });
246 }
247
248 const int64_t single_packet_size = data.size() + kOverheadIpv4Udp;
249 std::atomic<int> received_stats_count{0};
250 nt1->GetStats([&](EmulatedNetworkStats st) {
251 EXPECT_EQ(st.packets_sent, 2000l);
252 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
253 EXPECT_THAT(st.local_addresses,
254 ElementsAreArray({alice_endpoint->GetPeerLocalAddress()}));
255 EXPECT_EQ(st.PacketsReceived(), 2000l);
256 EXPECT_EQ(st.BytesReceived().bytes(), single_packet_size * 2000l);
257 EXPECT_EQ(st.PacketsDropped(), 0l);
258 EXPECT_EQ(st.BytesDropped().bytes(), 0l);
259
260 EXPECT_EQ(st.incoming_stats_per_source[bob_endpoint->GetPeerLocalAddress()]
261 .packets_received,
262 2000l);
263 EXPECT_EQ(st.incoming_stats_per_source[bob_endpoint->GetPeerLocalAddress()]
264 .bytes_received.bytes(),
265 single_packet_size * 2000l);
266 EXPECT_EQ(st.incoming_stats_per_source[bob_endpoint->GetPeerLocalAddress()]
267 .packets_dropped,
268 0l);
269 EXPECT_EQ(st.incoming_stats_per_source[bob_endpoint->GetPeerLocalAddress()]
270 .bytes_dropped.bytes(),
271 0l);
272 received_stats_count++;
273 });
274 nt2->GetStats([&](EmulatedNetworkStats st) {
275 EXPECT_EQ(st.packets_sent, 2000l);
276 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
277 EXPECT_THAT(st.local_addresses,
278 ElementsAreArray({bob_endpoint->GetPeerLocalAddress()}));
279 EXPECT_EQ(st.PacketsReceived(), 2000l);
280 EXPECT_EQ(st.BytesReceived().bytes(), single_packet_size * 2000l);
281 EXPECT_EQ(st.PacketsDropped(), 0l);
282 EXPECT_EQ(st.BytesDropped().bytes(), 0l);
283 EXPECT_GT(st.FirstReceivedPacketSize(), DataSize::Zero());
284 EXPECT_TRUE(st.FirstPacketReceivedTime().IsFinite());
285 EXPECT_TRUE(st.LastPacketReceivedTime().IsFinite());
286
287 EXPECT_EQ(
288 st.incoming_stats_per_source[alice_endpoint->GetPeerLocalAddress()]
289 .packets_received,
290 2000l);
291 EXPECT_EQ(
292 st.incoming_stats_per_source[alice_endpoint->GetPeerLocalAddress()]
293 .bytes_received.bytes(),
294 single_packet_size * 2000l);
295 EXPECT_EQ(
296 st.incoming_stats_per_source[alice_endpoint->GetPeerLocalAddress()]
297 .packets_dropped,
298 0l);
299 EXPECT_EQ(
300 st.incoming_stats_per_source[alice_endpoint->GetPeerLocalAddress()]
301 .bytes_dropped.bytes(),
302 0l);
303 received_stats_count++;
304 });
305 ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 2,
306 kStatsWaitTimeout.ms(),
307 *network_manager.time_controller());
308 }
309
TEST(NetworkEmulationManagerTest,ThroughputStats)310 TEST(NetworkEmulationManagerTest, ThroughputStats) {
311 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
312
313 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
314 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
315 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
316 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
317 EmulatedEndpoint* alice_endpoint =
318 network_manager.CreateEndpoint(EmulatedEndpointConfig());
319 EmulatedEndpoint* bob_endpoint =
320 network_manager.CreateEndpoint(EmulatedEndpointConfig());
321 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
322 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
323
324 EmulatedNetworkManagerInterface* nt1 =
325 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
326 EmulatedNetworkManagerInterface* nt2 =
327 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
328
329 rtc::Thread* t1 = nt1->network_thread();
330 rtc::Thread* t2 = nt2->network_thread();
331
332 constexpr int64_t kUdpPayloadSize = 100;
333 constexpr int64_t kSinglePacketSize = kUdpPayloadSize + kOverheadIpv4Udp;
334 rtc::CopyOnWriteBuffer data(kUdpPayloadSize);
335 auto* s1 = t1->socketserver()->CreateAsyncSocket(AF_INET, SOCK_DGRAM);
336 auto* s2 = t2->socketserver()->CreateAsyncSocket(AF_INET, SOCK_DGRAM);
337
338 SocketReader r1(s1, t1);
339 SocketReader r2(s2, t2);
340
341 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
342 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
343
344 t1->Invoke<void>(RTC_FROM_HERE, [&] {
345 s1->Bind(a1);
346 a1 = s1->GetLocalAddress();
347 });
348 t2->Invoke<void>(RTC_FROM_HERE, [&] {
349 s2->Bind(a2);
350 a2 = s2->GetLocalAddress();
351 });
352
353 t1->Invoke<void>(RTC_FROM_HERE, [&] { s1->Connect(a2); });
354 t2->Invoke<void>(RTC_FROM_HERE, [&] { s2->Connect(a1); });
355
356 // Send 11 packets, totalizing 1 second between the first and the last.
357 const int kNumPacketsSent = 11;
358 const TimeDelta kDelay = TimeDelta::Millis(100);
359 for (int i = 0; i < kNumPacketsSent; i++) {
360 t1->PostTask(RTC_FROM_HERE, [&]() { s1->Send(data.data(), data.size()); });
361 t2->PostTask(RTC_FROM_HERE, [&]() { s2->Send(data.data(), data.size()); });
362 network_manager.time_controller()->AdvanceTime(kDelay);
363 }
364
365 std::atomic<int> received_stats_count{0};
366 nt1->GetStats([&](EmulatedNetworkStats st) {
367 EXPECT_EQ(st.packets_sent, kNumPacketsSent);
368 EXPECT_EQ(st.bytes_sent.bytes(), kSinglePacketSize * kNumPacketsSent);
369
370 const double tolerance = 0.95; // Accept 5% tolerance for timing.
371 EXPECT_GE(st.last_packet_sent_time - st.first_packet_sent_time,
372 (kNumPacketsSent - 1) * kDelay * tolerance);
373 EXPECT_GT(st.AverageSendRate().bps(), 0);
374 received_stats_count++;
375 });
376
377 ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 1,
378 kStatsWaitTimeout.ms(),
379 *network_manager.time_controller());
380
381 EXPECT_EQ(r1.ReceivedCount(), 11);
382 EXPECT_EQ(r2.ReceivedCount(), 11);
383
384 t1->Invoke<void>(RTC_FROM_HERE, [&] { delete s1; });
385 t2->Invoke<void>(RTC_FROM_HERE, [&] { delete s2; });
386 }
387
388 // Testing that packets are delivered via all routes using a routing scheme as
389 // follows:
390 // * e1 -> n1 -> e2
391 // * e2 -> n2 -> e1
392 // * e1 -> n3 -> e3
393 // * e3 -> n4 -> e1
TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeers)394 TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
395 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeers) {
396 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
397 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
398 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
399 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
400 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
401 auto* node4 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
402
403 emulation->CreateRoute(e1, {node1}, e2);
404 emulation->CreateRoute(e2, {node2}, e1);
405
406 emulation->CreateRoute(e1, {node3}, e3);
407 emulation->CreateRoute(e3, {node4}, e1);
408 });
409 SendPacketsAndValidateDelivery();
410 }
411
412 // Testing that packets are delivered via all routes using a routing scheme as
413 // follows:
414 // * e1 -> n1 -> e2
415 // * e2 -> n2 -> e1
416 // * e1 -> n1 -> e3
417 // * e3 -> n4 -> e1
TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeersOverSameSendLink)418 TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
419 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeersOverSameSendLink) {
420 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
421 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
422 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
423 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
424 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
425
426 emulation->CreateRoute(e1, {node1}, e2);
427 emulation->CreateRoute(e2, {node2}, e1);
428
429 emulation->CreateRoute(e1, {node1}, e3);
430 emulation->CreateRoute(e3, {node3}, e1);
431 });
432 SendPacketsAndValidateDelivery();
433 }
434
435 } // namespace test
436 } // namespace webrtc
437