blob: ccc9c723c34c3496984c2b2eab58e199fb862eff [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"
Markus Handell4ab7dde2020-07-10 13:23:25 +020022#include "rtc_base/synchronization/mutex.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
Artem Titov1062cfe2020-07-21 15:46:08 +020031using ::testing::ElementsAreArray;
32
Danil Chapovalov0c626af2020-02-10 11:16:00 +010033constexpr TimeDelta kNetworkPacketWaitTimeout = TimeDelta::Millis(100);
34constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1);
Niels Möller7536bc52019-10-04 13:54:39 +020035constexpr int kOverheadIpv4Udp = 20 + 8;
Artem Titov0774bd92019-01-30 15:26:05 +010036
37class SocketReader : public sigslot::has_slots<> {
38 public:
Niels Möllerd0b88792021-08-12 10:32:30 +020039 explicit SocketReader(rtc::Socket* socket, rtc::Thread* network_thread)
Artem Titov519d74a2019-05-17 12:01:00 +020040 : socket_(socket), network_thread_(network_thread) {
Artem Titov0774bd92019-01-30 15:26:05 +010041 socket_->SignalReadEvent.connect(this, &SocketReader::OnReadEvent);
42 size_ = 128 * 1024;
43 buf_ = new char[size_];
44 }
45 ~SocketReader() override { delete[] buf_; }
46
Niels Möllerd0b88792021-08-12 10:32:30 +020047 void OnReadEvent(rtc::Socket* socket) {
Artem Titov0774bd92019-01-30 15:26:05 +010048 RTC_DCHECK(socket_ == socket);
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +010049 RTC_DCHECK(network_thread_->IsCurrent());
50 int64_t timestamp;
51 len_ = socket_->Recv(buf_, size_, &timestamp);
Artem Titov519d74a2019-05-17 12:01:00 +020052
Markus Handell4ab7dde2020-07-10 13:23:25 +020053 MutexLock lock(&lock_);
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +010054 received_count_++;
Artem Titov0774bd92019-01-30 15:26:05 +010055 }
56
57 int ReceivedCount() {
Markus Handell4ab7dde2020-07-10 13:23:25 +020058 MutexLock lock(&lock_);
Artem Titov0774bd92019-01-30 15:26:05 +010059 return received_count_;
60 }
61
62 private:
Niels Möllerd0b88792021-08-12 10:32:30 +020063 rtc::Socket* const socket_;
Artem Titov519d74a2019-05-17 12:01:00 +020064 rtc::Thread* const network_thread_;
Artem Titov0774bd92019-01-30 15:26:05 +010065 char* buf_;
66 size_t size_;
67 int len_;
68
Markus Handell4ab7dde2020-07-10 13:23:25 +020069 Mutex lock_;
Artem Titov0774bd92019-01-30 15:26:05 +010070 int received_count_ RTC_GUARDED_BY(lock_) = 0;
71};
72
Artem Titovff393122019-04-05 11:19:52 +020073class MockReceiver : public EmulatedNetworkReceiverInterface {
74 public:
Danil Chapovalov54706d62020-05-14 19:50:01 +020075 MOCK_METHOD(void, OnPacketReceived, (EmulatedIpPacket packet), (override));
Artem Titovff393122019-04-05 11:19:52 +020076};
77
78class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
79 public:
80 NetworkEmulationManagerThreeNodesRoutingTest() {
81 e1_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
82 e2_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
83 e3_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
84 }
85
86 void SetupRouting(
87 std::function<void(EmulatedEndpoint*,
88 EmulatedEndpoint*,
89 EmulatedEndpoint*,
90 NetworkEmulationManager*)> create_routing_func) {
91 create_routing_func(e1_, e2_, e3_, &emulation_);
92 }
93
94 void SendPacketsAndValidateDelivery() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020095 EXPECT_CALL(r_e1_e2_, OnPacketReceived(::testing::_)).Times(1);
96 EXPECT_CALL(r_e2_e1_, OnPacketReceived(::testing::_)).Times(1);
97 EXPECT_CALL(r_e1_e3_, OnPacketReceived(::testing::_)).Times(1);
98 EXPECT_CALL(r_e3_e1_, OnPacketReceived(::testing::_)).Times(1);
Artem Titovff393122019-04-05 11:19:52 +020099
100 uint16_t common_send_port = 80;
101 uint16_t r_e1_e2_port = e2_->BindReceiver(0, &r_e1_e2_).value();
102 uint16_t r_e2_e1_port = e1_->BindReceiver(0, &r_e2_e1_).value();
103 uint16_t r_e1_e3_port = e3_->BindReceiver(0, &r_e1_e3_).value();
104 uint16_t r_e3_e1_port = e1_->BindReceiver(0, &r_e3_e1_).value();
105
106 // Next code is using API of EmulatedEndpoint, that is visible only for
107 // internals of network emulation layer. Don't use this API in other tests.
108 // Send packet from e1 to e2.
109 e1_->SendPacket(
110 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
111 rtc::SocketAddress(e2_->GetPeerLocalAddress(), r_e1_e2_port),
112 rtc::CopyOnWriteBuffer(10));
113
114 // Send packet from e2 to e1.
115 e2_->SendPacket(
116 rtc::SocketAddress(e2_->GetPeerLocalAddress(), common_send_port),
117 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e2_e1_port),
118 rtc::CopyOnWriteBuffer(10));
119
120 // Send packet from e1 to e3.
121 e1_->SendPacket(
122 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
123 rtc::SocketAddress(e3_->GetPeerLocalAddress(), r_e1_e3_port),
124 rtc::CopyOnWriteBuffer(10));
125
126 // Send packet from e3 to e1.
127 e3_->SendPacket(
128 rtc::SocketAddress(e3_->GetPeerLocalAddress(), common_send_port),
129 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e3_e1_port),
130 rtc::CopyOnWriteBuffer(10));
131
132 // Sleep at the end to wait for async packets delivery.
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100133 emulation_.time_controller()->AdvanceTime(kNetworkPacketWaitTimeout);
Artem Titovff393122019-04-05 11:19:52 +0200134 }
135
136 private:
137 // Receivers: r_<source endpoint>_<destination endpoint>
138 // They must be destroyed after emulation, so they should be declared before.
139 MockReceiver r_e1_e2_;
140 MockReceiver r_e2_e1_;
141 MockReceiver r_e1_e3_;
142 MockReceiver r_e3_e1_;
143
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100144 NetworkEmulationManagerImpl emulation_{TimeMode::kRealTime};
Artem Titovff393122019-04-05 11:19:52 +0200145 EmulatedEndpoint* e1_;
146 EmulatedEndpoint* e2_;
147 EmulatedEndpoint* e3_;
148};
149
150EmulatedNetworkNode* CreateEmulatedNodeWithDefaultBuiltInConfig(
151 NetworkEmulationManager* emulation) {
152 return emulation->CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200153 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovff393122019-04-05 11:19:52 +0200154}
155
156} // namespace
157
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200158using ::testing::_;
Artem Titovff393122019-04-05 11:19:52 +0200159
Artem Titov0bf4c292019-02-26 10:00:07 +0100160TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100161 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
Artem Titov0bf4c292019-02-26 10:00:07 +0100162 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100163 EmulatedEndpointConfig config;
164 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv4;
Artem Titov0bf4c292019-02-26 10:00:07 +0100165 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100166 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100167 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET);
168 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
169 ASSERT_TRUE(result);
170 }
171}
172
173TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100174 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
Artem Titov0bf4c292019-02-26 10:00:07 +0100175 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100176 EmulatedEndpointConfig config;
177 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv6;
Artem Titov0bf4c292019-02-26 10:00:07 +0100178 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100179 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100180 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET6);
181 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
182 ASSERT_TRUE(result);
183 }
184}
185
Artem Titov0774bd92019-01-30 15:26:05 +0100186TEST(NetworkEmulationManagerTest, Run) {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100187 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
Artem Titov0774bd92019-01-30 15:26:05 +0100188
189 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200190 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov0774bd92019-01-30 15:26:05 +0100191 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200192 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovaba8dc22019-03-11 10:08:40 +0100193 EmulatedEndpoint* alice_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100194 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titovaba8dc22019-03-11 10:08:40 +0100195 EmulatedEndpoint* bob_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100196 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titov0774bd92019-01-30 15:26:05 +0100197 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
198 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
199
Artem Titove5cc85b2019-03-28 12:11:09 +0100200 EmulatedNetworkManagerInterface* nt1 =
201 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
202 EmulatedNetworkManagerInterface* nt2 =
203 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
Artem Titov0774bd92019-01-30 15:26:05 +0100204
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100205 rtc::Thread* t1 = nt1->network_thread();
206 rtc::Thread* t2 = nt2->network_thread();
207
Artem Titov806299e2019-04-12 12:17:19 +0200208 rtc::CopyOnWriteBuffer data("Hello");
Artem Titov0774bd92019-01-30 15:26:05 +0100209 for (uint64_t j = 0; j < 2; j++) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200210 rtc::Socket* s1 = nullptr;
211 rtc::Socket* s2 = nullptr;
Danil Chapovalov7358b402021-02-01 20:43:19 +0100212 t1->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200213 s1 = t1->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100214 });
215 t2->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200216 s2 = t2->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100217 });
Artem Titov0774bd92019-01-30 15:26:05 +0100218
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100219 SocketReader r1(s1, t1);
220 SocketReader r2(s2, t2);
Artem Titov0774bd92019-01-30 15:26:05 +0100221
222 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
223 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
224
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100225 t1->Invoke<void>(RTC_FROM_HERE, [&] {
226 s1->Bind(a1);
227 a1 = s1->GetLocalAddress();
228 });
229 t2->Invoke<void>(RTC_FROM_HERE, [&] {
230 s2->Bind(a2);
231 a2 = s2->GetLocalAddress();
232 });
Artem Titov0774bd92019-01-30 15:26:05 +0100233
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100234 t1->Invoke<void>(RTC_FROM_HERE, [&] { s1->Connect(a2); });
235 t2->Invoke<void>(RTC_FROM_HERE, [&] { s2->Connect(a1); });
Artem Titov0774bd92019-01-30 15:26:05 +0100236
Artem Titov0774bd92019-01-30 15:26:05 +0100237 for (uint64_t i = 0; i < 1000; i++) {
Henrik Boström2deee4b2022-01-20 11:58:05 +0100238 t1->PostTask([&]() { s1->Send(data.data(), data.size()); });
239 t2->PostTask([&]() { s2->Send(data.data(), data.size()); });
Artem Titov0774bd92019-01-30 15:26:05 +0100240 }
241
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100242 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100243
Artem Titov806299e2019-04-12 12:17:19 +0200244 EXPECT_EQ(r1.ReceivedCount(), 1000);
245 EXPECT_EQ(r2.ReceivedCount(), 1000);
Artem Titov0774bd92019-01-30 15:26:05 +0100246
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100247 t1->Invoke<void>(RTC_FROM_HERE, [&] { delete s1; });
248 t2->Invoke<void>(RTC_FROM_HERE, [&] { delete s2; });
Artem Titov0774bd92019-01-30 15:26:05 +0100249 }
Artem Titov806299e2019-04-12 12:17:19 +0200250
Niels Möller7536bc52019-10-04 13:54:39 +0200251 const int64_t single_packet_size = data.size() + kOverheadIpv4Udp;
Artem Titov806299e2019-04-12 12:17:19 +0200252 std::atomic<int> received_stats_count{0};
Artem Titov3e0b65d2020-07-23 02:19:02 +0200253 nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
254 EXPECT_EQ(st->PacketsSent(), 2000l);
255 EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
256 EXPECT_THAT(st->LocalAddresses(),
Artem Titov1062cfe2020-07-21 15:46:08 +0200257 ElementsAreArray({alice_endpoint->GetPeerLocalAddress()}));
Artem Titov3e0b65d2020-07-23 02:19:02 +0200258 EXPECT_EQ(st->PacketsReceived(), 2000l);
259 EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
260 EXPECT_EQ(st->PacketsDropped(), 0l);
261 EXPECT_EQ(st->BytesDropped().bytes(), 0l);
Artem Titovc1a07372020-07-21 09:50:11 +0200262
Artem Titov14b46a72020-07-31 12:57:24 +0200263 rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
264 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
265 source_st = st->IncomingStatsPerSource();
Artem Titov3e0b65d2020-07-23 02:19:02 +0200266 ASSERT_EQ(source_st.size(), 1lu);
Artem Titov14b46a72020-07-31 12:57:24 +0200267 EXPECT_EQ(source_st.at(bob_ip)->PacketsReceived(), 2000l);
268 EXPECT_EQ(source_st.at(bob_ip)->BytesReceived().bytes(),
Artem Titovc1a07372020-07-21 09:50:11 +0200269 single_packet_size * 2000l);
Artem Titov14b46a72020-07-31 12:57:24 +0200270 EXPECT_EQ(source_st.at(bob_ip)->PacketsDropped(), 0l);
271 EXPECT_EQ(source_st.at(bob_ip)->BytesDropped().bytes(), 0l);
272
273 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
274 dest_st = st->OutgoingStatsPerDestination();
275 ASSERT_EQ(dest_st.size(), 1lu);
276 EXPECT_EQ(dest_st.at(bob_ip)->PacketsSent(), 2000l);
277 EXPECT_EQ(dest_st.at(bob_ip)->BytesSent().bytes(),
278 single_packet_size * 2000l);
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200279
280 // No debug stats are collected by default.
281 EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
282 EXPECT_TRUE(st->SentPacketsQueueWaitTimeUs().IsEmpty());
283 EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
284 EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
285 EXPECT_TRUE(dest_st.at(bob_ip)->SentPacketsSizeCounter().IsEmpty());
286 EXPECT_TRUE(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().IsEmpty());
287 EXPECT_TRUE(source_st.at(bob_ip)->DroppedPacketsSizeCounter().IsEmpty());
288
Artem Titov806299e2019-04-12 12:17:19 +0200289 received_stats_count++;
290 });
Artem Titov3e0b65d2020-07-23 02:19:02 +0200291 nt2->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
292 EXPECT_EQ(st->PacketsSent(), 2000l);
293 EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
294 EXPECT_THAT(st->LocalAddresses(),
Artem Titov1062cfe2020-07-21 15:46:08 +0200295 ElementsAreArray({bob_endpoint->GetPeerLocalAddress()}));
Artem Titov3e0b65d2020-07-23 02:19:02 +0200296 EXPECT_EQ(st->PacketsReceived(), 2000l);
297 EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
298 EXPECT_EQ(st->PacketsDropped(), 0l);
299 EXPECT_EQ(st->BytesDropped().bytes(), 0l);
300 EXPECT_GT(st->FirstReceivedPacketSize(), DataSize::Zero());
301 EXPECT_TRUE(st->FirstPacketReceivedTime().IsFinite());
302 EXPECT_TRUE(st->LastPacketReceivedTime().IsFinite());
Artem Titovc1a07372020-07-21 09:50:11 +0200303
Artem Titov14b46a72020-07-31 12:57:24 +0200304 rtc::IPAddress alice_ip = alice_endpoint->GetPeerLocalAddress();
305 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
306 source_st = st->IncomingStatsPerSource();
Artem Titov3e0b65d2020-07-23 02:19:02 +0200307 ASSERT_EQ(source_st.size(), 1lu);
Artem Titov14b46a72020-07-31 12:57:24 +0200308 EXPECT_EQ(source_st.at(alice_ip)->PacketsReceived(), 2000l);
309 EXPECT_EQ(source_st.at(alice_ip)->BytesReceived().bytes(),
Artem Titov3e0b65d2020-07-23 02:19:02 +0200310 single_packet_size * 2000l);
Artem Titov14b46a72020-07-31 12:57:24 +0200311 EXPECT_EQ(source_st.at(alice_ip)->PacketsDropped(), 0l);
312 EXPECT_EQ(source_st.at(alice_ip)->BytesDropped().bytes(), 0l);
313
314 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
315 dest_st = st->OutgoingStatsPerDestination();
316 ASSERT_EQ(dest_st.size(), 1lu);
317 EXPECT_EQ(dest_st.at(alice_ip)->PacketsSent(), 2000l);
318 EXPECT_EQ(dest_st.at(alice_ip)->BytesSent().bytes(),
319 single_packet_size * 2000l);
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200320
321 // No debug stats are collected by default.
322 EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
323 EXPECT_TRUE(st->SentPacketsQueueWaitTimeUs().IsEmpty());
324 EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
325 EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
326 EXPECT_TRUE(dest_st.at(alice_ip)->SentPacketsSizeCounter().IsEmpty());
327 EXPECT_TRUE(source_st.at(alice_ip)->ReceivedPacketsSizeCounter().IsEmpty());
328 EXPECT_TRUE(source_st.at(alice_ip)->DroppedPacketsSizeCounter().IsEmpty());
329
Artem Titov806299e2019-04-12 12:17:19 +0200330 received_stats_count++;
331 });
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100332 ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 2,
333 kStatsWaitTimeout.ms(),
334 *network_manager.time_controller());
Artem Titov806299e2019-04-12 12:17:19 +0200335}
336
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200337TEST(NetworkEmulationManagerTest, DebugStatsCollectedInDebugMode) {
338 NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
339
340 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
341 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
342 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
343 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
344 EmulatedEndpointConfig debug_config;
345 debug_config.stats_gathering_mode =
346 EmulatedEndpointConfig::StatsGatheringMode::kDebug;
347 EmulatedEndpoint* alice_endpoint =
348 network_manager.CreateEndpoint(debug_config);
349 EmulatedEndpoint* bob_endpoint =
350 network_manager.CreateEndpoint(EmulatedEndpointConfig());
351 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
352 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
353
354 EmulatedNetworkManagerInterface* nt1 =
355 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
356 EmulatedNetworkManagerInterface* nt2 =
357 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
358
359 rtc::Thread* t1 = nt1->network_thread();
360 rtc::Thread* t2 = nt2->network_thread();
361
362 rtc::CopyOnWriteBuffer data("Hello");
363 for (uint64_t j = 0; j < 2; j++) {
Niels Möllerd0b88792021-08-12 10:32:30 +0200364 rtc::Socket* s1 = nullptr;
365 rtc::Socket* s2 = nullptr;
Danil Chapovalov7358b402021-02-01 20:43:19 +0100366 t1->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200367 s1 = t1->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100368 });
369 t2->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200370 s2 = t2->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100371 });
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200372
373 SocketReader r1(s1, t1);
374 SocketReader r2(s2, t2);
375
376 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
377 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
378
379 t1->Invoke<void>(RTC_FROM_HERE, [&] {
380 s1->Bind(a1);
381 a1 = s1->GetLocalAddress();
382 });
383 t2->Invoke<void>(RTC_FROM_HERE, [&] {
384 s2->Bind(a2);
385 a2 = s2->GetLocalAddress();
386 });
387
388 t1->Invoke<void>(RTC_FROM_HERE, [&] { s1->Connect(a2); });
389 t2->Invoke<void>(RTC_FROM_HERE, [&] { s2->Connect(a1); });
390
391 for (uint64_t i = 0; i < 1000; i++) {
Henrik Boström2deee4b2022-01-20 11:58:05 +0100392 t1->PostTask([&]() { s1->Send(data.data(), data.size()); });
393 t2->PostTask([&]() { s2->Send(data.data(), data.size()); });
Artem Titovcbe6e8a2020-09-22 15:45:00 +0200394 }
395
396 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
397
398 EXPECT_EQ(r1.ReceivedCount(), 1000);
399 EXPECT_EQ(r2.ReceivedCount(), 1000);
400
401 t1->Invoke<void>(RTC_FROM_HERE, [&] { delete s1; });
402 t2->Invoke<void>(RTC_FROM_HERE, [&] { delete s2; });
403 }
404
405 const int64_t single_packet_size = data.size() + kOverheadIpv4Udp;
406 std::atomic<int> received_stats_count{0};
407 nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
408 rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
409 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
410 source_st = st->IncomingStatsPerSource();
411 ASSERT_EQ(source_st.size(), 1lu);
412
413 std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
414 dest_st = st->OutgoingStatsPerDestination();
415 ASSERT_EQ(dest_st.size(), 1lu);
416
417 // No debug stats are collected by default.
418 EXPECT_EQ(st->SentPacketsSizeCounter().NumSamples(), 2000l);
419 EXPECT_EQ(st->ReceivedPacketsSizeCounter().GetAverage(),
420 single_packet_size);
421 EXPECT_EQ(st->SentPacketsQueueWaitTimeUs().NumSamples(), 2000l);
422 EXPECT_LT(st->SentPacketsQueueWaitTimeUs().GetMax(), 1);
423 EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
424 EXPECT_EQ(dest_st.at(bob_ip)->SentPacketsSizeCounter().NumSamples(), 2000l);
425 EXPECT_EQ(dest_st.at(bob_ip)->SentPacketsSizeCounter().GetAverage(),
426 single_packet_size);
427 EXPECT_EQ(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().NumSamples(),
428 2000l);
429 EXPECT_EQ(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().GetAverage(),
430 single_packet_size);
431 EXPECT_TRUE(source_st.at(bob_ip)->DroppedPacketsSizeCounter().IsEmpty());
432
433 received_stats_count++;
434 });
435 ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 1,
436 kStatsWaitTimeout.ms(),
437 *network_manager.time_controller());
438}
439
Artem Titova7683452019-05-15 12:26:38 +0200440TEST(NetworkEmulationManagerTest, ThroughputStats) {
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100441 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
Artem Titov806299e2019-04-12 12:17:19 +0200442
443 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200444 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200445 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200446 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200447 EmulatedEndpoint* alice_endpoint =
448 network_manager.CreateEndpoint(EmulatedEndpointConfig());
449 EmulatedEndpoint* bob_endpoint =
450 network_manager.CreateEndpoint(EmulatedEndpointConfig());
451 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
452 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
453
454 EmulatedNetworkManagerInterface* nt1 =
455 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
456 EmulatedNetworkManagerInterface* nt2 =
457 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
458
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100459 rtc::Thread* t1 = nt1->network_thread();
460 rtc::Thread* t2 = nt2->network_thread();
461
Niels Möller7536bc52019-10-04 13:54:39 +0200462 constexpr int64_t kUdpPayloadSize = 100;
463 constexpr int64_t kSinglePacketSize = kUdpPayloadSize + kOverheadIpv4Udp;
464 rtc::CopyOnWriteBuffer data(kUdpPayloadSize);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100465
Niels Möllerd0b88792021-08-12 10:32:30 +0200466 rtc::Socket* s1 = nullptr;
467 rtc::Socket* s2 = nullptr;
Danil Chapovalov7358b402021-02-01 20:43:19 +0100468 t1->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200469 s1 = t1->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100470 });
471 t2->Invoke<void>(RTC_FROM_HERE, [&] {
Niels Möllerd0b88792021-08-12 10:32:30 +0200472 s2 = t2->socketserver()->CreateSocket(AF_INET, SOCK_DGRAM);
Danil Chapovalov7358b402021-02-01 20:43:19 +0100473 });
Artem Titov806299e2019-04-12 12:17:19 +0200474
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100475 SocketReader r1(s1, t1);
476 SocketReader r2(s2, t2);
Artem Titov806299e2019-04-12 12:17:19 +0200477
478 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
479 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
480
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100481 t1->Invoke<void>(RTC_FROM_HERE, [&] {
482 s1->Bind(a1);
483 a1 = s1->GetLocalAddress();
484 });
485 t2->Invoke<void>(RTC_FROM_HERE, [&] {
486 s2->Bind(a2);
487 a2 = s2->GetLocalAddress();
488 });
Artem Titov806299e2019-04-12 12:17:19 +0200489
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100490 t1->Invoke<void>(RTC_FROM_HERE, [&] { s1->Connect(a2); });
491 t2->Invoke<void>(RTC_FROM_HERE, [&] { s2->Connect(a1); });
Artem Titov806299e2019-04-12 12:17:19 +0200492
Yves Gereyb64d65e2019-09-06 16:35:20 +0200493 // Send 11 packets, totalizing 1 second between the first and the last.
494 const int kNumPacketsSent = 11;
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100495 const TimeDelta kDelay = TimeDelta::Millis(100);
Yves Gereyb64d65e2019-09-06 16:35:20 +0200496 for (int i = 0; i < kNumPacketsSent; i++) {
Henrik Boström2deee4b2022-01-20 11:58:05 +0100497 t1->PostTask([&]() { s1->Send(data.data(), data.size()); });
498 t2->PostTask([&]() { s2->Send(data.data(), data.size()); });
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100499 network_manager.time_controller()->AdvanceTime(kDelay);
Artem Titov806299e2019-04-12 12:17:19 +0200500 }
Artem Titov806299e2019-04-12 12:17:19 +0200501
Artem Titov806299e2019-04-12 12:17:19 +0200502 std::atomic<int> received_stats_count{0};
Artem Titov3e0b65d2020-07-23 02:19:02 +0200503 nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
504 EXPECT_EQ(st->PacketsSent(), kNumPacketsSent);
505 EXPECT_EQ(st->BytesSent().bytes(), kSinglePacketSize * kNumPacketsSent);
Yves Gereyb64d65e2019-09-06 16:35:20 +0200506
Yves Gereyc65de422019-11-08 20:29:04 +0100507 const double tolerance = 0.95; // Accept 5% tolerance for timing.
Artem Titov3e0b65d2020-07-23 02:19:02 +0200508 EXPECT_GE(st->LastPacketSentTime() - st->FirstPacketSentTime(),
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100509 (kNumPacketsSent - 1) * kDelay * tolerance);
Artem Titov3e0b65d2020-07-23 02:19:02 +0200510 EXPECT_GT(st->AverageSendRate().bps(), 0);
Artem Titov806299e2019-04-12 12:17:19 +0200511 received_stats_count++;
512 });
Sebastian Jansson6ce033a2020-01-22 10:12:56 +0100513
514 ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 1,
515 kStatsWaitTimeout.ms(),
516 *network_manager.time_controller());
517
Artem Titova7683452019-05-15 12:26:38 +0200518 EXPECT_EQ(r1.ReceivedCount(), 11);
519 EXPECT_EQ(r2.ReceivedCount(), 11);
Artem Titov519d74a2019-05-17 12:01:00 +0200520
Sebastian Jansson9d4bbc22020-01-10 20:03:56 +0100521 t1->Invoke<void>(RTC_FROM_HERE, [&] { delete s1; });
522 t2->Invoke<void>(RTC_FROM_HERE, [&] { delete s2; });
Artem Titov0774bd92019-01-30 15:26:05 +0100523}
524
Artem Titovff393122019-04-05 11:19:52 +0200525// Testing that packets are delivered via all routes using a routing scheme as
526// follows:
527// * e1 -> n1 -> e2
528// * e2 -> n2 -> e1
529// * e1 -> n3 -> e3
530// * e3 -> n4 -> e1
531TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
532 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeers) {
533 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
534 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
535 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
536 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
537 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
538 auto* node4 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
539
540 emulation->CreateRoute(e1, {node1}, e2);
541 emulation->CreateRoute(e2, {node2}, e1);
542
543 emulation->CreateRoute(e1, {node3}, e3);
544 emulation->CreateRoute(e3, {node4}, e1);
545 });
546 SendPacketsAndValidateDelivery();
547}
548
549// Testing that packets are delivered via all routes using a routing scheme as
550// follows:
551// * e1 -> n1 -> e2
552// * e2 -> n2 -> e1
553// * e1 -> n1 -> e3
554// * e3 -> n4 -> e1
555TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
556 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeersOverSameSendLink) {
557 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
558 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
559 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
560 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
561 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
562
563 emulation->CreateRoute(e1, {node1}, e2);
564 emulation->CreateRoute(e2, {node2}, e1);
565
566 emulation->CreateRoute(e1, {node1}, e3);
567 emulation->CreateRoute(e3, {node3}, e1);
568 });
569 SendPacketsAndValidateDelivery();
570}
571
Artem Titov5d555972020-11-12 16:15:44 +0100572TEST(NetworkEmulationManagerTest, EndpointLoopback) {
573 NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
574 auto endpoint = network_manager.CreateEndpoint(EmulatedEndpointConfig());
575
576 MockReceiver receiver;
577 EXPECT_CALL(receiver, OnPacketReceived(::testing::_)).Times(1);
578 ASSERT_EQ(endpoint->BindReceiver(80, &receiver), 80);
579
580 endpoint->SendPacket(rtc::SocketAddress(endpoint->GetPeerLocalAddress(), 80),
581 rtc::SocketAddress(endpoint->GetPeerLocalAddress(), 80),
582 "Hello");
583 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
584}
585
Artem Titov3d37e062021-02-19 20:26:32 +0100586TEST(NetworkEmulationManagerTest, EndpointCanSendWithDifferentSourceIp) {
587 constexpr uint32_t kEndpointIp = 0xC0A80011; // 192.168.0.17
588 constexpr uint32_t kSourceIp = 0xC0A80012; // 192.168.0.18
589 NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
590 EmulatedEndpointConfig endpoint_config;
591 endpoint_config.ip = rtc::IPAddress(kEndpointIp);
592 endpoint_config.allow_send_packet_with_different_source_ip = true;
593 auto endpoint = network_manager.CreateEndpoint(endpoint_config);
594
595 MockReceiver receiver;
596 EXPECT_CALL(receiver, OnPacketReceived(::testing::_)).Times(1);
597 ASSERT_EQ(endpoint->BindReceiver(80, &receiver), 80);
598
599 endpoint->SendPacket(rtc::SocketAddress(kSourceIp, 80),
600 rtc::SocketAddress(endpoint->GetPeerLocalAddress(), 80),
601 "Hello");
602 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
603}
604
605TEST(NetworkEmulationManagerTest,
606 EndpointCanReceiveWithDifferentDestIpThroughDefaultRoute) {
607 constexpr uint32_t kDestEndpointIp = 0xC0A80011; // 192.168.0.17
608 constexpr uint32_t kDestIp = 0xC0A80012; // 192.168.0.18
609 NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
610 auto sender_endpoint =
611 network_manager.CreateEndpoint(EmulatedEndpointConfig());
612 EmulatedEndpointConfig endpoint_config;
613 endpoint_config.ip = rtc::IPAddress(kDestEndpointIp);
614 endpoint_config.allow_receive_packets_with_different_dest_ip = true;
615 auto receiver_endpoint = network_manager.CreateEndpoint(endpoint_config);
616
617 MockReceiver receiver;
618 EXPECT_CALL(receiver, OnPacketReceived(::testing::_)).Times(1);
619 ASSERT_EQ(receiver_endpoint->BindReceiver(80, &receiver), 80);
620
621 network_manager.CreateDefaultRoute(
622 sender_endpoint, {network_manager.NodeBuilder().Build().node},
623 receiver_endpoint);
624
625 sender_endpoint->SendPacket(
626 rtc::SocketAddress(sender_endpoint->GetPeerLocalAddress(), 80),
627 rtc::SocketAddress(kDestIp, 80), "Hello");
628 network_manager.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
629}
630
Jonas Oreland97050112020-11-17 21:30:33 +0100631TEST(NetworkEmulationManagerTURNTest, GetIceServerConfig) {
632 NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
633 auto turn = network_manager.CreateTURNServer(EmulatedTURNServerConfig());
634
635 EXPECT_GT(turn->GetIceServerConfig().username.size(), 0u);
636 EXPECT_GT(turn->GetIceServerConfig().password.size(), 0u);
637 EXPECT_NE(turn->GetIceServerConfig().url.find(
638 turn->GetClientEndpoint()->GetPeerLocalAddress().ToString()),
639 std::string::npos);
640}
641
642TEST(NetworkEmulationManagerTURNTest, ClientTraffic) {
643 NetworkEmulationManagerImpl emulation(TimeMode::kSimulated);
644 auto* ep = emulation.CreateEndpoint(EmulatedEndpointConfig());
645 auto* turn = emulation.CreateTURNServer(EmulatedTURNServerConfig());
646 auto* node = CreateEmulatedNodeWithDefaultBuiltInConfig(&emulation);
647 emulation.CreateRoute(ep, {node}, turn->GetClientEndpoint());
648 emulation.CreateRoute(turn->GetClientEndpoint(), {node}, ep);
649
650 MockReceiver recv;
651 int port = ep->BindReceiver(0, &recv).value();
652
653 // Construct a STUN BINDING.
654 cricket::StunMessage ping;
655 ping.SetType(cricket::STUN_BINDING_REQUEST);
656 rtc::ByteBufferWriter buf;
657 ping.Write(&buf);
658 rtc::CopyOnWriteBuffer packet(buf.Data(), buf.Length());
659
660 // We expect to get a ping reply.
661 EXPECT_CALL(recv, OnPacketReceived(::testing::_)).Times(1);
662
663 ep->SendPacket(rtc::SocketAddress(ep->GetPeerLocalAddress(), port),
664 turn->GetClientEndpointAddress(), packet);
665 emulation.time_controller()->AdvanceTime(TimeDelta::Seconds(1));
666}
667
Artem Titov0774bd92019-01-30 15:26:05 +0100668} // namespace test
669} // namespace webrtc