blob: 30d02be453e5ec96dbbc8790f2c38fdba89f5c5e [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;
Niels Möller7536bc52019-10-04 13:54:39 +020033constexpr int kOverheadIpv4Udp = 20 + 8;
Artem Titov0774bd92019-01-30 15:26:05 +010034
35class SocketReader : public sigslot::has_slots<> {
36 public:
Artem Titov519d74a2019-05-17 12:01:00 +020037 explicit SocketReader(rtc::AsyncSocket* socket, rtc::Thread* network_thread)
38 : socket_(socket), network_thread_(network_thread) {
Artem Titov0774bd92019-01-30 15:26:05 +010039 socket_->SignalReadEvent.connect(this, &SocketReader::OnReadEvent);
40 size_ = 128 * 1024;
41 buf_ = new char[size_];
42 }
43 ~SocketReader() override { delete[] buf_; }
44
45 void OnReadEvent(rtc::AsyncSocket* socket) {
46 RTC_DCHECK(socket_ == socket);
Artem Titov519d74a2019-05-17 12:01:00 +020047 network_thread_->PostTask(RTC_FROM_HERE, [this]() {
48 int64_t timestamp;
49 len_ = socket_->Recv(buf_, size_, &timestamp);
50
Artem Titov0774bd92019-01-30 15:26:05 +010051 rtc::CritScope crit(&lock_);
52 received_count_++;
Artem Titov519d74a2019-05-17 12:01:00 +020053 });
Artem Titov0774bd92019-01-30 15:26:05 +010054 }
55
56 int ReceivedCount() {
57 rtc::CritScope crit(&lock_);
58 return received_count_;
59 }
60
61 private:
Artem Titov519d74a2019-05-17 12:01:00 +020062 rtc::AsyncSocket* const socket_;
63 rtc::Thread* const network_thread_;
Artem Titov0774bd92019-01-30 15:26:05 +010064 char* buf_;
65 size_t size_;
66 int len_;
67
68 rtc::CriticalSection lock_;
69 int received_count_ RTC_GUARDED_BY(lock_) = 0;
70};
71
Artem Titovff393122019-04-05 11:19:52 +020072class MockReceiver : public EmulatedNetworkReceiverInterface {
73 public:
74 MOCK_METHOD1(OnPacketReceived, void(EmulatedIpPacket packet));
75};
76
77class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
78 public:
79 NetworkEmulationManagerThreeNodesRoutingTest() {
80 e1_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
81 e2_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
82 e3_ = emulation_.CreateEndpoint(EmulatedEndpointConfig());
83 }
84
85 void SetupRouting(
86 std::function<void(EmulatedEndpoint*,
87 EmulatedEndpoint*,
88 EmulatedEndpoint*,
89 NetworkEmulationManager*)> create_routing_func) {
90 create_routing_func(e1_, e2_, e3_, &emulation_);
91 }
92
93 void SendPacketsAndValidateDelivery() {
Mirko Bonadei6a489f22019-04-09 15:11:12 +020094 EXPECT_CALL(r_e1_e2_, OnPacketReceived(::testing::_)).Times(1);
95 EXPECT_CALL(r_e2_e1_, OnPacketReceived(::testing::_)).Times(1);
96 EXPECT_CALL(r_e1_e3_, OnPacketReceived(::testing::_)).Times(1);
97 EXPECT_CALL(r_e3_e1_, OnPacketReceived(::testing::_)).Times(1);
Artem Titovff393122019-04-05 11:19:52 +020098
99 uint16_t common_send_port = 80;
100 uint16_t r_e1_e2_port = e2_->BindReceiver(0, &r_e1_e2_).value();
101 uint16_t r_e2_e1_port = e1_->BindReceiver(0, &r_e2_e1_).value();
102 uint16_t r_e1_e3_port = e3_->BindReceiver(0, &r_e1_e3_).value();
103 uint16_t r_e3_e1_port = e1_->BindReceiver(0, &r_e3_e1_).value();
104
105 // Next code is using API of EmulatedEndpoint, that is visible only for
106 // internals of network emulation layer. Don't use this API in other tests.
107 // Send packet from e1 to e2.
108 e1_->SendPacket(
109 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
110 rtc::SocketAddress(e2_->GetPeerLocalAddress(), r_e1_e2_port),
111 rtc::CopyOnWriteBuffer(10));
112
113 // Send packet from e2 to e1.
114 e2_->SendPacket(
115 rtc::SocketAddress(e2_->GetPeerLocalAddress(), common_send_port),
116 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e2_e1_port),
117 rtc::CopyOnWriteBuffer(10));
118
119 // Send packet from e1 to e3.
120 e1_->SendPacket(
121 rtc::SocketAddress(e1_->GetPeerLocalAddress(), common_send_port),
122 rtc::SocketAddress(e3_->GetPeerLocalAddress(), r_e1_e3_port),
123 rtc::CopyOnWriteBuffer(10));
124
125 // Send packet from e3 to e1.
126 e3_->SendPacket(
127 rtc::SocketAddress(e3_->GetPeerLocalAddress(), common_send_port),
128 rtc::SocketAddress(e1_->GetPeerLocalAddress(), r_e3_e1_port),
129 rtc::CopyOnWriteBuffer(10));
130
131 // Sleep at the end to wait for async packets delivery.
132 SleepMs(kNetworkPacketWaitTimeoutMs);
133 }
134
135 private:
136 // Receivers: r_<source endpoint>_<destination endpoint>
137 // They must be destroyed after emulation, so they should be declared before.
138 MockReceiver r_e1_e2_;
139 MockReceiver r_e2_e1_;
140 MockReceiver r_e1_e3_;
141 MockReceiver r_e3_e1_;
142
143 NetworkEmulationManagerImpl emulation_;
144 EmulatedEndpoint* e1_;
145 EmulatedEndpoint* e2_;
146 EmulatedEndpoint* e3_;
147};
148
149EmulatedNetworkNode* CreateEmulatedNodeWithDefaultBuiltInConfig(
150 NetworkEmulationManager* emulation) {
151 return emulation->CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200152 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovff393122019-04-05 11:19:52 +0200153}
154
155} // namespace
156
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200157using ::testing::_;
Artem Titovff393122019-04-05 11:19:52 +0200158
Artem Titov0bf4c292019-02-26 10:00:07 +0100159TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100160 NetworkEmulationManagerImpl network_manager;
Artem Titov0bf4c292019-02-26 10:00:07 +0100161 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100162 EmulatedEndpointConfig config;
163 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv4;
Artem Titov0bf4c292019-02-26 10:00:07 +0100164 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100165 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100166 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET);
167 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
168 ASSERT_TRUE(result);
169 }
170}
171
172TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100173 NetworkEmulationManagerImpl network_manager;
Artem Titov0bf4c292019-02-26 10:00:07 +0100174 std::set<rtc::IPAddress> ips;
Artem Titova268b692019-03-12 13:37:28 +0100175 EmulatedEndpointConfig config;
176 config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv6;
Artem Titov0bf4c292019-02-26 10:00:07 +0100177 for (int i = 0; i < 1000; i++) {
Artem Titovaba8dc22019-03-11 10:08:40 +0100178 EmulatedEndpoint* endpoint = network_manager.CreateEndpoint(config);
Artem Titov0bf4c292019-02-26 10:00:07 +0100179 ASSERT_EQ(endpoint->GetPeerLocalAddress().family(), AF_INET6);
180 bool result = ips.insert(endpoint->GetPeerLocalAddress()).second;
181 ASSERT_TRUE(result);
182 }
183}
184
Artem Titov0774bd92019-01-30 15:26:05 +0100185TEST(NetworkEmulationManagerTest, Run) {
Artem Titov7bf8c7f2019-03-15 15:00:37 +0100186 NetworkEmulationManagerImpl network_manager;
Artem Titov0774bd92019-01-30 15:26:05 +0100187
188 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200189 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov0774bd92019-01-30 15:26:05 +0100190 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200191 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titovaba8dc22019-03-11 10:08:40 +0100192 EmulatedEndpoint* alice_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100193 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titovaba8dc22019-03-11 10:08:40 +0100194 EmulatedEndpoint* bob_endpoint =
Artem Titova268b692019-03-12 13:37:28 +0100195 network_manager.CreateEndpoint(EmulatedEndpointConfig());
Artem Titov0774bd92019-01-30 15:26:05 +0100196 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
197 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
198
Artem Titove5cc85b2019-03-28 12:11:09 +0100199 EmulatedNetworkManagerInterface* nt1 =
200 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
201 EmulatedNetworkManagerInterface* nt2 =
202 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
Artem Titov0774bd92019-01-30 15:26:05 +0100203
Artem Titov806299e2019-04-12 12:17:19 +0200204 rtc::CopyOnWriteBuffer data("Hello");
Artem Titov0774bd92019-01-30 15:26:05 +0100205 for (uint64_t j = 0; j < 2; j++) {
Artem Titove5cc85b2019-03-28 12:11:09 +0100206 auto* s1 = nt1->network_thread()->socketserver()->CreateAsyncSocket(
207 AF_INET, SOCK_DGRAM);
208 auto* s2 = nt2->network_thread()->socketserver()->CreateAsyncSocket(
209 AF_INET, SOCK_DGRAM);
Artem Titov0774bd92019-01-30 15:26:05 +0100210
Artem Titov519d74a2019-05-17 12:01:00 +0200211 SocketReader r1(s1, nt1->network_thread());
212 SocketReader r2(s2, nt2->network_thread());
Artem Titov0774bd92019-01-30 15:26:05 +0100213
214 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
215 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
216
217 s1->Bind(a1);
218 s2->Bind(a2);
219
Artem Titove5cc85b2019-03-28 12:11:09 +0100220 s1->Connect(s2->GetLocalAddress());
221 s2->Connect(s1->GetLocalAddress());
Artem Titov0774bd92019-01-30 15:26:05 +0100222
Artem Titov0774bd92019-01-30 15:26:05 +0100223 for (uint64_t i = 0; i < 1000; i++) {
Artem Titov519d74a2019-05-17 12:01:00 +0200224 nt1->network_thread()->PostTask(
225 RTC_FROM_HERE, [&]() { s1->Send(data.data(), data.size()); });
226 nt2->network_thread()->PostTask(
227 RTC_FROM_HERE, [&]() { s2->Send(data.data(), data.size()); });
Artem Titov0774bd92019-01-30 15:26:05 +0100228 }
229
230 rtc::Event wait;
231 wait.Wait(1000);
Artem Titov806299e2019-04-12 12:17:19 +0200232 EXPECT_EQ(r1.ReceivedCount(), 1000);
233 EXPECT_EQ(r2.ReceivedCount(), 1000);
Artem Titov0774bd92019-01-30 15:26:05 +0100234
235 delete s1;
236 delete s2;
237 }
Artem Titov806299e2019-04-12 12:17:19 +0200238
Niels Möller7536bc52019-10-04 13:54:39 +0200239 const int64_t single_packet_size = data.size() + kOverheadIpv4Udp;
Artem Titov806299e2019-04-12 12:17:19 +0200240 std::atomic<int> received_stats_count{0};
241 nt1->GetStats([&](EmulatedNetworkStats st) {
242 EXPECT_EQ(st.packets_sent, 2000l);
243 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
244 EXPECT_EQ(st.packets_received, 2000l);
245 EXPECT_EQ(st.bytes_received.bytes(), single_packet_size * 2000l);
246 EXPECT_EQ(st.packets_dropped, 0l);
247 EXPECT_EQ(st.bytes_dropped.bytes(), 0l);
248 received_stats_count++;
249 });
250 nt2->GetStats([&](EmulatedNetworkStats st) {
251 EXPECT_EQ(st.packets_sent, 2000l);
252 EXPECT_EQ(st.bytes_sent.bytes(), single_packet_size * 2000l);
253 EXPECT_EQ(st.packets_received, 2000l);
254 EXPECT_EQ(st.bytes_received.bytes(), single_packet_size * 2000l);
255 EXPECT_EQ(st.packets_dropped, 0l);
256 EXPECT_EQ(st.bytes_dropped.bytes(), 0l);
257 received_stats_count++;
258 });
259 ASSERT_EQ_WAIT(received_stats_count.load(), 2, kStatsWaitTimeoutMs);
260}
261
Artem Titova7683452019-05-15 12:26:38 +0200262TEST(NetworkEmulationManagerTest, ThroughputStats) {
Artem Titov806299e2019-04-12 12:17:19 +0200263 NetworkEmulationManagerImpl network_manager;
264
265 EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200266 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200267 EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200268 std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
Artem Titov806299e2019-04-12 12:17:19 +0200269 EmulatedEndpoint* alice_endpoint =
270 network_manager.CreateEndpoint(EmulatedEndpointConfig());
271 EmulatedEndpoint* bob_endpoint =
272 network_manager.CreateEndpoint(EmulatedEndpointConfig());
273 network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
274 network_manager.CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
275
276 EmulatedNetworkManagerInterface* nt1 =
277 network_manager.CreateEmulatedNetworkManagerInterface({alice_endpoint});
278 EmulatedNetworkManagerInterface* nt2 =
279 network_manager.CreateEmulatedNetworkManagerInterface({bob_endpoint});
280
Niels Möller7536bc52019-10-04 13:54:39 +0200281 constexpr int64_t kUdpPayloadSize = 100;
282 constexpr int64_t kSinglePacketSize = kUdpPayloadSize + kOverheadIpv4Udp;
283 rtc::CopyOnWriteBuffer data(kUdpPayloadSize);
Artem Titov806299e2019-04-12 12:17:19 +0200284 auto* s1 = nt1->network_thread()->socketserver()->CreateAsyncSocket(
285 AF_INET, SOCK_DGRAM);
286 auto* s2 = nt2->network_thread()->socketserver()->CreateAsyncSocket(
287 AF_INET, SOCK_DGRAM);
288
Artem Titov519d74a2019-05-17 12:01:00 +0200289 SocketReader r1(s1, nt1->network_thread());
290 SocketReader r2(s2, nt2->network_thread());
Artem Titov806299e2019-04-12 12:17:19 +0200291
292 rtc::SocketAddress a1(alice_endpoint->GetPeerLocalAddress(), 0);
293 rtc::SocketAddress a2(bob_endpoint->GetPeerLocalAddress(), 0);
294
295 s1->Bind(a1);
296 s2->Bind(a2);
297
298 s1->Connect(s2->GetLocalAddress());
299 s2->Connect(s1->GetLocalAddress());
300
Yves Gereyb64d65e2019-09-06 16:35:20 +0200301 // Send 11 packets, totalizing 1 second between the first and the last.
302 const int kNumPacketsSent = 11;
303 const int kDelayMs = 100;
Artem Titov806299e2019-04-12 12:17:19 +0200304 rtc::Event wait;
Yves Gereyb64d65e2019-09-06 16:35:20 +0200305 for (int i = 0; i < kNumPacketsSent; i++) {
Artem Titov519d74a2019-05-17 12:01:00 +0200306 nt1->network_thread()->PostTask(
307 RTC_FROM_HERE, [&]() { s1->Send(data.data(), data.size()); });
308 nt2->network_thread()->PostTask(
309 RTC_FROM_HERE, [&]() { s2->Send(data.data(), data.size()); });
Yves Gereyb64d65e2019-09-06 16:35:20 +0200310 wait.Wait(kDelayMs);
Artem Titov806299e2019-04-12 12:17:19 +0200311 }
Artem Titov806299e2019-04-12 12:17:19 +0200312
Artem Titov806299e2019-04-12 12:17:19 +0200313 std::atomic<int> received_stats_count{0};
314 nt1->GetStats([&](EmulatedNetworkStats st) {
Yves Gereyb64d65e2019-09-06 16:35:20 +0200315 EXPECT_EQ(st.packets_sent, kNumPacketsSent);
Niels Möller7536bc52019-10-04 13:54:39 +0200316 EXPECT_EQ(st.bytes_sent.bytes(), kSinglePacketSize * kNumPacketsSent);
Yves Gereyb64d65e2019-09-06 16:35:20 +0200317
Yves Gereyc65de422019-11-08 20:29:04 +0100318 const double tolerance = 0.95; // Accept 5% tolerance for timing.
Artem Titova7683452019-05-15 12:26:38 +0200319 EXPECT_GE(st.last_packet_sent_time - st.first_packet_sent_time,
Yves Gereyb64d65e2019-09-06 16:35:20 +0200320 TimeDelta::ms((kNumPacketsSent - 1) * kDelayMs * tolerance));
Artem Titova7683452019-05-15 12:26:38 +0200321 EXPECT_GT(st.AverageSendRate().bps(), 0);
Artem Titov806299e2019-04-12 12:17:19 +0200322 received_stats_count++;
323 });
324 ASSERT_EQ_WAIT(received_stats_count.load(), 1, kStatsWaitTimeoutMs);
Artem Titova7683452019-05-15 12:26:38 +0200325 EXPECT_EQ(r1.ReceivedCount(), 11);
326 EXPECT_EQ(r2.ReceivedCount(), 11);
Artem Titov519d74a2019-05-17 12:01:00 +0200327
328 delete s1;
329 delete s2;
Artem Titov0774bd92019-01-30 15:26:05 +0100330}
331
Artem Titovff393122019-04-05 11:19:52 +0200332// Testing that packets are delivered via all routes using a routing scheme as
333// follows:
334// * e1 -> n1 -> e2
335// * e2 -> n2 -> e1
336// * e1 -> n3 -> e3
337// * e3 -> n4 -> e1
338TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
339 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeers) {
340 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
341 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
342 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
343 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
344 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
345 auto* node4 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
346
347 emulation->CreateRoute(e1, {node1}, e2);
348 emulation->CreateRoute(e2, {node2}, e1);
349
350 emulation->CreateRoute(e1, {node3}, e3);
351 emulation->CreateRoute(e3, {node4}, e1);
352 });
353 SendPacketsAndValidateDelivery();
354}
355
356// Testing that packets are delivered via all routes using a routing scheme as
357// follows:
358// * e1 -> n1 -> e2
359// * e2 -> n2 -> e1
360// * e1 -> n1 -> e3
361// * e3 -> n4 -> e1
362TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
363 PacketsAreDeliveredInBothWaysWhenConnectedToTwoPeersOverSameSendLink) {
364 SetupRouting([](EmulatedEndpoint* e1, EmulatedEndpoint* e2,
365 EmulatedEndpoint* e3, NetworkEmulationManager* emulation) {
366 auto* node1 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
367 auto* node2 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
368 auto* node3 = CreateEmulatedNodeWithDefaultBuiltInConfig(emulation);
369
370 emulation->CreateRoute(e1, {node1}, e2);
371 emulation->CreateRoute(e2, {node2}, e1);
372
373 emulation->CreateRoute(e1, {node1}, e3);
374 emulation->CreateRoute(e3, {node3}, e1);
375 });
376 SendPacketsAndValidateDelivery();
377}
378
Artem Titov0774bd92019-01-30 15:26:05 +0100379} // namespace test
380} // namespace webrtc