Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / net / tools / quic / quic_time_wait_list_manager_test.cc
blobe6baf7dbc22cb5b0e57c538b35bfdc88c0290b32
1 // Copyright 2013 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_time_wait_list_manager.h"
7 #include <errno.h>
9 #include "net/quic/crypto/crypto_protocol.h"
10 #include "net/quic/crypto/null_encrypter.h"
11 #include "net/quic/crypto/quic_decrypter.h"
12 #include "net/quic/crypto/quic_encrypter.h"
13 #include "net/quic/quic_connection_helper.h"
14 #include "net/quic/quic_data_reader.h"
15 #include "net/quic/quic_flags.h"
16 #include "net/quic/quic_framer.h"
17 #include "net/quic/quic_packet_writer.h"
18 #include "net/quic/quic_protocol.h"
19 #include "net/quic/quic_utils.h"
20 #include "net/quic/test_tools/quic_test_utils.h"
21 #include "net/tools/quic/quic_epoll_connection_helper.h"
22 #include "net/tools/quic/test_tools/mock_epoll_server.h"
23 #include "net/tools/quic/test_tools/mock_quic_server_session_visitor.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using net::test::kTestPort;
28 using net::test::BuildUnsizedDataPacket;
29 using net::test::NoOpFramerVisitor;
30 using net::test::QuicVersionMax;
31 using net::test::QuicVersionMin;
32 using net::test::ValueRestore;
33 using net::test::MockPacketWriter;
35 using testing::Args;
36 using testing::Assign;
37 using testing::DoAll;
38 using testing::Matcher;
39 using testing::MatcherInterface;
40 using testing::NiceMock;
41 using testing::Return;
42 using testing::ReturnPointee;
43 using testing::SetArgPointee;
44 using testing::StrictMock;
45 using testing::Truly;
46 using testing::_;
48 namespace net {
49 namespace tools {
50 namespace test {
52 class FramerVisitorCapturingPublicReset : public NoOpFramerVisitor {
53 public:
54 FramerVisitorCapturingPublicReset() {}
55 ~FramerVisitorCapturingPublicReset() override {}
57 void OnPublicResetPacket(const QuicPublicResetPacket& public_reset) override {
58 public_reset_packet_ = public_reset;
61 const QuicPublicResetPacket public_reset_packet() {
62 return public_reset_packet_;
65 private:
66 QuicPublicResetPacket public_reset_packet_;
69 class QuicTimeWaitListManagerPeer {
70 public:
71 static bool ShouldSendResponse(QuicTimeWaitListManager* manager,
72 int received_packet_count) {
73 return manager->ShouldSendResponse(received_packet_count);
76 static QuicTime::Delta time_wait_period(QuicTimeWaitListManager* manager) {
77 return manager->time_wait_period_;
80 static QuicVersion GetQuicVersionFromConnectionId(
81 QuicTimeWaitListManager* manager,
82 QuicConnectionId connection_id) {
83 return manager->GetQuicVersionFromConnectionId(connection_id);
87 namespace {
89 class MockFakeTimeEpollServer : public FakeTimeEpollServer {
90 public:
91 MOCK_METHOD2(RegisterAlarm, void(int64 timeout_in_us,
92 EpollAlarmCallbackInterface* alarm));
95 class QuicTimeWaitListManagerTest : public ::testing::Test {
96 protected:
97 QuicTimeWaitListManagerTest()
98 : helper_(&epoll_server_),
99 time_wait_list_manager_(&writer_,
100 &visitor_,
101 &helper_,
102 QuicSupportedVersions()),
103 framer_(QuicSupportedVersions(),
104 QuicTime::Zero(),
105 Perspective::IS_SERVER),
106 connection_id_(45),
107 client_address_(net::test::TestPeerIPAddress(), kTestPort),
108 writer_is_blocked_(false) {}
110 ~QuicTimeWaitListManagerTest() override {}
112 void SetUp() override {
113 EXPECT_CALL(writer_, IsWriteBlocked())
114 .WillRepeatedly(ReturnPointee(&writer_is_blocked_));
115 EXPECT_CALL(writer_, IsWriteBlockedDataBuffered())
116 .WillRepeatedly(Return(false));
119 void AddConnectionId(QuicConnectionId connection_id) {
120 AddConnectionId(connection_id, QuicVersionMax(),
121 /*connection_rejected_statelessly=*/false, nullptr);
124 void AddStatelessConnectionId(QuicConnectionId connection_id) {
125 time_wait_list_manager_.AddConnectionIdToTimeWait(
126 connection_id, QuicVersionMax(),
127 /*connection_rejected_statelessly=*/true, nullptr);
130 void AddConnectionId(QuicConnectionId connection_id,
131 QuicVersion version,
132 bool connection_rejected_statelessly,
133 QuicEncryptedPacket* packet) {
134 time_wait_list_manager_.AddConnectionIdToTimeWait(
135 connection_id, version, connection_rejected_statelessly, packet);
138 bool IsConnectionIdInTimeWait(QuicConnectionId connection_id) {
139 return time_wait_list_manager_.IsConnectionIdInTimeWait(connection_id);
142 void ProcessPacket(QuicConnectionId connection_id,
143 QuicPacketNumber packet_number) {
144 QuicEncryptedPacket packet(nullptr, 0);
145 time_wait_list_manager_.ProcessPacket(server_address_, client_address_,
146 connection_id, packet_number, packet);
149 QuicEncryptedPacket* ConstructEncryptedPacket(
150 EncryptionLevel level,
151 QuicConnectionId connection_id,
152 QuicPacketNumber packet_number) {
153 QuicPacketHeader header;
154 header.public_header.connection_id = connection_id;
155 header.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID;
156 header.public_header.version_flag = false;
157 header.public_header.reset_flag = false;
158 header.public_header.packet_number_length = PACKET_6BYTE_PACKET_NUMBER;
159 header.packet_packet_number = packet_number;
160 header.entropy_flag = false;
161 header.entropy_hash = 0;
162 header.fec_flag = false;
163 header.is_in_fec_group = NOT_IN_FEC_GROUP;
164 header.fec_group = 0;
165 QuicStreamFrame stream_frame(1, false, 0, StringPiece("data"));
166 QuicFrame frame(&stream_frame);
167 QuicFrames frames;
168 frames.push_back(frame);
169 scoped_ptr<QuicPacket> packet(
170 BuildUnsizedDataPacket(&framer_, header, frames));
171 EXPECT_TRUE(packet != nullptr);
172 char buffer[kMaxPacketSize];
173 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPayload(
174 ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize));
175 EXPECT_TRUE(encrypted != nullptr);
176 return encrypted->Clone();
179 NiceMock<MockFakeTimeEpollServer> epoll_server_;
180 QuicEpollConnectionHelper helper_;
181 StrictMock<MockPacketWriter> writer_;
182 StrictMock<MockQuicServerSessionVisitor> visitor_;
183 QuicTimeWaitListManager time_wait_list_manager_;
184 QuicFramer framer_;
185 QuicConnectionId connection_id_;
186 IPEndPoint server_address_;
187 IPEndPoint client_address_;
188 bool writer_is_blocked_;
191 class ValidatePublicResetPacketPredicate
192 : public MatcherInterface<const std::tr1::tuple<const char*, int> > {
193 public:
194 explicit ValidatePublicResetPacketPredicate(QuicConnectionId connection_id,
195 QuicPacketNumber number)
196 : connection_id_(connection_id), packet_number_(number) {}
198 bool MatchAndExplain(
199 const std::tr1::tuple<const char*, int> packet_buffer,
200 testing::MatchResultListener* /* listener */) const override {
201 FramerVisitorCapturingPublicReset visitor;
202 QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(),
203 Perspective::IS_CLIENT);
204 framer.set_visitor(&visitor);
205 QuicEncryptedPacket encrypted(std::tr1::get<0>(packet_buffer),
206 std::tr1::get<1>(packet_buffer));
207 framer.ProcessPacket(encrypted);
208 QuicPublicResetPacket packet = visitor.public_reset_packet();
209 return connection_id_ == packet.public_header.connection_id &&
210 packet.public_header.reset_flag &&
211 !packet.public_header.version_flag &&
212 packet_number_ == packet.rejected_packet_number &&
213 net::test::TestPeerIPAddress() == packet.client_address.address() &&
214 kTestPort == packet.client_address.port();
217 void DescribeTo(::std::ostream* os) const override {}
219 void DescribeNegationTo(::std::ostream* os) const override {}
221 private:
222 QuicConnectionId connection_id_;
223 QuicPacketNumber packet_number_;
226 Matcher<const std::tr1::tuple<const char*, int>> PublicResetPacketEq(
227 QuicConnectionId connection_id,
228 QuicPacketNumber packet_number) {
229 return MakeMatcher(
230 new ValidatePublicResetPacketPredicate(connection_id, packet_number));
233 TEST_F(QuicTimeWaitListManagerTest, CheckConnectionIdInTimeWait) {
234 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
235 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
236 AddConnectionId(connection_id_);
237 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
238 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
241 TEST_F(QuicTimeWaitListManagerTest, CheckStatelessConnectionIdInTimeWait) {
242 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
243 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
244 AddStatelessConnectionId(connection_id_);
245 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
246 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
249 TEST_F(QuicTimeWaitListManagerTest, SendConnectionClose) {
250 const size_t kConnectionCloseLength = 100;
251 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
252 AddConnectionId(connection_id_, QuicVersionMax(),
253 /*connection_rejected_statelessly=*/false,
254 new QuicEncryptedPacket(new char[kConnectionCloseLength],
255 kConnectionCloseLength, true));
256 const int kRandomSequenceNumber = 1;
257 EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
258 server_address_.address(),
259 client_address_))
260 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
262 ProcessPacket(connection_id_, kRandomSequenceNumber);
265 TEST_F(QuicTimeWaitListManagerTest, SendPublicReset) {
266 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
267 AddConnectionId(connection_id_);
268 const int kRandomSequenceNumber = 1;
269 EXPECT_CALL(writer_, WritePacket(_, _,
270 server_address_.address(),
271 client_address_))
272 .With(Args<0, 1>(PublicResetPacketEq(connection_id_,
273 kRandomSequenceNumber)))
274 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
276 ProcessPacket(connection_id_, kRandomSequenceNumber);
279 TEST_F(QuicTimeWaitListManagerTest, SendPublicResetWithExponentialBackOff) {
280 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
281 AddConnectionId(connection_id_);
282 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
283 for (int packet_number = 1; packet_number < 101; ++packet_number) {
284 if ((packet_number & (packet_number - 1)) == 0) {
285 EXPECT_CALL(writer_, WritePacket(_, _, _, _))
286 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
288 ProcessPacket(connection_id_, packet_number);
289 // Send public reset with exponential back off.
290 if ((packet_number & (packet_number - 1)) == 0) {
291 EXPECT_TRUE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
292 &time_wait_list_manager_, packet_number));
293 } else {
294 EXPECT_FALSE(QuicTimeWaitListManagerPeer::ShouldSendResponse(
295 &time_wait_list_manager_, packet_number));
300 TEST_F(QuicTimeWaitListManagerTest, NoPublicResetForStatelessConnections) {
301 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
302 AddStatelessConnectionId(connection_id_);
303 const int kRandomSequenceNumber = 1;
304 ProcessPacket(connection_id_, kRandomSequenceNumber);
307 TEST_F(QuicTimeWaitListManagerTest, CleanUpOldConnectionIds) {
308 const size_t kConnectionIdCount = 100;
309 const size_t kOldConnectionIdCount = 31;
311 // Add connection_ids such that their expiry time is time_wait_period_.
312 epoll_server_.set_now_in_usec(0);
313 for (size_t connection_id = 1; connection_id <= kOldConnectionIdCount;
314 ++connection_id) {
315 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
316 AddConnectionId(connection_id);
318 EXPECT_EQ(kOldConnectionIdCount, time_wait_list_manager_.num_connections());
320 // Add remaining connection_ids such that their add time is
321 // 2 * time_wait_period_.
322 const QuicTime::Delta time_wait_period =
323 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
324 epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds());
325 for (size_t connection_id = kOldConnectionIdCount + 1;
326 connection_id <= kConnectionIdCount; ++connection_id) {
327 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
328 AddConnectionId(connection_id);
330 EXPECT_EQ(kConnectionIdCount, time_wait_list_manager_.num_connections());
332 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
333 // Now set the current time as time_wait_period + offset usecs.
334 epoll_server_.set_now_in_usec(time_wait_period.Add(offset).ToMicroseconds());
335 // After all the old connection_ids are cleaned up, check the next alarm
336 // interval.
337 int64 next_alarm_time = epoll_server_.ApproximateNowInUsec() +
338 time_wait_period.Subtract(offset).ToMicroseconds();
339 EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
341 for (size_t connection_id = 1; connection_id <= kConnectionIdCount;
342 ++connection_id) {
343 if (connection_id <= kOldConnectionIdCount) {
344 EXPECT_CALL(visitor_, OnConnectionRemovedFromTimeWaitList(connection_id));
347 time_wait_list_manager_.CleanUpOldConnectionIds();
348 for (size_t connection_id = 1; connection_id <= kConnectionIdCount;
349 ++connection_id) {
350 EXPECT_EQ(connection_id > kOldConnectionIdCount,
351 IsConnectionIdInTimeWait(connection_id))
352 << "kOldConnectionIdCount: " << kOldConnectionIdCount
353 << " connection_id: " << connection_id;
355 EXPECT_EQ(kConnectionIdCount - kOldConnectionIdCount,
356 time_wait_list_manager_.num_connections());
359 TEST_F(QuicTimeWaitListManagerTest, SendQueuedPackets) {
360 QuicConnectionId connection_id = 1;
361 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
362 AddConnectionId(connection_id);
363 QuicPacketNumber packet_number = 234;
364 scoped_ptr<QuicEncryptedPacket> packet(
365 ConstructEncryptedPacket(ENCRYPTION_NONE, connection_id, packet_number));
366 // Let first write through.
367 EXPECT_CALL(writer_,
368 WritePacket(_, _, server_address_.address(), client_address_))
369 .With(Args<0, 1>(PublicResetPacketEq(connection_id, packet_number)))
370 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
371 ProcessPacket(connection_id, packet_number);
373 // write block for the next packet.
374 EXPECT_CALL(writer_,
375 WritePacket(_, _, server_address_.address(), client_address_))
376 .With(Args<0, 1>(PublicResetPacketEq(connection_id, packet_number)))
377 .WillOnce(DoAll(Assign(&writer_is_blocked_, true),
378 Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
379 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
380 ProcessPacket(connection_id, packet_number);
381 // 3rd packet. No public reset should be sent;
382 ProcessPacket(connection_id, packet_number);
384 // write packet should not be called since we are write blocked but the
385 // should be queued.
386 QuicConnectionId other_connection_id = 2;
387 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
388 AddConnectionId(other_connection_id);
389 QuicPacketNumber other_packet_number = 23423;
390 scoped_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
391 ENCRYPTION_NONE, other_connection_id, other_packet_number));
392 EXPECT_CALL(writer_, WritePacket(_, _, _, _))
393 .Times(0);
394 EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
395 ProcessPacket(other_connection_id, other_packet_number);
396 EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
398 // Now expect all the write blocked public reset packets to be sent again.
399 writer_is_blocked_ = false;
400 EXPECT_CALL(writer_,
401 WritePacket(_, _, server_address_.address(), client_address_))
402 .With(Args<0, 1>(PublicResetPacketEq(connection_id, packet_number)))
403 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
404 EXPECT_CALL(writer_,
405 WritePacket(_, _, server_address_.address(), client_address_))
406 .With(Args<0, 1>(
407 PublicResetPacketEq(other_connection_id, other_packet_number)))
408 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, other_packet->length())));
409 time_wait_list_manager_.OnCanWrite();
412 TEST_F(QuicTimeWaitListManagerTest, GetQuicVersionFromMap) {
413 const int kConnectionId1 = 123;
414 const int kConnectionId2 = 456;
415 const int kConnectionId3 = 789;
417 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId1));
418 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId2));
419 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(kConnectionId3));
420 AddConnectionId(kConnectionId1, QuicVersionMin(),
421 /*connection_rejected_statelessly=*/false, nullptr);
422 AddConnectionId(kConnectionId2, QuicVersionMax(),
423 /*connection_rejected_statelessly=*/false, nullptr);
424 AddConnectionId(kConnectionId3, QuicVersionMax(),
425 /*connection_rejected_statelessly=*/false, nullptr);
427 EXPECT_EQ(QuicVersionMin(),
428 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
429 &time_wait_list_manager_, kConnectionId1));
430 EXPECT_EQ(QuicVersionMax(),
431 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
432 &time_wait_list_manager_, kConnectionId2));
433 EXPECT_EQ(QuicVersionMax(),
434 QuicTimeWaitListManagerPeer::GetQuicVersionFromConnectionId(
435 &time_wait_list_manager_, kConnectionId3));
438 TEST_F(QuicTimeWaitListManagerTest, AddConnectionIdTwice) {
439 // Add connection_ids such that their expiry time is time_wait_period_.
440 epoll_server_.set_now_in_usec(0);
441 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
442 AddConnectionId(connection_id_);
443 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
444 const size_t kConnectionCloseLength = 100;
445 AddConnectionId(connection_id_, QuicVersionMax(),
446 /*connection_rejected_statelessly=*/false,
447 new QuicEncryptedPacket(new char[kConnectionCloseLength],
448 kConnectionCloseLength, true));
449 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id_));
450 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
452 EXPECT_CALL(writer_, WritePacket(_,
453 kConnectionCloseLength,
454 server_address_.address(),
455 client_address_))
456 .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
458 const int kRandomSequenceNumber = 1;
459 ProcessPacket(connection_id_, kRandomSequenceNumber);
461 const QuicTime::Delta time_wait_period =
462 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
464 QuicTime::Delta offset = QuicTime::Delta::FromMicroseconds(39);
465 // Now set the current time as time_wait_period + offset usecs.
466 epoll_server_.set_now_in_usec(time_wait_period.Add(offset).ToMicroseconds());
467 // After the connection_ids are cleaned up, check the next alarm interval.
468 int64 next_alarm_time = epoll_server_.ApproximateNowInUsec() +
469 time_wait_period.ToMicroseconds();
471 EXPECT_CALL(epoll_server_, RegisterAlarm(next_alarm_time, _));
472 EXPECT_CALL(visitor_, OnConnectionRemovedFromTimeWaitList(connection_id_));
473 time_wait_list_manager_.CleanUpOldConnectionIds();
474 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id_));
475 EXPECT_EQ(0u, time_wait_list_manager_.num_connections());
478 TEST_F(QuicTimeWaitListManagerTest, ConnectionIdsOrderedByTime) {
479 // Simple randomization: the values of connection_ids are swapped based on the
480 // current seconds on the clock. If the container is broken, the test will be
481 // 50% flaky.
482 int odd_second = static_cast<int>(epoll_server_.ApproximateNowInUsec()) % 2;
483 EXPECT_TRUE(odd_second == 0 || odd_second == 1);
484 const QuicConnectionId connection_id1 = odd_second;
485 const QuicConnectionId connection_id2 = 1 - odd_second;
487 // 1 will hash lower than 2, but we add it later. They should come out in the
488 // add order, not hash order.
489 epoll_server_.set_now_in_usec(0);
490 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id1));
491 AddConnectionId(connection_id1);
492 epoll_server_.set_now_in_usec(10);
493 EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id2));
494 AddConnectionId(connection_id2);
495 EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
497 const QuicTime::Delta time_wait_period =
498 QuicTimeWaitListManagerPeer::time_wait_period(&time_wait_list_manager_);
499 epoll_server_.set_now_in_usec(time_wait_period.ToMicroseconds() + 1);
501 EXPECT_CALL(epoll_server_, RegisterAlarm(_, _));
503 EXPECT_CALL(visitor_, OnConnectionRemovedFromTimeWaitList(connection_id1));
504 time_wait_list_manager_.CleanUpOldConnectionIds();
505 EXPECT_FALSE(IsConnectionIdInTimeWait(connection_id1));
506 EXPECT_TRUE(IsConnectionIdInTimeWait(connection_id2));
507 EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
510 TEST_F(QuicTimeWaitListManagerTest, MaxConnectionsTest) {
511 // Basically, shut off time-based eviction.
512 FLAGS_quic_time_wait_list_seconds = 10000000000;
513 FLAGS_quic_time_wait_list_max_connections = 5;
515 QuicConnectionId current_connection_id = 0;
516 // Add exactly the maximum number of connections
517 for (int64 i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
518 ++current_connection_id;
519 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
520 EXPECT_CALL(visitor_,
521 OnConnectionAddedToTimeWaitList(current_connection_id));
522 AddConnectionId(current_connection_id);
523 EXPECT_EQ(current_connection_id, time_wait_list_manager_.num_connections());
524 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
527 // Now keep adding. Since we're already at the max, every new connection-id
528 // will evict the oldest one.
529 for (int64 i = 0; i < FLAGS_quic_time_wait_list_max_connections; ++i) {
530 ++current_connection_id;
531 const QuicConnectionId id_to_evict =
532 current_connection_id - FLAGS_quic_time_wait_list_max_connections;
533 EXPECT_TRUE(IsConnectionIdInTimeWait(id_to_evict));
534 EXPECT_FALSE(IsConnectionIdInTimeWait(current_connection_id));
535 EXPECT_CALL(visitor_, OnConnectionRemovedFromTimeWaitList(id_to_evict));
536 EXPECT_CALL(visitor_,
537 OnConnectionAddedToTimeWaitList(current_connection_id));
538 AddConnectionId(current_connection_id);
539 EXPECT_EQ(static_cast<size_t>(FLAGS_quic_time_wait_list_max_connections),
540 time_wait_list_manager_.num_connections());
541 EXPECT_FALSE(IsConnectionIdInTimeWait(id_to_evict));
542 EXPECT_TRUE(IsConnectionIdInTimeWait(current_connection_id));
546 } // namespace
547 } // namespace test
548 } // namespace tools
549 } // namespace net