OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_epoll_connection_helper.h" | 5 #include "net/tools/quic/quic_epoll_connection_helper.h" |
6 | 6 |
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" | 7 #include "net/quic/crypto/quic_random.h" |
11 #include "net/quic/quic_connection.h" | |
12 #include "net/quic/quic_framer.h" | |
13 #include "net/quic/test_tools/quic_connection_peer.h" | |
14 #include "net/quic/test_tools/quic_test_utils.h" | |
15 #include "net/tools/quic/test_tools/mock_epoll_server.h" | 8 #include "net/tools/quic/test_tools/mock_epoll_server.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
18 | 10 |
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; | 11 using net::tools::test::MockEpollServer; |
24 using testing::_; | |
25 using testing::AnyNumber; | |
26 using testing::Return; | |
27 | 12 |
28 namespace net { | 13 namespace net { |
29 namespace tools { | 14 namespace tools { |
30 namespace test { | 15 namespace test { |
31 namespace { | 16 namespace { |
32 | 17 |
33 const char kData[] = "foo"; | 18 class TestDelegate : public QuicAlarm::Delegate { |
34 const bool kFromPeer = true; | 19 public: |
| 20 TestDelegate() : fired_(false) {} |
35 | 21 |
36 class TestWriter : public QuicPacketWriter { | 22 virtual QuicTime OnAlarm() OVERRIDE { |
37 public: | 23 fired_ = true; |
38 // QuicPacketWriter | 24 return QuicTime::Zero(); |
39 virtual WriteResult WritePacket( | |
40 const char* buffer, size_t buf_len, | |
41 const IPAddressNumber& self_address, | |
42 const IPEndPoint& peer_address, | |
43 QuicBlockedWriterInterface* blocked_writer) OVERRIDE { | |
44 QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), true); | |
45 FramerVisitorCapturingFrames visitor; | |
46 framer.set_visitor(&visitor); | |
47 QuicEncryptedPacket packet(buffer, buf_len); | |
48 EXPECT_TRUE(framer.ProcessPacket(packet)); | |
49 header_ = *visitor.header(); | |
50 return WriteResult(WRITE_STATUS_OK, packet.length()); | |
51 } | 25 } |
52 | 26 |
53 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE { | 27 bool fired() const { return fired_; } |
54 return false; | |
55 } | |
56 | |
57 // Returns the header from the last packet written. | |
58 const QuicPacketHeader& header() { return header_; } | |
59 | 28 |
60 private: | 29 private: |
61 QuicPacketHeader header_; | 30 bool fired_; |
62 }; | |
63 | |
64 class TestConnection : public QuicConnection { | |
65 public: | |
66 TestConnection(QuicGuid guid, | |
67 IPEndPoint address, | |
68 QuicEpollConnectionHelper* helper, | |
69 TestWriter* writer) | |
70 : QuicConnection(guid, address, helper, writer, false, | |
71 QuicSupportedVersions()) { | |
72 } | |
73 | |
74 void SendAck() { | |
75 QuicConnectionPeer::SendAck(this); | |
76 } | |
77 | |
78 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { | |
79 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); | |
80 } | |
81 }; | 31 }; |
82 | 32 |
83 class QuicEpollConnectionHelperTest : public ::testing::Test { | 33 class QuicEpollConnectionHelperTest : public ::testing::Test { |
84 protected: | 34 protected: |
85 QuicEpollConnectionHelperTest() | 35 QuicEpollConnectionHelperTest() : helper_(&epoll_server_) {} |
86 : guid_(42), | |
87 framer_(QuicSupportedVersions(), QuicTime::Zero(), false), | |
88 send_algorithm_(new testing::StrictMock<MockSendAlgorithm>), | |
89 helper_(&epoll_server_), | |
90 connection_(guid_, IPEndPoint(), &helper_, &writer_), | |
91 frame_(3, false, 0, MakeIOVector(kData)) { | |
92 connection_.set_visitor(&visitor_); | |
93 connection_.SetSendAlgorithm(send_algorithm_); | |
94 epoll_server_.set_timeout_in_us(-1); | |
95 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | |
96 WillRepeatedly(Return(QuicTime::Delta::Zero())); | |
97 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(Return( | |
98 QuicBandwidth::FromKBitsPerSecond(100))); | |
99 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly(Return( | |
100 QuicTime::Delta::FromMilliseconds(100))); | |
101 ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) | |
102 .WillByDefault(Return(true)); | |
103 } | |
104 | |
105 QuicPacket* ConstructDataPacket(QuicPacketSequenceNumber number, | |
106 QuicFecGroupNumber fec_group) { | |
107 QuicPacketHeader header; | |
108 header.public_header.version_flag = false; | |
109 header.public_header.reset_flag = false; | |
110 header.fec_flag = false; | |
111 header.entropy_flag = false; | |
112 header.packet_sequence_number = number; | |
113 header.is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | |
114 header.fec_group = fec_group; | |
115 | |
116 QuicFrames frames; | |
117 frames.push_back(QuicFrame(&frame_)); | |
118 return framer_.BuildUnsizedDataPacket(header, frames).packet; | |
119 } | |
120 | |
121 QuicGuid guid_; | |
122 QuicFramer framer_; | |
123 | 36 |
124 MockEpollServer epoll_server_; | 37 MockEpollServer epoll_server_; |
125 testing::StrictMock<MockSendAlgorithm>* send_algorithm_; | |
126 QuicEpollConnectionHelper helper_; | 38 QuicEpollConnectionHelper helper_; |
127 TestWriter writer_; | |
128 TestConnection connection_; | |
129 testing::StrictMock<MockConnectionVisitor> visitor_; | |
130 | |
131 QuicStreamFrame frame_; | |
132 }; | 39 }; |
133 | 40 |
134 TEST_F(QuicEpollConnectionHelperTest, DISABLED_TestRTORetransmission) { | 41 TEST_F(QuicEpollConnectionHelperTest, GetClock) { |
135 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( | 42 const QuicClock* clock = helper_.GetClock(); |
136 Return(QuicTime::Delta::Zero())); | 43 QuicTime start = clock->Now(); |
137 const int64 kDefaultRetransmissionTimeMs = 500; | |
138 | 44 |
139 char buffer[] = "foo"; | 45 QuicTime::Delta delta = QuicTime::Delta::FromMilliseconds(5); |
140 const size_t packet_size = | 46 epoll_server_.AdvanceBy(delta.ToMicroseconds()); |
141 QuicPacketCreator::StreamFramePacketOverhead( | |
142 framer_.version(), PACKET_8BYTE_GUID, kIncludeVersion, | |
143 PACKET_1BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP) + | |
144 arraysize(buffer) - 1; | |
145 | 47 |
146 EXPECT_CALL(*send_algorithm_, | 48 EXPECT_EQ(start.Add(delta), clock->Now()); |
147 OnPacketSent(_, 1, packet_size, NOT_RETRANSMISSION, _)); | |
148 EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, packet_size)); | |
149 EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(Return(true)); | |
150 EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber()); | |
151 IOVector data; | |
152 data.Append(buffer, 3); | |
153 connection_.SendStreamData(1, data, 0, false, NULL); | |
154 EXPECT_EQ(1u, writer_.header().packet_sequence_number); | |
155 EXPECT_CALL(*send_algorithm_, | |
156 OnPacketSent(_, 2, packet_size, RTO_RETRANSMISSION, _)); | |
157 epoll_server_.AdvanceByAndCallCallbacks(kDefaultRetransmissionTimeMs * 1000); | |
158 | |
159 EXPECT_EQ(2u, writer_.header().packet_sequence_number); | |
160 } | 49 } |
161 | 50 |
162 TEST_F(QuicEpollConnectionHelperTest, InitialTimeout) { | 51 TEST_F(QuicEpollConnectionHelperTest, GetRandomGenerator) { |
163 EXPECT_TRUE(connection_.connected()); | 52 QuicRandom* random = helper_.GetRandomGenerator(); |
164 | 53 EXPECT_EQ(QuicRandom::GetInstance(), random); |
165 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, NOT_RETRANSMISSION, | |
166 HAS_RETRANSMITTABLE_DATA)); | |
167 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillOnce( | |
168 Return(QuicTime::Delta::FromMicroseconds(1))); | |
169 EXPECT_CALL(visitor_, | |
170 OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, !kFromPeer)); | |
171 epoll_server_.WaitForEventsAndExecuteCallbacks(); | |
172 EXPECT_FALSE(connection_.connected()); | |
173 EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000, epoll_server_.NowInUsec()); | |
174 } | 54 } |
175 | 55 |
176 TEST_F(QuicEpollConnectionHelperTest, TimeoutAfterSend) { | 56 TEST_F(QuicEpollConnectionHelperTest, CreateAlarm) { |
177 EXPECT_TRUE(connection_.connected()); | 57 TestDelegate* delegate = new TestDelegate(); |
178 EXPECT_EQ(0, epoll_server_.NowInUsec()); | 58 scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate)); |
179 | 59 |
180 // When we send a packet, the timeout will change to 5000 + | 60 const QuicClock* clock = helper_.GetClock(); |
181 // kDefaultInitialTimeoutSecs. | 61 QuicTime start = clock->Now(); |
182 epoll_server_.AdvanceBy(5000); | 62 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); |
183 EXPECT_EQ(5000, epoll_server_.NowInUsec()); | 63 alarm->Set(start.Add(delta)); |
184 | 64 |
185 // Send an ack so we don't set the retransmission alarm. | 65 epoll_server_.AdvanceByAndCallCallbacks(delta.ToMicroseconds()); |
186 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 1, _, NOT_RETRANSMISSION, | 66 EXPECT_EQ(start.Add(delta), clock->Now()); |
187 NO_RETRANSMITTABLE_DATA)); | |
188 connection_.SendAck(); | |
189 | |
190 // The original alarm will fire. We should not time out because we had a | |
191 // network event at t=5000. The alarm will reregister. | |
192 epoll_server_.WaitForEventsAndExecuteCallbacks(); | |
193 EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000, epoll_server_.NowInUsec()); | |
194 | |
195 // This time, we should time out. | |
196 EXPECT_CALL(visitor_, | |
197 OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, !kFromPeer)); | |
198 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, 2, _, NOT_RETRANSMISSION, | |
199 HAS_RETRANSMITTABLE_DATA)); | |
200 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillOnce( | |
201 Return(QuicTime::Delta::FromMicroseconds(1))); | |
202 epoll_server_.WaitForEventsAndExecuteCallbacks(); | |
203 EXPECT_EQ(kDefaultInitialTimeoutSecs * 1000000 + 5000, | |
204 epoll_server_.NowInUsec()); | |
205 EXPECT_FALSE(connection_.connected()); | |
206 } | 67 } |
207 | 68 |
208 TEST_F(QuicEpollConnectionHelperTest, SendSchedulerDelayThenSend) { | 69 TEST_F(QuicEpollConnectionHelperTest, CreateAlarmAndCancel) { |
209 // Test that if we send a packet with a delay, it ends up queued. | 70 TestDelegate* delegate = new TestDelegate(); |
210 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( | 71 scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate)); |
211 Return(QuicTime::Delta::Zero())); | |
212 EXPECT_CALL( | |
213 *send_algorithm_, TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce( | |
214 Return(QuicTime::Delta::FromMicroseconds(1))); | |
215 connection_.OnSerializedPacket( | |
216 SerializedPacket(1, PACKET_6BYTE_SEQUENCE_NUMBER, | |
217 ConstructDataPacket(1, 0), 0, | |
218 new RetransmittableFrames)); | |
219 | 72 |
220 EXPECT_CALL(*send_algorithm_, | 73 const QuicClock* clock = helper_.GetClock(); |
221 OnPacketSent(_, 1, _, NOT_RETRANSMISSION, _)); | 74 QuicTime start = clock->Now(); |
222 EXPECT_EQ(1u, connection_.NumQueuedPackets()); | 75 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); |
| 76 alarm->Set(start.Add(delta)); |
| 77 alarm->Cancel(); |
223 | 78 |
224 // Advance the clock to fire the alarm, and configure the scheduler | 79 epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds()); |
225 // to permit the packet to be sent. | 80 EXPECT_EQ(start.Add(delta), clock->Now()); |
226 EXPECT_CALL(*send_algorithm_, | 81 EXPECT_FALSE(delegate->fired()); |
227 TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillRepeatedly( | 82 } |
228 Return(QuicTime::Delta::Zero())); | 83 |
229 EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(Return(true)); | 84 TEST_F(QuicEpollConnectionHelperTest, CreateAlarmAndReset) { |
230 EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber()); | 85 TestDelegate* delegate = new TestDelegate(); |
231 epoll_server_.AdvanceByAndCallCallbacks(1); | 86 scoped_ptr<QuicAlarm> alarm(helper_.CreateAlarm(delegate)); |
232 EXPECT_EQ(0u, connection_.NumQueuedPackets()); | 87 |
| 88 const QuicClock* clock = helper_.GetClock(); |
| 89 QuicTime start = clock->Now(); |
| 90 QuicTime::Delta delta = QuicTime::Delta::FromMicroseconds(1); |
| 91 alarm->Set(clock->Now().Add(delta)); |
| 92 alarm->Cancel(); |
| 93 QuicTime::Delta new_delta = QuicTime::Delta::FromMicroseconds(3); |
| 94 alarm->Set(clock->Now().Add(new_delta)); |
| 95 |
| 96 epoll_server_.AdvanceByExactlyAndCallCallbacks(delta.ToMicroseconds()); |
| 97 EXPECT_EQ(start.Add(delta), clock->Now()); |
| 98 EXPECT_FALSE(delegate->fired()); |
| 99 |
| 100 epoll_server_.AdvanceByExactlyAndCallCallbacks( |
| 101 new_delta.Subtract(delta).ToMicroseconds()); |
| 102 EXPECT_EQ(start.Add(new_delta), clock->Now()); |
| 103 EXPECT_TRUE(delegate->fired()); |
233 } | 104 } |
234 | 105 |
235 } // namespace | 106 } // namespace |
236 } // namespace test | 107 } // namespace test |
237 } // namespace tools | 108 } // namespace tools |
238 } // namespace net | 109 } // namespace net |
OLD | NEW |