summaryrefslogtreecommitdiff
path: root/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/tools/quic/quic_epoll_connection_helper_test.cc')
-rw-r--r--chromium/net/tools/quic/quic_epoll_connection_helper_test.cc207
1 files changed, 207 insertions, 0 deletions
diff --git a/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc b/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc
new file mode 100644
index 00000000000..0bfaee27d07
--- /dev/null
+++ b/chromium/net/tools/quic/quic_epoll_connection_helper_test.cc
@@ -0,0 +1,207 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/tools/quic/quic_epoll_connection_helper.h"
+
+#include "net/quic/crypto/crypto_protocol.h"
+#include "net/quic/crypto/quic_decrypter.h"
+#include "net/quic/crypto/quic_encrypter.h"
+#include "net/quic/crypto/quic_random.h"
+#include "net/quic/quic_framer.h"
+#include "net/quic/test_tools/quic_connection_peer.h"
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/tools/quic/test_tools/mock_epoll_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using net::test::GetMinStreamFrameSize;
+using net::test::FramerVisitorCapturingFrames;
+using net::test::MockSendAlgorithm;
+using net::test::QuicConnectionPeer;
+using net::test::MockConnectionVisitor;
+using net::tools::test::MockEpollServer;
+using testing::_;
+using testing::Return;
+
+namespace net {
+namespace tools {
+namespace test {
+namespace {
+
+const char data1[] = "foo";
+const bool kFromPeer = true;
+
+class TestConnectionHelper : public QuicEpollConnectionHelper {
+ public:
+ TestConnectionHelper(int fd, EpollServer* eps)
+ : QuicEpollConnectionHelper(fd, eps) {
+ }
+
+ virtual int WritePacketToWire(const QuicEncryptedPacket& packet,
+ int* error) OVERRIDE {
+ QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), true);
+ FramerVisitorCapturingFrames visitor;
+ framer.set_visitor(&visitor);
+ EXPECT_TRUE(framer.ProcessPacket(packet));
+ header_ = *visitor.header();
+ *error = 0;
+ return packet.length();
+ }
+
+ QuicPacketHeader* header() { return &header_; }
+
+ private:
+ QuicPacketHeader header_;
+};
+
+class TestConnection : public QuicConnection {
+ public:
+ TestConnection(QuicGuid guid,
+ IPEndPoint address,
+ TestConnectionHelper* helper)
+ : QuicConnection(guid, address, helper, false, QuicVersionMax()) {
+ }
+
+ void SendAck() {
+ QuicConnectionPeer::SendAck(this);
+ }
+
+ void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
+ QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
+ }
+
+ using QuicConnection::SendOrQueuePacket;
+};
+
+class QuicEpollConnectionHelperTest : public ::testing::Test {
+ protected:
+ QuicEpollConnectionHelperTest()
+ : guid_(42),
+ framer_(QuicVersionMax(), QuicTime::Zero(), false),
+ send_algorithm_(new testing::StrictMock<MockSendAlgorithm>),
+ helper_(new TestConnectionHelper(0, &epoll_server_)),
+ connection_(guid_, IPEndPoint(), helper_),
+ frame1_(1, false, 0, data1) {
+ connection_.set_visitor(&visitor_);
+ connection_.SetSendAlgorithm(send_algorithm_);
+ epoll_server_.set_timeout_in_us(-1);
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)).
+ WillRepeatedly(Return(QuicTime::Delta::Zero()));
+ }
+
+ QuicPacket* ConstructDataPacket(QuicPacketSequenceNumber number,
+ QuicFecGroupNumber fec_group) {
+ header_.public_header.version_flag = false;
+ header_.public_header.reset_flag = false;
+ header_.fec_flag = false;
+ header_.entropy_flag = false;
+ header_.packet_sequence_number = number;
+ header_.is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP;
+ header_.fec_group = fec_group;
+
+ QuicFrames frames;
+ QuicFrame frame(&frame1_);
+ frames.push_back(frame);
+ return framer_.BuildUnsizedDataPacket(header_, frames).packet;
+ }
+
+ QuicGuid guid_;
+ QuicFramer framer_;
+
+ MockEpollServer epoll_server_;
+ testing::StrictMock<MockSendAlgorithm>* send_algorithm_;
+ TestConnectionHelper* helper_;
+ TestConnection connection_;
+ testing::StrictMock<MockConnectionVisitor> visitor_;
+
+ QuicPacketHeader header_;
+ QuicStreamFrame frame1_;
+};
+
+TEST_F(QuicEpollConnectionHelperTest, DISABLED_TestRetransmission) {
+ //FLAGS_fake_packet_loss_percentage = 100;
+ EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
+ Return(QuicTime::Delta::Zero()));
+ const int64 kDefaultRetransmissionTimeMs = 500;
+
+ const char buffer[] = "foo";
+ const size_t packet_size =
+ GetPacketHeaderSize(PACKET_8BYTE_GUID, kIncludeVersion,
+ PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) +
+ GetMinStreamFrameSize(framer_.version()) + arraysize(buffer) - 1;
+ EXPECT_CALL(*send_algorithm_,
+ SentPacket(_, 1, packet_size, NOT_RETRANSMISSION));
+ EXPECT_CALL(*send_algorithm_, AbandoningPacket(1, packet_size));
+ connection_.SendStreamData(1, buffer, 0, false);
+ EXPECT_EQ(1u, helper_->header()->packet_sequence_number);
+ EXPECT_CALL(*send_algorithm_,
+ SentPacket(_, 2, packet_size, IS_RETRANSMISSION));
+ epoll_server_.AdvanceByAndCallCallbacks(kDefaultRetransmissionTimeMs * 1000);
+
+ EXPECT_EQ(2u, helper_->header()->packet_sequence_number);
+}
+
+TEST_F(QuicEpollConnectionHelperTest, InitialTimeout) {
+ EXPECT_TRUE(connection_.connected());
+
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION));
+ EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, !kFromPeer));
+ epoll_server_.WaitForEventsAndExecuteCallbacks();
+ EXPECT_FALSE(connection_.connected());
+ EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000, epoll_server_.NowInUsec());
+}
+
+TEST_F(QuicEpollConnectionHelperTest, TimeoutAfterSend) {
+ EXPECT_TRUE(connection_.connected());
+ EXPECT_EQ(0, epoll_server_.NowInUsec());
+
+ // When we send a packet, the timeout will change to 5000 +
+ // kDefaultInitialTimeoutSecs.
+ epoll_server_.AdvanceBy(5000);
+ EXPECT_EQ(5000, epoll_server_.NowInUsec());
+
+ // Send an ack so we don't set the retransmission alarm.
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION));
+ connection_.SendAck();
+
+ // The original alarm will fire. We should not time out because we had a
+ // network event at t=5000. The alarm will reregister.
+ epoll_server_.WaitForEventsAndExecuteCallbacks();
+ EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000, epoll_server_.NowInUsec());
+
+ // This time, we should time out.
+ EXPECT_CALL(visitor_, ConnectionClose(QUIC_CONNECTION_TIMED_OUT, !kFromPeer));
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, 2, _, NOT_RETRANSMISSION));
+ epoll_server_.WaitForEventsAndExecuteCallbacks();
+ EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000 + 5000,
+ epoll_server_.NowInUsec());
+ EXPECT_FALSE(connection_.connected());
+}
+
+TEST_F(QuicEpollConnectionHelperTest, SendSchedulerDelayThenSend) {
+ // Test that if we send a packet with a delay, it ends up queued.
+ EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
+ Return(QuicTime::Delta::Zero()));
+ QuicPacket* packet = ConstructDataPacket(1, 0);
+ EXPECT_CALL(
+ *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce(
+ testing::Return(QuicTime::Delta::FromMicroseconds(1)));
+ connection_.SendOrQueuePacket(ENCRYPTION_NONE, 1, packet, 0,
+ HAS_RETRANSMITTABLE_DATA);
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, 1, _, NOT_RETRANSMISSION));
+ EXPECT_EQ(1u, connection_.NumQueuedPackets());
+
+ // Advance the clock to fire the alarm, and configure the scheduler
+ // to permit the packet to be sent.
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).
+ WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
+ EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(testing::Return(true));
+ epoll_server_.AdvanceByAndCallCallbacks(1);
+ EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+} // namespace
+} // namespace test
+} // namespace tools
+} // namespace net