blob: 0399688f62dbc564503d9b59db6d38e06d5886f5 [file] [log] [blame]
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +00001/*
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:48 +000011#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000013
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000014#include "webrtc/call.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000015#include "webrtc/system_wrappers/interface/scoped_ptr.h"
16#include "webrtc/system_wrappers/interface/tick_util.h"
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000017#include "webrtc/test/fake_network_pipe.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000018
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:25 +000031 void IncomingPacket(const uint8_t* data, size_t length) {
32 DeliverPacket(data, length);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000033 delete [] data;
34 }
35
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +000036 MOCK_METHOD2(DeliverPacket, DeliveryStatus(const uint8_t*, size_t));
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000037};
38
39class FakeNetworkPipeTest : public ::testing::Test {
40 protected:
41 virtual void SetUp() {
42 TickTime::UseFakeClock(12345);
43 receiver_.reset(new MockReceiver());
44 }
45
46 virtual void TearDown() {
47 }
48
49 void SendPackets(FakeNetworkPipe* pipe, int number_packets, int kPacketSize) {
andrew@webrtc.org8f693302014-04-25 23:10:28 +000050 scoped_ptr<uint8_t[]> packet(new uint8_t[kPacketSize]);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000051 for (int i = 0; i < number_packets; ++i) {
52 pipe->SendPacket(packet.get(), kPacketSize);
53 }
54 }
55
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52 +000056 int PacketTimeMs(int capacity_kbps, int kPacketSize) const {
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000057 return 8 * kPacketSize / capacity_kbps;
58 }
59
60 scoped_ptr<MockReceiver> receiver_;
61};
62
63void DeleteMemory(uint8_t* data, int length) { delete [] data; }
64
65// Test the capacity link and verify we get as many packets as we expect.
66TEST_F(FakeNetworkPipeTest, CapacityTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000067 FakeNetworkPipe::Config config;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000068 config.queue_length = 20;
69 config.link_capacity_kbps = 80;
70 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000071 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000072
73 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
74 // get through the pipe.
75 const int kNumPackets = 10;
76 const int kPacketSize = 1000;
77 SendPackets(pipe.get(), kNumPackets , kPacketSize);
78
79 // Time to get one packet through the link.
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000080 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
81 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000082
83 // Time haven't increased yet, so we souldn't get any packets.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000084 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000085 .Times(0);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000086 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000087
88 // Advance enough time to release one packet.
89 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000090 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000091 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000092 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000093
94 // Release all but one packet
95 TickTime::AdvanceFakeClock(9 * kPacketTimeMs - 1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000096 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000097 .Times(8);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000098 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000099
100 // And the last one.
101 TickTime::AdvanceFakeClock(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000102 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000103 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000104 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000105}
106
107// Test the extra network delay.
108TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000109 FakeNetworkPipe::Config config;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000110 config.queue_length = 20;
111 config.queue_delay_ms = 100;
112 config.link_capacity_kbps = 80;
113 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000114 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000115
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.
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000121 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
122 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000123
124 // Increase more than kPacketTimeMs, but not more than the extra delay.
125 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000126 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000127 .Times(0);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000128 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000129
130 // Advance the network delay to get the first packet.
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000131 TickTime::AdvanceFakeClock(config.queue_delay_ms);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000132 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000133 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000134 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000135
136 // Advance one more kPacketTimeMs to get the last packet.
137 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000138 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000139 .Times(1);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000140 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000141}
142
143// Test the number of buffers and packets are dropped when sending too many
144// packets too quickly.
145TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000146 FakeNetworkPipe::Config config;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000147 config.queue_length = 2;
148 config.link_capacity_kbps = 80;
149 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000150 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000151
152 const int kPacketSize = 1000;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000153 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
154 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000155
156 // Send three packets and verify only 2 are delivered.
157 SendPackets(pipe.get(), 3, kPacketSize);
158
159 // Increase time enough to deliver all three packets, verify only two are
160 // delivered.
161 TickTime::AdvanceFakeClock(3 * kPacketTimeMs);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000162 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000163 .Times(2);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000164 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000165}
166
167// Test we get statistics as expected.
168TEST_F(FakeNetworkPipeTest, StatisticsTest) {
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000169 FakeNetworkPipe::Config config;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000170 config.queue_length = 2;
171 config.queue_delay_ms = 20;
172 config.link_capacity_kbps = 80;
173 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000174 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000175
176 const int kPacketSize = 1000;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000177 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
178 kPacketSize);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000179
180 // Send three packets and verify only 2 are delivered.
181 SendPackets(pipe.get(), 3, kPacketSize);
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000182 TickTime::AdvanceFakeClock(3 * kPacketTimeMs + config.queue_delay_ms);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000183
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000184 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000185 .Times(2);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000186 pipe->Process();
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000187
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +0000188 // Packet 1: kPacketTimeMs + config.queue_delay_ms,
189 // packet 2: 2 * kPacketTimeMs + config.queue_delay_ms => 170 ms average.
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000190 EXPECT_EQ(pipe->AverageDelay(), 170);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000191 EXPECT_EQ(pipe->sent_packets(), 2u);
192 EXPECT_EQ(pipe->dropped_packets(), 1u);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000193 EXPECT_EQ(pipe->PercentageLoss(), 1/3.f);
194}
195
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52 +0000196// Change the link capacity half-way through the test and verify that the
197// delivery times change accordingly.
198TEST_F(FakeNetworkPipeTest, ChangingCapacityWithEmptyPipeTest) {
199 FakeNetworkPipe::Config config;
200 config.queue_length = 20;
201 config.link_capacity_kbps = 80;
202 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
203 pipe->SetReceiver(receiver_.get());
204
205 // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
206 // get through the pipe.
207 const int kNumPackets = 10;
208 const int kPacketSize = 1000;
209 SendPackets(pipe.get(), kNumPackets, kPacketSize);
210
211 // Time to get one packet through the link.
212 int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
213
214 // Time hasn't increased yet, so we souldn't get any packets.
215 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(0);
216 pipe->Process();
217
218 // Advance time in steps to release one packet at a time.
219 for (int i = 0; i < kNumPackets; ++i) {
220 TickTime::AdvanceFakeClock(packet_time_ms);
221 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(1);
222 pipe->Process();
223 }
224
225 // Change the capacity.
226 config.link_capacity_kbps /= 2; // Reduce to 50%.
227 pipe->SetConfig(config);
228
229 // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
230 // seconds to get them through the pipe.
231 SendPackets(pipe.get(), kNumPackets, kPacketSize);
232
233 // Time to get one packet through the link.
234 packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
235
236 // Time hasn't increased yet, so we souldn't get any packets.
237 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(0);
238 pipe->Process();
239
240 // Advance time in steps to release one packet at a time.
241 for (int i = 0; i < kNumPackets; ++i) {
242 TickTime::AdvanceFakeClock(packet_time_ms);
243 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(1);
244 pipe->Process();
245 }
246
247 // Check that all the packets were sent.
248 EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
249 TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
250 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(0);
251 pipe->Process();
252}
253
254// Change the link capacity half-way through the test and verify that the
255// delivery times change accordingly.
256TEST_F(FakeNetworkPipeTest, ChangingCapacityWithPacketsInPipeTest) {
257 FakeNetworkPipe::Config config;
258 config.queue_length = 20;
259 config.link_capacity_kbps = 80;
260 scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
261 pipe->SetReceiver(receiver_.get());
262
263 // Add 10 packets of 1000 bytes, = 80 kb.
264 const int kNumPackets = 10;
265 const int kPacketSize = 1000;
266 SendPackets(pipe.get(), kNumPackets, kPacketSize);
267
268 // Time to get one packet through the link at the initial speed.
269 int packet_time_1_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
270
271 // Change the capacity.
272 config.link_capacity_kbps *= 2; // Double the capacity.
273 pipe->SetConfig(config);
274
275 // Add another 10 packets of 1000 bytes, = 80 kb, and verify it takes two
276 // seconds to get them through the pipe.
277 SendPackets(pipe.get(), kNumPackets, kPacketSize);
278
279 // Time to get one packet through the link at the new capacity.
280 int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
281
282 // Time hasn't increased yet, so we souldn't get any packets.
283 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(0);
284 pipe->Process();
285
286 // Advance time in steps to release one packet at a time.
287 for (int i = 0; i < kNumPackets; ++i) {
288 TickTime::AdvanceFakeClock(packet_time_1_ms);
289 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(1);
290 pipe->Process();
291 }
292
293 // Advance time in steps to release one packet at a time.
294 for (int i = 0; i < kNumPackets; ++i) {
295 TickTime::AdvanceFakeClock(packet_time_2_ms);
296 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(1);
297 pipe->Process();
298 }
299
300 // Check that all the packets were sent.
301 EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
302 TickTime::AdvanceFakeClock(pipe->TimeUntilNextProcess());
303 EXPECT_CALL(*receiver_, DeliverPacket(_, _)).Times(0);
304 pipe->Process();
305}
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000306} // namespace webrtc