blob: 65573438c521dc5fe9a70e3ed69668506b6eb6e0 [file] [log] [blame]
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:221/*
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
pbos@webrtc.orgf5d4cb12013-05-17 13:44:4811#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2213
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:5514#include "webrtc/base/scoped_ptr.h"
stefan@webrtc.orgfaada6e2013-12-18 20:28:2515#include "webrtc/call.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2216#include "webrtc/system_wrappers/interface/tick_util.h"
stefan@webrtc.orgfaada6e2013-12-18 20:28:2517#include "webrtc/test/fake_network_pipe.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2218
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
stefan@webrtc.orgfaada6e2013-12-18 20:28:2531 void IncomingPacket(const uint8_t* data, size_t length) {
Fredrik Solenberg23fba1f2015-04-29 13:24:0132 DeliverPacket(MediaType::ANY, data, length);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2233 delete [] data;
34 }
35
Fredrik Solenberg23fba1f2015-04-29 13:24:0136 MOCK_METHOD3(DeliverPacket,
37 DeliveryStatus(MediaType, const uint8_t*, size_t));
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2238};
39
40class FakeNetworkPipeTest : public ::testing::Test {
41 protected:
42 virtual void SetUp() {
43 TickTime::UseFakeClock(12345);
44 receiver_.reset(new MockReceiver());
Fredrik Solenberg23fba1f2015-04-29 13:24:0145 ON_CALL(*receiver_, DeliverPacket(_, _, _))
stefan@webrtc.org1ccff3492014-08-06 15:41:5846 .WillByDefault(Return(PacketReceiver::DELIVERY_OK));
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2247 }
48
49 virtual void TearDown() {
50 }
51
52 void SendPackets(FakeNetworkPipe* pipe, int number_packets, int kPacketSize) {
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:5553 rtc::scoped_ptr<uint8_t[]> packet(new uint8_t[kPacketSize]);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2254 for (int i = 0; i < number_packets; ++i) {
55 pipe->SendPacket(packet.get(), kPacketSize);
56 }
57 }
58
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:5259 int PacketTimeMs(int capacity_kbps, int kPacketSize) const {
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2260 return 8 * kPacketSize / capacity_kbps;
61 }
62
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:5563 rtc::scoped_ptr<MockReceiver> receiver_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2264};
65
66void DeleteMemory(uint8_t* data, int length) { delete [] data; }
67
68// Test the capacity link and verify we get as many packets as we expect.
69TEST_F(FakeNetworkPipeTest, CapacityTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:2570 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:0671 config.queue_length_packets = 20;
mflodman@webrtc.org7acb65a2012-12-13 15:53:1172 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:5573 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:2574 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2275
76 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
77 // get through the pipe.
78 const int kNumPackets = 10;
79 const int kPacketSize = 1000;
80 SendPackets(pipe.get(), kNumPackets , kPacketSize);
81
82 // Time to get one packet through the link.
mflodman@webrtc.org7acb65a2012-12-13 15:53:1183 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
84 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2285
86 // Time haven't increased yet, so we souldn't get any packets.
Fredrik Solenberg23fba1f2015-04-29 13:24:0187 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2288 .Times(0);
stefan@webrtc.orgfaada6e2013-12-18 20:28:2589 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2290
91 // Advance enough time to release one packet.
92 TickTime::AdvanceFakeClock(kPacketTimeMs);
Fredrik Solenberg23fba1f2015-04-29 13:24:0193 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2294 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:2595 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:2296
97 // Release all but one packet
98 TickTime::AdvanceFakeClock(9 * kPacketTimeMs - 1);
Fredrik Solenberg23fba1f2015-04-29 13:24:0199 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22100 .Times(8);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25101 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22102
103 // And the last one.
104 TickTime::AdvanceFakeClock(1);
Fredrik Solenberg23fba1f2015-04-29 13:24:01105 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22106 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25107 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22108}
109
110// Test the extra network delay.
111TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25112 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06113 config.queue_length_packets = 20;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11114 config.queue_delay_ms = 100;
115 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55116 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25117 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22118
119 const int kNumPackets = 2;
120 const int kPacketSize = 1000;
121 SendPackets(pipe.get(), kNumPackets , kPacketSize);
122
123 // Time to get one packet through the link.
mflodman@webrtc.org7acb65a2012-12-13 15:53:11124 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
125 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22126
127 // Increase more than kPacketTimeMs, but not more than the extra delay.
128 TickTime::AdvanceFakeClock(kPacketTimeMs);
Fredrik Solenberg23fba1f2015-04-29 13:24:01129 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22130 .Times(0);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25131 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22132
133 // Advance the network delay to get the first packet.
mflodman@webrtc.org7acb65a2012-12-13 15:53:11134 TickTime::AdvanceFakeClock(config.queue_delay_ms);
Fredrik Solenberg23fba1f2015-04-29 13:24:01135 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22136 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25137 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22138
139 // Advance one more kPacketTimeMs to get the last packet.
140 TickTime::AdvanceFakeClock(kPacketTimeMs);
Fredrik Solenberg23fba1f2015-04-29 13:24:01141 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22142 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25143 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22144}
145
146// Test the number of buffers and packets are dropped when sending too many
147// packets too quickly.
148TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25149 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06150 config.queue_length_packets = 2;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11151 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55152 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25153 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22154
155 const int kPacketSize = 1000;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11156 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
157 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22158
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 TickTime::AdvanceFakeClock(3 * kPacketTimeMs);
Fredrik Solenberg23fba1f2015-04-29 13:24:01165 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22166 .Times(2);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25167 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22168}
169
170// Test we get statistics as expected.
171TEST_F(FakeNetworkPipeTest, StatisticsTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25172 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06173 config.queue_length_packets = 2;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11174 config.queue_delay_ms = 20;
175 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55176 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25177 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22178
179 const int kPacketSize = 1000;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11180 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
181 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22182
183 // Send three packets and verify only 2 are delivered.
184 SendPackets(pipe.get(), 3, kPacketSize);
mflodman@webrtc.org7acb65a2012-12-13 15:53:11185 TickTime::AdvanceFakeClock(3 * kPacketTimeMs + config.queue_delay_ms);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22186
Fredrik Solenberg23fba1f2015-04-29 13:24:01187 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22188 .Times(2);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25189 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22190
mflodman@webrtc.org7acb65a2012-12-13 15:53:11191 // Packet 1: kPacketTimeMs + config.queue_delay_ms,
192 // packet 2: 2 * kPacketTimeMs + config.queue_delay_ms => 170 ms average.
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22193 EXPECT_EQ(pipe->AverageDelay(), 170);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25194 EXPECT_EQ(pipe->sent_packets(), 2u);
195 EXPECT_EQ(pipe->dropped_packets(), 1u);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22196 EXPECT_EQ(pipe->PercentageLoss(), 1/3.f);
197}
198
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52199// Change the link capacity half-way through the test and verify that the
200// delivery times change accordingly.
201TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
202 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06203 config.queue_length_packets = 20;
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52204 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55205 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52206 pipe->SetReceiver(receiver_.get());
207
208 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
209 // get through the pipe.
210 const int kNumPackets = 10;
211 const int kPacketSize = 1000;
212 SendPackets(pipe.get(), kNumPackets, kPacketSize);
213
214 // Time to get one packet through the link.
215 int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
216
217 // Time hasn't increased yet, so we souldn't get any packets.
Fredrik Solenberg23fba1f2015-04-29 13:24:01218 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(0);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52219 pipe->Process();
220
221 // Advance time in steps to release one packet at a time.
222 for (int i = 0; i < kNumPackets; ++i) {
223 TickTime::AdvanceFakeClock(packet_time_ms);
Fredrik Solenberg23fba1f2015-04-29 13:24:01224 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(1);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52225 pipe->Process();
226 }
227
228 // Change the capacity.
229 config.link_capacity_kbps /= 2; // Reduce to 50%.
230 pipe->SetConfig(config);
231
232 // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
233 // seconds to get them through the pipe.
234 SendPackets(pipe.get(), kNumPackets, kPacketSize);
235
236 // Time to get one packet through the link.
237 packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
238
239 // Time hasn't increased yet, so we souldn't get any packets.
Fredrik Solenberg23fba1f2015-04-29 13:24:01240 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(0);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52241 pipe->Process();
242
243 // Advance time in steps to release one packet at a time.
244 for (int i = 0; i < kNumPackets; ++i) {
245 TickTime::AdvanceFakeClock(packet_time_ms);
Fredrik Solenberg23fba1f2015-04-29 13:24:01246 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(1);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52247 pipe->Process();
248 }
249
250 // Check that all the packets were sent.
251 EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
252 TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
Fredrik Solenberg23fba1f2015-04-29 13:24:01253 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(0);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52254 pipe->Process();
255}
256
257// Change the link capacity half-way through the test and verify that the
258// delivery times change accordingly.
259TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
260 FakeNetworkPipe::Config config;
stefan@webrtc.orgb8e9e442014-07-09 11:29:06261 config.queue_length_packets = 20;
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52262 config.link_capacity_kbps = 80;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55263 rtc::scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52264 pipe->SetReceiver(receiver_.get());
265
266 // Add 10 packets of 1000 bytes, = 80 kb.
267 const int kNumPackets = 10;
268 const int kPacketSize = 1000;
269 SendPackets(pipe.get(), kNumPackets, kPacketSize);
270
271 // Time to get one packet through the link at the initial speed.
272 int packet_time_1_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
273
274 // Change the capacity.
275 config.link_capacity_kbps *= 2; // Double the capacity.
276 pipe->SetConfig(config);
277
278 // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
279 // seconds to get them through the pipe.
280 SendPackets(pipe.get(), kNumPackets, kPacketSize);
281
282 // Time to get one packet through the link at the new capacity.
283 int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
284
285 // Time hasn't increased yet, so we souldn't get any packets.
Fredrik Solenberg23fba1f2015-04-29 13:24:01286 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(0);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52287 pipe->Process();
288
289 // Advance time in steps to release one packet at a time.
290 for (int i = 0; i < kNumPackets; ++i) {
291 TickTime::AdvanceFakeClock(packet_time_1_ms);
Fredrik Solenberg23fba1f2015-04-29 13:24:01292 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(1);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52293 pipe->Process();
294 }
295
296 // Advance time in steps to release one packet at a time.
297 for (int i = 0; i < kNumPackets; ++i) {
298 TickTime::AdvanceFakeClock(packet_time_2_ms);
Fredrik Solenberg23fba1f2015-04-29 13:24:01299 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(1);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52300 pipe->Process();
301 }
302
303 // Check that all the packets were sent.
304 EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
305 TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
Fredrik Solenberg23fba1f2015-04-29 13:24:01306 EXPECT_CALL(*receiver_, DeliverPacket(_, _, _)).Times(0);
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52307 pipe->Process();
308}
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22309} // namespace webrtc