Integrate fake_network_pipe into direct_transport.
TEST=trybots
R=mflodman@webrtc.org, pbos@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/5529004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5321 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/test/fake_network_pipe_unittest.cc b/webrtc/test/fake_network_pipe_unittest.cc
new file mode 100644
index 0000000..1245f61
--- /dev/null
+++ b/webrtc/test/fake_network_pipe_unittest.cc
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include "webrtc/call.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/tick_util.h"
+#include "webrtc/test/fake_network_pipe.h"
+
+using ::testing::_;
+using ::testing::AnyNumber;
+using ::testing::Return;
+using ::testing::Invoke;
+
+namespace webrtc {
+
+class MockReceiver : public PacketReceiver {
+ public:
+ MockReceiver() {}
+ virtual ~MockReceiver() {}
+
+ void IncomingPacket(const uint8_t* data, size_t length) {
+ DeliverPacket(data, length);
+ delete [] data;
+ }
+
+ MOCK_METHOD2(DeliverPacket, bool(const uint8_t*, size_t));
+};
+
+class FakeNetworkPipeTest : public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ TickTime::UseFakeClock(12345);
+ receiver_.reset(new MockReceiver());
+ }
+
+ virtual void TearDown() {
+ }
+
+ void SendPackets(FakeNetworkPipe* pipe, int number_packets, int kPacketSize) {
+ scoped_array<uint8_t> packet(new uint8_t[kPacketSize]);
+ for (int i = 0; i < number_packets; ++i) {
+ pipe->SendPacket(packet.get(), kPacketSize);
+ }
+ }
+
+ int PacketTimeMs(int capacity_kbps, int kPacketSize) {
+ return 8 * kPacketSize / capacity_kbps;
+ }
+
+ scoped_ptr<MockReceiver> receiver_;
+};
+
+void DeleteMemory(uint8_t* data, int length) { delete [] data; }
+
+// Test the capacity link and verify we get as many packets as we expect.
+TEST_F(FakeNetworkPipeTest, CapacityTest) {
+ FakeNetworkPipe::Config config;
+ config.queue_length = 20;
+ config.link_capacity_kbps = 80;
+ scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
+ pipe->SetReceiver(receiver_.get());
+
+ // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
+ // get through the pipe.
+ const int kNumPackets = 10;
+ const int kPacketSize = 1000;
+ SendPackets(pipe.get(), kNumPackets , kPacketSize);
+
+ // Time to get one packet through the link.
+ const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
+ kPacketSize);
+
+ // Time haven't increased yet, so we souldn't get any packets.
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(0);
+ pipe->Process();
+
+ // Advance enough time to release one packet.
+ TickTime::AdvanceFakeClock(kPacketTimeMs);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(1);
+ pipe->Process();
+
+ // Release all but one packet
+ TickTime::AdvanceFakeClock(9 * kPacketTimeMs - 1);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(8);
+ pipe->Process();
+
+ // And the last one.
+ TickTime::AdvanceFakeClock(1);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(1);
+ pipe->Process();
+}
+
+// Test the extra network delay.
+TEST_F(FakeNetworkPipeTest, ExtraDelayTest) {
+ FakeNetworkPipe::Config config;
+ config.queue_length = 20;
+ config.queue_delay_ms = 100;
+ config.link_capacity_kbps = 80;
+ scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
+ pipe->SetReceiver(receiver_.get());
+
+ const int kNumPackets = 2;
+ const int kPacketSize = 1000;
+ SendPackets(pipe.get(), kNumPackets , kPacketSize);
+
+ // Time to get one packet through the link.
+ const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
+ kPacketSize);
+
+ // Increase more than kPacketTimeMs, but not more than the extra delay.
+ TickTime::AdvanceFakeClock(kPacketTimeMs);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(0);
+ pipe->Process();
+
+ // Advance the network delay to get the first packet.
+ TickTime::AdvanceFakeClock(config.queue_delay_ms);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(1);
+ pipe->Process();
+
+ // Advance one more kPacketTimeMs to get the last packet.
+ TickTime::AdvanceFakeClock(kPacketTimeMs);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(1);
+ pipe->Process();
+}
+
+// Test the number of buffers and packets are dropped when sending too many
+// packets too quickly.
+TEST_F(FakeNetworkPipeTest, QueueLengthTest) {
+ FakeNetworkPipe::Config config;
+ config.queue_length = 2;
+ config.link_capacity_kbps = 80;
+ scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
+ pipe->SetReceiver(receiver_.get());
+
+ const int kPacketSize = 1000;
+ const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
+ kPacketSize);
+
+ // Send three packets and verify only 2 are delivered.
+ SendPackets(pipe.get(), 3, kPacketSize);
+
+ // Increase time enough to deliver all three packets, verify only two are
+ // delivered.
+ TickTime::AdvanceFakeClock(3 * kPacketTimeMs);
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(2);
+ pipe->Process();
+}
+
+// Test we get statistics as expected.
+TEST_F(FakeNetworkPipeTest, StatisticsTest) {
+ FakeNetworkPipe::Config config;
+ config.queue_length = 2;
+ config.queue_delay_ms = 20;
+ config.link_capacity_kbps = 80;
+ scoped_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(config));
+ pipe->SetReceiver(receiver_.get());
+
+ const int kPacketSize = 1000;
+ const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
+ kPacketSize);
+
+ // Send three packets and verify only 2 are delivered.
+ SendPackets(pipe.get(), 3, kPacketSize);
+ TickTime::AdvanceFakeClock(3 * kPacketTimeMs + config.queue_delay_ms);
+
+ EXPECT_CALL(*receiver_, DeliverPacket(_, _))
+ .Times(2);
+ pipe->Process();
+
+ // Packet 1: kPacketTimeMs + config.queue_delay_ms,
+ // packet 2: 2 * kPacketTimeMs + config.queue_delay_ms => 170 ms average.
+ EXPECT_EQ(pipe->AverageDelay(), 170);
+ EXPECT_EQ(pipe->sent_packets(), 2u);
+ EXPECT_EQ(pipe->dropped_packets(), 1u);
+ EXPECT_EQ(pipe->PercentageLoss(), 1/3.f);
+}
+
+} // namespace webrtc