• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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