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