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