| 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 |