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