fake_network_pipe_unittest.cc revision 68786d20400f1f3744ad83549325665c18ea9e5b
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 "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14#include "webrtc/base/scoped_ptr.h"
15#include "webrtc/call.h"
16#include "webrtc/system_wrappers/interface/tick_util.h"
17#include "webrtc/test/fake_network_pipe.h"
18
19using ::testing::_;
20using ::testing::AnyNumber;
21using ::testing::Return;
22using ::testing::Invoke;
23
24namespace webrtc {
25
26class MockReceiver : public PacketReceiver {
27 public:
28  MockReceiver() {}
29  virtual ~MockReceiver() {}
30
31  void IncomingPacket(const uint8_t* data, size_t length) {
32    DeliverPacket(MediaType::ANY, data, length, PacketTime());
33    delete [] data;
34  }
35
36  MOCK_METHOD4(
37      DeliverPacket,
38      DeliveryStatus(MediaType, const uint8_t*, size_t, const PacketTime&));
39};
40
41class FakeNetworkPipeTest : public ::testing::Test {
42 protected:
43  virtual void SetUp() {
44    TickTime::UseFakeClock(12345);
45    receiver_.reset(new MockReceiver());
46    ON_CALL(*receiver_, DeliverPacket(_, _, _, _))
47        .WillByDefault(Return(PacketReceiver::DELIVERY_OK));
48  }
49
50  virtual void TearDown() {
51  }
52
53  void SendPackets(FakeNetworkPipe* pipe, int number_packets, int kPacketSize) {
54    rtc::scoped_ptr<uint8_t[]> packet(new uint8_t[kPacketSize]);
55    for (int i = 0; i < number_packets; ++i) {
56      pipe->SendPacket(packet.get(), kPacketSize);
57    }
58  }
59
60  int PacketTimeMs(int capacity_kbps, int kPacketSize) const {
61    return 8 * kPacketSize / capacity_kbps;
62  }
63
64  rtc::scoped_ptr<MockReceiver> receiver_;
65};
66
67void DeleteMemory(uint8_t* data, int length) { delete [] data; }
68
69// Test the capacity link and verify we get as many packets as we expect.
70TEST_F(FakeNetworkPipeTest, CapacityTest) {
71  FakeNetworkPipe::Config config;
72  config.queue_length_packets = 20;
73  config.link_capacity_kbps = 80;
74  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
75  pipe->SetReceiver(receiver_.get());
76
77  // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
78  // get through the pipe.
79  const int kNumPackets = 10;
80  const int kPacketSize = 1000;
81  SendPackets(pipe.get(), kNumPackets , kPacketSize);
82
83  // Time to get one packet through the link.
84  const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
85                                         kPacketSize);
86
87  // Time haven't increased yet, so we souldn't get any packets.
88  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
89  pipe->Process();
90
91  // Advance enough time to release one packet.
92  TickTime::AdvanceFakeClock(kPacketTimeMs);
93  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
94  pipe->Process();
95
96  // Release all but one packet
97  TickTime::AdvanceFakeClock(9 * kPacketTimeMs - 1);
98  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(8);
99  pipe->Process();
100
101  // And the last one.
102  TickTime::AdvanceFakeClock(1);
103  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
104  pipe->Process();
105}
106
107// Test the extra network delay.
108TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
109  FakeNetworkPipe::Config config;
110  config.queue_length_packets = 20;
111  config.queue_delay_ms = 100;
112  config.link_capacity_kbps = 80;
113  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
114  pipe->SetReceiver(receiver_.get());
115
116  const int kNumPackets = 2;
117  const int kPacketSize = 1000;
118  SendPackets(pipe.get(), kNumPackets , kPacketSize);
119
120  // Time to get one packet through the link.
121  const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
122                                         kPacketSize);
123
124  // Increase more than kPacketTimeMs, but not more than the extra delay.
125  TickTime::AdvanceFakeClock(kPacketTimeMs);
126  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
127  pipe->Process();
128
129  // Advance the network delay to get the first packet.
130  TickTime::AdvanceFakeClock(config.queue_delay_ms);
131  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
132  pipe->Process();
133
134  // Advance one more kPacketTimeMs to get the last packet.
135  TickTime::AdvanceFakeClock(kPacketTimeMs);
136  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
137  pipe->Process();
138}
139
140// Test the number of buffers and packets are dropped when sending too many
141// packets too quickly.
142TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
143  FakeNetworkPipe::Config config;
144  config.queue_length_packets = 2;
145  config.link_capacity_kbps = 80;
146  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
147  pipe->SetReceiver(receiver_.get());
148
149  const int kPacketSize = 1000;
150  const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
151                                         kPacketSize);
152
153  // Send three packets and verify only 2 are delivered.
154  SendPackets(pipe.get(), 3, kPacketSize);
155
156  // Increase time enough to deliver all three packets, verify only two are
157  // delivered.
158  TickTime::AdvanceFakeClock(3 * kPacketTimeMs);
159  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(2);
160  pipe->Process();
161}
162
163// Test we get statistics as expected.
164TEST_F(FakeNetworkPipeTest, StatisticsTest) {
165  FakeNetworkPipe::Config config;
166  config.queue_length_packets = 2;
167  config.queue_delay_ms = 20;
168  config.link_capacity_kbps = 80;
169  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
170  pipe->SetReceiver(receiver_.get());
171
172  const int kPacketSize = 1000;
173  const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
174                                         kPacketSize);
175
176  // Send three packets and verify only 2 are delivered.
177  SendPackets(pipe.get(), 3, kPacketSize);
178  TickTime::AdvanceFakeClock(3 * kPacketTimeMs + config.queue_delay_ms);
179
180  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(2);
181  pipe->Process();
182
183  // Packet 1: kPacketTimeMs + config.queue_delay_ms,
184  // packet 2: 2 * kPacketTimeMs + config.queue_delay_ms => 170 ms average.
185  EXPECT_EQ(pipe->AverageDelay(), 170);
186  EXPECT_EQ(pipe->sent_packets(), 2u);
187  EXPECT_EQ(pipe->dropped_packets(), 1u);
188  EXPECT_EQ(pipe->PercentageLoss(), 1/3.f);
189}
190
191// Change the link capacity half-way through the test and verify that the
192// delivery times change accordingly.
193TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
194  FakeNetworkPipe::Config config;
195  config.queue_length_packets = 20;
196  config.link_capacity_kbps = 80;
197  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
198  pipe->SetReceiver(receiver_.get());
199
200  // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
201  // get through the pipe.
202  const int kNumPackets = 10;
203  const int kPacketSize = 1000;
204  SendPackets(pipe.get(), kNumPackets, kPacketSize);
205
206  // Time to get one packet through the link.
207  int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
208
209  // Time hasn't increased yet, so we souldn't get any packets.
210  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
211  pipe->Process();
212
213  // Advance time in steps to release one packet at a time.
214  for (int i = 0; i < kNumPackets; ++i) {
215    TickTime::AdvanceFakeClock(packet_time_ms);
216    EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
217    pipe->Process();
218  }
219
220  // Change the capacity.
221  config.link_capacity_kbps /= 2;  // Reduce to 50%.
222  pipe->SetConfig(config);
223
224  // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
225  // seconds to get them through the pipe.
226  SendPackets(pipe.get(), kNumPackets, kPacketSize);
227
228  // Time to get one packet through the link.
229  packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
230
231  // Time hasn't increased yet, so we souldn't get any packets.
232  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
233  pipe->Process();
234
235  // Advance time in steps to release one packet at a time.
236  for (int i = 0; i < kNumPackets; ++i) {
237    TickTime::AdvanceFakeClock(packet_time_ms);
238    EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
239    pipe->Process();
240  }
241
242  // Check that all the packets were sent.
243  EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
244  TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
245  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
246  pipe->Process();
247}
248
249// Change the link capacity half-way through the test and verify that the
250// delivery times change accordingly.
251TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
252  FakeNetworkPipe::Config config;
253  config.queue_length_packets = 20;
254  config.link_capacity_kbps = 80;
255  rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
256  pipe->SetReceiver(receiver_.get());
257
258  // Add 10 packets of 1000 bytes, = 80 kb.
259  const int kNumPackets = 10;
260  const int kPacketSize = 1000;
261  SendPackets(pipe.get(), kNumPackets, kPacketSize);
262
263  // Time to get one packet through the link at the initial speed.
264  int packet_time_1_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
265
266  // Change the capacity.
267  config.link_capacity_kbps *= 2;  // Double the capacity.
268  pipe->SetConfig(config);
269
270  // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
271  // seconds to get them through the pipe.
272  SendPackets(pipe.get(), kNumPackets, kPacketSize);
273
274  // Time to get one packet through the link at the new capacity.
275  int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
276
277  // Time hasn't increased yet, so we souldn't get any packets.
278  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
279  pipe->Process();
280
281  // Advance time in steps to release one packet at a time.
282  for (int i = 0; i < kNumPackets; ++i) {
283    TickTime::AdvanceFakeClock(packet_time_1_ms);
284    EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
285    pipe->Process();
286  }
287
288  // Advance time in steps to release one packet at a time.
289  for (int i = 0; i < kNumPackets; ++i) {
290    TickTime::AdvanceFakeClock(packet_time_2_ms);
291    EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(1);
292    pipe->Process();
293  }
294
295  // Check that all the packets were sent.
296  EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
297  TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
298  EXPECT_CALL(*receiver_, DeliverPacket(_, _, _, _)).Times(0);
299  pipe->Process();
300}
301}  // namespace webrtc
302