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