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