blob: 1245f618f165b3d156e9321d523c8ae5a132295c [file] [log] [blame]
mflodman@webrtc.org8c0b2532012-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.org281cff82013-05-17 13:44:48 +000011#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000013
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000014#include "webrtc/call.h"
mflodman@webrtc.org8c0b2532012-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.orgaacdb9f2013-12-18 20:28:25 +000017#include "webrtc/test/fake_network_pipe.h"
mflodman@webrtc.org8c0b2532012-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.orgaacdb9f2013-12-18 20:28:25 +000031 void IncomingPacket(const uint8_t* data, size_t length) {
32 DeliverPacket(data, length);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000033 delete [] data;
34 }
35
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000036 MOCK_METHOD2(DeliverPacket, bool(const uint8_t*, size_t));
mflodman@webrtc.org8c0b2532012-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) {
50 scoped_array<uint8_t> packet(new uint8_t[kPacketSize]);
51 for (int i = 0; i < number_packets; ++i) {
52 pipe->SendPacket(packet.get(), kPacketSize);
53 }
54 }
55
56 int PacketTimeMs(int capacity_kbps, int kPacketSize) {
57 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.orgaacdb9f2013-12-18 20:28:25 +000067 FakeNetworkPipe::Config config;
mflodman@webrtc.org4f920052012-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.orgaacdb9f2013-12-18 20:28:25 +000071 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.org8c0b2532012-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.org4f920052012-12-13 15:53:11 +000080 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
81 kPacketSize);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000082
83 // Time haven't increased yet, so we souldn't get any packets.
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000084 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000085 .Times(0);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000086 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000087
88 // Advance enough time to release one packet.
89 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000090 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000091 .Times(1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000092 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000093
94 // Release all but one packet
95 TickTime::AdvanceFakeClock(9 * kPacketTimeMs - 1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000096 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000097 .Times(8);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +000098 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +000099
100 // And the last one.
101 TickTime::AdvanceFakeClock(1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000102 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000103 .Times(1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000104 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000105}
106
107// Test the extra network delay.
108TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000109 FakeNetworkPipe::Config config;
mflodman@webrtc.org4f920052012-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.orgaacdb9f2013-12-18 20:28:25 +0000114 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.org8c0b2532012-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.org4f920052012-12-13 15:53:11 +0000121 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
122 kPacketSize);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000123
124 // Increase more than kPacketTimeMs, but not more than the extra delay.
125 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000126 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000127 .Times(0);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000128 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000129
130 // Advance the network delay to get the first packet.
mflodman@webrtc.org4f920052012-12-13 15:53:11 +0000131 TickTime::AdvanceFakeClock(config.queue_delay_ms);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000132 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000133 .Times(1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000134 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000135
136 // Advance one more kPacketTimeMs to get the last packet.
137 TickTime::AdvanceFakeClock(kPacketTimeMs);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000138 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000139 .Times(1);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000140 pipe->Process();
mflodman@webrtc.org8c0b2532012-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.orgaacdb9f2013-12-18 20:28:25 +0000146 FakeNetworkPipe::Config config;
mflodman@webrtc.org4f920052012-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.orgaacdb9f2013-12-18 20:28:25 +0000150 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000151
152 const int kPacketSize = 1000;
mflodman@webrtc.org4f920052012-12-13 15:53:11 +0000153 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
154 kPacketSize);
mflodman@webrtc.org8c0b2532012-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.orgaacdb9f2013-12-18 20:28:25 +0000162 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000163 .Times(2);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000164 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000165}
166
167// Test we get statistics as expected.
168TEST_F(FakeNetworkPipeTest, StatisticsTest) {
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000169 FakeNetworkPipe::Config config;
mflodman@webrtc.org4f920052012-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.orgaacdb9f2013-12-18 20:28:25 +0000174 pipe->SetReceiver(receiver_.get());
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000175
176 const int kPacketSize = 1000;
mflodman@webrtc.org4f920052012-12-13 15:53:11 +0000177 const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
178 kPacketSize);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000179
180 // Send three packets and verify only 2 are delivered.
181 SendPackets(pipe.get(), 3, kPacketSize);
mflodman@webrtc.org4f920052012-12-13 15:53:11 +0000182 TickTime::AdvanceFakeClock(3 * kPacketTimeMs + config.queue_delay_ms);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000183
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000184 EXPECT_CALL(*receiver_, DeliverPacket(_, _))
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000185 .Times(2);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000186 pipe->Process();
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000187
mflodman@webrtc.org4f920052012-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.org8c0b2532012-12-11 11:47:22 +0000190 EXPECT_EQ(pipe->AverageDelay(), 170);
stefan@webrtc.orgaacdb9f2013-12-18 20:28:25 +0000191 EXPECT_EQ(pipe->sent_packets(), 2u);
192 EXPECT_EQ(pipe->dropped_packets(), 1u);
mflodman@webrtc.org8c0b2532012-12-11 11:47:22 +0000193 EXPECT_EQ(pipe->PercentageLoss(), 1/3.f);
194}
195
196} // namespace webrtc