Home | History | Annotate | Download | only in test
      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:
     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 
     41 class FakeNetworkPipeTest : public ::testing::Test {
     42  public:
     43   FakeNetworkPipeTest() : fake_clock_(12345) {}
     44 
     45  protected:
     46   virtual void SetUp() {
     47     receiver_.reset(new MockReceiver());
     48     ON_CALL(*receiver_, DeliverPacket(_, _, _, _))
     49         .WillByDefault(Return(PacketReceiver::DELIVERY_OK));
     50   }
     51 
     52   virtual void TearDown() {
     53   }
     54 
     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 
     62   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 
     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.
     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.
    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.
    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.
    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.
    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.
    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