1 /*
2 * Copyright (c) 2012 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 "call/fake_network_pipe.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "call/simulated_network.h"
17 #include "system_wrappers/include/clock.h"
18 #include "test/gmock.h"
19 #include "test/gtest.h"
20
21 using ::testing::_;
22
23 namespace webrtc {
24
25 class MockReceiver : public PacketReceiver {
26 public:
27 MOCK_METHOD(DeliveryStatus,
28 DeliverPacket,
29 (MediaType, rtc::CopyOnWriteBuffer, int64_t),
30 (override));
31 virtual ~MockReceiver() = default;
32 };
33
34 class ReorderTestReceiver : public MockReceiver {
35 public:
DeliverPacket(MediaType media_type,rtc::CopyOnWriteBuffer packet,int64_t)36 DeliveryStatus DeliverPacket(MediaType media_type,
37 rtc::CopyOnWriteBuffer packet,
38 int64_t /* packet_time_us */) override {
39 RTC_DCHECK_GE(packet.size(), sizeof(int));
40 int seq_num;
41 memcpy(&seq_num, packet.data<uint8_t>(), sizeof(int));
42 delivered_sequence_numbers_.push_back(seq_num);
43 return DeliveryStatus::DELIVERY_OK;
44 }
45 std::vector<int> delivered_sequence_numbers_;
46 };
47
48 class FakeNetworkPipeTest : public ::testing::Test {
49 public:
FakeNetworkPipeTest()50 FakeNetworkPipeTest() : fake_clock_(12345) {}
51
52 protected:
SendPackets(FakeNetworkPipe * pipe,int number_packets,int packet_size)53 void SendPackets(FakeNetworkPipe* pipe, int number_packets, int packet_size) {
54 RTC_DCHECK_GE(packet_size, sizeof(int));
55 std::unique_ptr<uint8_t[]> packet(new uint8_t[packet_size]);
56 for (int i = 0; i < number_packets; ++i) {
57 // Set a sequence number for the packets by
58 // using the first bytes in the packet.
59 memcpy(packet.get(), &i, sizeof(int));
60 rtc::CopyOnWriteBuffer buffer(packet.get(), packet_size);
61 pipe->DeliverPacket(MediaType::ANY, buffer, /* packet_time_us */ -1);
62 }
63 }
64
PacketTimeMs(int capacity_kbps,int packet_size) const65 int PacketTimeMs(int capacity_kbps, int packet_size) const {
66 return 8 * packet_size / capacity_kbps;
67 }
68
69 SimulatedClock fake_clock_;
70 };
71
72 // Test the capacity link and verify we get as many packets as we expect.
TEST_F(FakeNetworkPipeTest,CapacityTest)73 TEST_F(FakeNetworkPipeTest, CapacityTest) {
74 BuiltInNetworkBehaviorConfig config;
75 config.queue_length_packets = 20;
76 config.link_capacity_kbps = 80;
77 MockReceiver receiver;
78 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
79 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
80 &fake_clock_, std::move(simulated_network), &receiver));
81
82 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
83 // get through the pipe.
84 const int kNumPackets = 10;
85 const int kPacketSize = 1000;
86 SendPackets(pipe.get(), kNumPackets, kPacketSize);
87
88 // Time to get one packet through the link.
89 const int kPacketTimeMs =
90 PacketTimeMs(config.link_capacity_kbps, kPacketSize);
91
92 // Time haven't increased yet, so we souldn't get any packets.
93 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
94 pipe->Process();
95
96 // Advance enough time to release one packet.
97 fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
98 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
99 pipe->Process();
100
101 // Release all but one packet
102 fake_clock_.AdvanceTimeMilliseconds(9 * kPacketTimeMs - 1);
103 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(8);
104 pipe->Process();
105
106 // And the last one.
107 fake_clock_.AdvanceTimeMilliseconds(1);
108 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
109 pipe->Process();
110 }
111
112 // Test the extra network delay.
TEST_F(FakeNetworkPipeTest,ExtraDelayTest)113 TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
114 BuiltInNetworkBehaviorConfig config;
115 config.queue_length_packets = 20;
116 config.queue_delay_ms = 100;
117 config.link_capacity_kbps = 80;
118 MockReceiver receiver;
119 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
120 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
121 &fake_clock_, std::move(simulated_network), &receiver));
122
123 const int kNumPackets = 2;
124 const int kPacketSize = 1000;
125 SendPackets(pipe.get(), kNumPackets, kPacketSize);
126
127 // Time to get one packet through the link.
128 const int kPacketTimeMs =
129 PacketTimeMs(config.link_capacity_kbps, kPacketSize);
130
131 // Increase more than kPacketTimeMs, but not more than the extra delay.
132 fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
133 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
134 pipe->Process();
135
136 // Advance the network delay to get the first packet.
137 fake_clock_.AdvanceTimeMilliseconds(config.queue_delay_ms);
138 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
139 pipe->Process();
140
141 // Advance one more kPacketTimeMs to get the last packet.
142 fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
143 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
144 pipe->Process();
145 }
146
147 // Test the number of buffers and packets are dropped when sending too many
148 // packets too quickly.
TEST_F(FakeNetworkPipeTest,QueueLengthTest)149 TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
150 BuiltInNetworkBehaviorConfig config;
151 config.queue_length_packets = 2;
152 config.link_capacity_kbps = 80;
153 MockReceiver receiver;
154 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
155 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
156 &fake_clock_, std::move(simulated_network), &receiver));
157
158 const int kPacketSize = 1000;
159 const int kPacketTimeMs =
160 PacketTimeMs(config.link_capacity_kbps, kPacketSize);
161
162 // Send three packets and verify only 2 are delivered.
163 SendPackets(pipe.get(), 3, kPacketSize);
164
165 // Increase time enough to deliver all three packets, verify only two are
166 // delivered.
167 fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs);
168 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(2);
169 pipe->Process();
170 }
171
172 // Test we get statistics as expected.
TEST_F(FakeNetworkPipeTest,StatisticsTest)173 TEST_F(FakeNetworkPipeTest, StatisticsTest) {
174 BuiltInNetworkBehaviorConfig config;
175 config.queue_length_packets = 2;
176 config.queue_delay_ms = 20;
177 config.link_capacity_kbps = 80;
178 MockReceiver receiver;
179 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
180 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
181 &fake_clock_, std::move(simulated_network), &receiver));
182
183 const int kPacketSize = 1000;
184 const int kPacketTimeMs =
185 PacketTimeMs(config.link_capacity_kbps, kPacketSize);
186
187 // Send three packets and verify only 2 are delivered.
188 SendPackets(pipe.get(), 3, kPacketSize);
189 fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs +
190 config.queue_delay_ms);
191
192 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(2);
193 pipe->Process();
194
195 // Packet 1: kPacketTimeMs + config.queue_delay_ms,
196 // packet 2: 2 * kPacketTimeMs + config.queue_delay_ms => 170 ms average.
197 EXPECT_EQ(pipe->AverageDelay(), 170);
198 EXPECT_EQ(pipe->SentPackets(), 2u);
199 EXPECT_EQ(pipe->DroppedPackets(), 1u);
200 EXPECT_EQ(pipe->PercentageLoss(), 1 / 3.f);
201 }
202
203 // Change the link capacity half-way through the test and verify that the
204 // delivery times change accordingly.
TEST_F(FakeNetworkPipeTest,ChangingCapacityWithEmptyPipeTest)205 TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
206 BuiltInNetworkBehaviorConfig config;
207 config.queue_length_packets = 20;
208 config.link_capacity_kbps = 80;
209 MockReceiver receiver;
210 std::unique_ptr<SimulatedNetwork> network(new SimulatedNetwork(config));
211 SimulatedNetwork* simulated_network = network.get();
212 std::unique_ptr<FakeNetworkPipe> pipe(
213 new FakeNetworkPipe(&fake_clock_, std::move(network), &receiver));
214
215 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
216 // get through the pipe.
217 const int kNumPackets = 10;
218 const int kPacketSize = 1000;
219 SendPackets(pipe.get(), kNumPackets, kPacketSize);
220
221 // Time to get one packet through the link.
222 int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
223
224 // Time hasn't increased yet, so we souldn't get any packets.
225 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
226 pipe->Process();
227
228 // Advance time in steps to release one packet at a time.
229 for (int i = 0; i < kNumPackets; ++i) {
230 fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
231 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
232 pipe->Process();
233 }
234
235 // Change the capacity.
236 config.link_capacity_kbps /= 2; // Reduce to 50%.
237 simulated_network->SetConfig(config);
238
239 // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
240 // seconds to get them through the pipe.
241 SendPackets(pipe.get(), kNumPackets, kPacketSize);
242
243 // Time to get one packet through the link.
244 packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
245
246 // Time hasn't increased yet, so we souldn't get any packets.
247 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
248 pipe->Process();
249
250 // Advance time in steps to release one packet at a time.
251 for (int i = 0; i < kNumPackets; ++i) {
252 fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
253 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
254 pipe->Process();
255 }
256
257 // Check that all the packets were sent.
258 EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->SentPackets());
259 EXPECT_FALSE(pipe->TimeUntilNextProcess().has_value());
260 fake_clock_.AdvanceTimeMilliseconds(1000);
261 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
262 pipe->Process();
263 }
264
265 // Change the link capacity half-way through the test and verify that the
266 // delivery times change accordingly.
TEST_F(FakeNetworkPipeTest,ChangingCapacityWithPacketsInPipeTest)267 TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
268 BuiltInNetworkBehaviorConfig config;
269 config.queue_length_packets = 20;
270 config.link_capacity_kbps = 80;
271 MockReceiver receiver;
272 std::unique_ptr<SimulatedNetwork> network(new SimulatedNetwork(config));
273 SimulatedNetwork* simulated_network = network.get();
274 std::unique_ptr<FakeNetworkPipe> pipe(
275 new FakeNetworkPipe(&fake_clock_, std::move(network), &receiver));
276
277 // Add 20 packets of 1000 bytes, = 80 kb.
278 const int kNumPackets = 20;
279 const int kPacketSize = 1000;
280 SendPackets(pipe.get(), kNumPackets, kPacketSize);
281
282 // Time hasn't increased yet, so we souldn't get any packets.
283 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
284 pipe->Process();
285
286 // Advance time in steps to release half of the packets one at a time.
287 int step_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
288 for (int i = 0; i < kNumPackets / 2; ++i) {
289 fake_clock_.AdvanceTimeMilliseconds(step_ms);
290 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
291 pipe->Process();
292 }
293
294 // Change the capacity.
295 config.link_capacity_kbps *= 2; // Double the capacity.
296 simulated_network->SetConfig(config);
297
298 // Advance time in steps to release remaining packets one at a time.
299 step_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
300 for (int i = 0; i < kNumPackets / 2; ++i) {
301 fake_clock_.AdvanceTimeMilliseconds(step_ms);
302 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
303 pipe->Process();
304 }
305
306 // Check that all the packets were sent.
307 EXPECT_EQ(static_cast<size_t>(kNumPackets), pipe->SentPackets());
308 EXPECT_FALSE(pipe->TimeUntilNextProcess().has_value());
309 fake_clock_.AdvanceTimeMilliseconds(1000);
310 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
311 pipe->Process();
312 }
313
314 // At first disallow reordering and then allow reordering.
TEST_F(FakeNetworkPipeTest,DisallowReorderingThenAllowReordering)315 TEST_F(FakeNetworkPipeTest, DisallowReorderingThenAllowReordering) {
316 BuiltInNetworkBehaviorConfig config;
317 config.queue_length_packets = 1000;
318 config.link_capacity_kbps = 800;
319 config.queue_delay_ms = 100;
320 config.delay_standard_deviation_ms = 10;
321 ReorderTestReceiver receiver;
322 std::unique_ptr<SimulatedNetwork> network(new SimulatedNetwork(config));
323 SimulatedNetwork* simulated_network = network.get();
324 std::unique_ptr<FakeNetworkPipe> pipe(
325 new FakeNetworkPipe(&fake_clock_, std::move(network), &receiver));
326
327 const uint32_t kNumPackets = 100;
328 const int kPacketSize = 10;
329 SendPackets(pipe.get(), kNumPackets, kPacketSize);
330 fake_clock_.AdvanceTimeMilliseconds(1000);
331 pipe->Process();
332
333 // Confirm that all packets have been delivered in order.
334 EXPECT_EQ(kNumPackets, receiver.delivered_sequence_numbers_.size());
335 int last_seq_num = -1;
336 for (int seq_num : receiver.delivered_sequence_numbers_) {
337 EXPECT_GT(seq_num, last_seq_num);
338 last_seq_num = seq_num;
339 }
340
341 config.allow_reordering = true;
342 simulated_network->SetConfig(config);
343 SendPackets(pipe.get(), kNumPackets, kPacketSize);
344 fake_clock_.AdvanceTimeMilliseconds(1000);
345 receiver.delivered_sequence_numbers_.clear();
346 pipe->Process();
347
348 // Confirm that all packets have been delivered
349 // and that reordering has occured.
350 EXPECT_EQ(kNumPackets, receiver.delivered_sequence_numbers_.size());
351 bool reordering_has_occured = false;
352 last_seq_num = -1;
353 for (int seq_num : receiver.delivered_sequence_numbers_) {
354 if (last_seq_num > seq_num) {
355 reordering_has_occured = true;
356 break;
357 }
358 last_seq_num = seq_num;
359 }
360 EXPECT_TRUE(reordering_has_occured);
361 }
362
TEST_F(FakeNetworkPipeTest,BurstLoss)363 TEST_F(FakeNetworkPipeTest, BurstLoss) {
364 const int kLossPercent = 5;
365 const int kAvgBurstLength = 3;
366 const int kNumPackets = 10000;
367 const int kPacketSize = 10;
368
369 BuiltInNetworkBehaviorConfig config;
370 config.queue_length_packets = kNumPackets;
371 config.loss_percent = kLossPercent;
372 config.avg_burst_loss_length = kAvgBurstLength;
373 ReorderTestReceiver receiver;
374 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
375 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
376 &fake_clock_, std::move(simulated_network), &receiver));
377
378 SendPackets(pipe.get(), kNumPackets, kPacketSize);
379 fake_clock_.AdvanceTimeMilliseconds(1000);
380 pipe->Process();
381
382 // Check that the average loss is |kLossPercent| percent.
383 int lost_packets = kNumPackets - receiver.delivered_sequence_numbers_.size();
384 double loss_fraction = lost_packets / static_cast<double>(kNumPackets);
385
386 EXPECT_NEAR(kLossPercent / 100.0, loss_fraction, 0.05);
387
388 // Find the number of bursts that has occurred.
389 size_t received_packets = receiver.delivered_sequence_numbers_.size();
390 int num_bursts = 0;
391 for (size_t i = 0; i < received_packets - 1; ++i) {
392 int diff = receiver.delivered_sequence_numbers_[i + 1] -
393 receiver.delivered_sequence_numbers_[i];
394 if (diff > 1)
395 ++num_bursts;
396 }
397
398 double average_burst_length = static_cast<double>(lost_packets) / num_bursts;
399
400 EXPECT_NEAR(kAvgBurstLength, average_burst_length, 0.3);
401 }
402
TEST_F(FakeNetworkPipeTest,SetReceiver)403 TEST_F(FakeNetworkPipeTest, SetReceiver) {
404 BuiltInNetworkBehaviorConfig config;
405 config.link_capacity_kbps = 800;
406 MockReceiver receiver;
407 auto simulated_network = std::make_unique<SimulatedNetwork>(config);
408 std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
409 &fake_clock_, std::move(simulated_network), &receiver));
410
411 const int kPacketSize = 1000;
412 const int kPacketTimeMs =
413 PacketTimeMs(config.link_capacity_kbps, kPacketSize);
414 SendPackets(pipe.get(), 1, kPacketSize);
415 fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
416 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(1);
417 pipe->Process();
418
419 MockReceiver new_receiver;
420 pipe->SetReceiver(&new_receiver);
421
422 SendPackets(pipe.get(), 1, kPacketSize);
423 fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
424 EXPECT_CALL(receiver, DeliverPacket(_, _, _)).Times(0);
425 EXPECT_CALL(new_receiver, DeliverPacket(_, _, _)).Times(1);
426 pipe->Process();
427 }
428
429 } // namespace webrtc
430