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