1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/tools/quic/quic_epoll_connection_helper.h"
7 #include "net/quic/crypto/crypto_protocol.h"
8 #include "net/quic/crypto/quic_decrypter.h"
9 #include "net/quic/crypto/quic_encrypter.h"
10 #include "net/quic/crypto/quic_random.h"
11 #include "net/quic/quic_framer.h"
12 #include "net/quic/test_tools/quic_connection_peer.h"
13 #include "net/quic/test_tools/quic_test_utils.h"
14 #include "net/tools/quic/test_tools/mock_epoll_server.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using net::test::GetMinStreamFrameSize
;
19 using net::test::FramerVisitorCapturingFrames
;
20 using net::test::MockSendAlgorithm
;
21 using net::test::QuicConnectionPeer
;
22 using net::test::MockConnectionVisitor
;
23 using net::tools::test::MockEpollServer
;
25 using testing::Return
;
32 const char data1
[] = "foo";
33 const bool kFromPeer
= true;
35 class TestConnectionHelper
: public QuicEpollConnectionHelper
{
37 TestConnectionHelper(int fd
, EpollServer
* eps
)
38 : QuicEpollConnectionHelper(fd
, eps
) {
41 virtual int WritePacketToWire(const QuicEncryptedPacket
& packet
,
42 int* error
) OVERRIDE
{
43 QuicFramer
framer(QuicVersionMax(), QuicTime::Zero(), true);
44 FramerVisitorCapturingFrames visitor
;
45 framer
.set_visitor(&visitor
);
46 EXPECT_TRUE(framer
.ProcessPacket(packet
));
47 header_
= *visitor
.header();
49 return packet
.length();
52 QuicPacketHeader
* header() { return &header_
; }
55 QuicPacketHeader header_
;
58 class TestConnection
: public QuicConnection
{
60 TestConnection(QuicGuid guid
,
62 TestConnectionHelper
* helper
)
63 : QuicConnection(guid
, address
, helper
, false, QuicVersionMax()) {
67 QuicConnectionPeer::SendAck(this);
70 void SetSendAlgorithm(SendAlgorithmInterface
* send_algorithm
) {
71 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm
);
74 using QuicConnection::SendOrQueuePacket
;
77 class QuicEpollConnectionHelperTest
: public ::testing::Test
{
79 QuicEpollConnectionHelperTest()
81 framer_(QuicVersionMax(), QuicTime::Zero(), false),
82 send_algorithm_(new testing::StrictMock
<MockSendAlgorithm
>),
83 helper_(new TestConnectionHelper(0, &epoll_server_
)),
84 connection_(guid_
, IPEndPoint(), helper_
),
85 frame1_(1, false, 0, data1
) {
86 connection_
.set_visitor(&visitor_
);
87 connection_
.SetSendAlgorithm(send_algorithm_
);
88 epoll_server_
.set_timeout_in_us(-1);
89 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, _
, _
, _
)).
90 WillRepeatedly(Return(QuicTime::Delta::Zero()));
93 QuicPacket
* ConstructDataPacket(QuicPacketSequenceNumber number
,
94 QuicFecGroupNumber fec_group
) {
95 header_
.public_header
.version_flag
= false;
96 header_
.public_header
.reset_flag
= false;
97 header_
.fec_flag
= false;
98 header_
.entropy_flag
= false;
99 header_
.packet_sequence_number
= number
;
100 header_
.is_in_fec_group
= fec_group
== 0 ? NOT_IN_FEC_GROUP
: IN_FEC_GROUP
;
101 header_
.fec_group
= fec_group
;
104 QuicFrame
frame(&frame1_
);
105 frames
.push_back(frame
);
106 return framer_
.BuildUnsizedDataPacket(header_
, frames
).packet
;
112 MockEpollServer epoll_server_
;
113 testing::StrictMock
<MockSendAlgorithm
>* send_algorithm_
;
114 TestConnectionHelper
* helper_
;
115 TestConnection connection_
;
116 testing::StrictMock
<MockConnectionVisitor
> visitor_
;
118 QuicPacketHeader header_
;
119 QuicStreamFrame frame1_
;
122 TEST_F(QuicEpollConnectionHelperTest
, DISABLED_TestRetransmission
) {
123 //FLAGS_fake_packet_loss_percentage = 100;
124 EXPECT_CALL(*send_algorithm_
, RetransmissionDelay()).WillRepeatedly(
125 Return(QuicTime::Delta::Zero()));
126 const int64 kDefaultRetransmissionTimeMs
= 500;
128 const char buffer
[] = "foo";
129 const size_t packet_size
=
130 GetPacketHeaderSize(PACKET_8BYTE_GUID
, kIncludeVersion
,
131 PACKET_6BYTE_SEQUENCE_NUMBER
, NOT_IN_FEC_GROUP
) +
132 GetMinStreamFrameSize(framer_
.version()) + arraysize(buffer
) - 1;
133 EXPECT_CALL(*send_algorithm_
,
134 SentPacket(_
, 1, packet_size
, NOT_RETRANSMISSION
));
135 EXPECT_CALL(*send_algorithm_
, AbandoningPacket(1, packet_size
));
136 connection_
.SendStreamData(1, buffer
, 0, false);
137 EXPECT_EQ(1u, helper_
->header()->packet_sequence_number
);
138 EXPECT_CALL(*send_algorithm_
,
139 SentPacket(_
, 2, packet_size
, IS_RETRANSMISSION
));
140 epoll_server_
.AdvanceByAndCallCallbacks(kDefaultRetransmissionTimeMs
* 1000);
142 EXPECT_EQ(2u, helper_
->header()->packet_sequence_number
);
145 TEST_F(QuicEpollConnectionHelperTest
, InitialTimeout
) {
146 EXPECT_TRUE(connection_
.connected());
148 EXPECT_CALL(*send_algorithm_
, SentPacket(_
, 1, _
, NOT_RETRANSMISSION
));
149 EXPECT_CALL(visitor_
, ConnectionClose(QUIC_CONNECTION_TIMED_OUT
, !kFromPeer
));
150 epoll_server_
.WaitForEventsAndExecuteCallbacks();
151 EXPECT_FALSE(connection_
.connected());
152 EXPECT_EQ(kDefaultInitialTimeoutSecs
* 1000000, epoll_server_
.NowInUsec());
155 TEST_F(QuicEpollConnectionHelperTest
, TimeoutAfterSend
) {
156 EXPECT_TRUE(connection_
.connected());
157 EXPECT_EQ(0, epoll_server_
.NowInUsec());
159 // When we send a packet, the timeout will change to 5000 +
160 // kDefaultInitialTimeoutSecs.
161 epoll_server_
.AdvanceBy(5000);
162 EXPECT_EQ(5000, epoll_server_
.NowInUsec());
164 // Send an ack so we don't set the retransmission alarm.
165 EXPECT_CALL(*send_algorithm_
, SentPacket(_
, 1, _
, NOT_RETRANSMISSION
));
166 connection_
.SendAck();
168 // The original alarm will fire. We should not time out because we had a
169 // network event at t=5000. The alarm will reregister.
170 epoll_server_
.WaitForEventsAndExecuteCallbacks();
171 EXPECT_EQ(kDefaultInitialTimeoutSecs
* 1000000, epoll_server_
.NowInUsec());
173 // This time, we should time out.
174 EXPECT_CALL(visitor_
, ConnectionClose(QUIC_CONNECTION_TIMED_OUT
, !kFromPeer
));
175 EXPECT_CALL(*send_algorithm_
, SentPacket(_
, 2, _
, NOT_RETRANSMISSION
));
176 epoll_server_
.WaitForEventsAndExecuteCallbacks();
177 EXPECT_EQ(kDefaultInitialTimeoutSecs
* 1000000 + 5000,
178 epoll_server_
.NowInUsec());
179 EXPECT_FALSE(connection_
.connected());
182 TEST_F(QuicEpollConnectionHelperTest
, SendSchedulerDelayThenSend
) {
183 // Test that if we send a packet with a delay, it ends up queued.
184 EXPECT_CALL(*send_algorithm_
, RetransmissionDelay()).WillRepeatedly(
185 Return(QuicTime::Delta::Zero()));
186 QuicPacket
* packet
= ConstructDataPacket(1, 0);
188 *send_algorithm_
, TimeUntilSend(_
, NOT_RETRANSMISSION
, _
, _
)).WillOnce(
189 testing::Return(QuicTime::Delta::FromMicroseconds(1)));
190 connection_
.SendOrQueuePacket(ENCRYPTION_NONE
, 1, packet
, 0,
191 HAS_RETRANSMITTABLE_DATA
);
192 EXPECT_CALL(*send_algorithm_
, SentPacket(_
, 1, _
, NOT_RETRANSMISSION
));
193 EXPECT_EQ(1u, connection_
.NumQueuedPackets());
195 // Advance the clock to fire the alarm, and configure the scheduler
196 // to permit the packet to be sent.
197 EXPECT_CALL(*send_algorithm_
, TimeUntilSend(_
, NOT_RETRANSMISSION
, _
, _
)).
198 WillRepeatedly(testing::Return(QuicTime::Delta::Zero()));
199 EXPECT_CALL(visitor_
, OnCanWrite()).WillOnce(testing::Return(true));
200 epoll_server_
.AdvanceByAndCallCallbacks(1);
201 EXPECT_EQ(0u, connection_
.NumQueuedPackets());