| 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_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/strings/string_piece.h" | 9 #include "base/strings/string_piece.h" |
| 10 #include "net/quic/crypto/crypto_handshake.h" | 10 #include "net/quic/crypto/crypto_handshake.h" |
| 11 #include "net/quic/crypto/quic_crypto_server_config.h" | 11 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 12 #include "net/quic/crypto/quic_random.h" | 12 #include "net/quic/crypto/quic_random.h" |
| 13 #include "net/quic/quic_crypto_stream.h" | 13 #include "net/quic/quic_crypto_stream.h" |
| 14 #include "net/quic/test_tools/quic_test_utils.h" | 14 #include "net/quic/test_tools/quic_test_utils.h" |
| 15 #include "net/quic/test_tools/quic_test_writer.h" | |
| 16 #include "net/tools/epoll_server/epoll_server.h" | 15 #include "net/tools/epoll_server/epoll_server.h" |
| 16 #include "net/tools/quic/quic_packet_writer_wrapper.h" |
| 17 #include "net/tools/quic/quic_time_wait_list_manager.h" | 17 #include "net/tools/quic/quic_time_wait_list_manager.h" |
| 18 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" | 18 #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" |
| 19 #include "net/tools/quic/test_tools/quic_test_utils.h" | 19 #include "net/tools/quic/test_tools/quic_test_utils.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 22 |
| 23 using base::StringPiece; | 23 using base::StringPiece; |
| 24 using net::EpollServer; | 24 using net::EpollServer; |
| 25 using net::test::MockSession; | 25 using net::test::MockSession; |
| 26 using net::test::QuicTestWriter; | |
| 27 using net::tools::test::MockConnection; | 26 using net::tools::test::MockConnection; |
| 28 using std::make_pair; | 27 using std::make_pair; |
| 29 using testing::_; | 28 using testing::_; |
| 30 using testing::DoAll; | 29 using testing::DoAll; |
| 31 using testing::Invoke; | 30 using testing::Invoke; |
| 32 using testing::InSequence; | 31 using testing::InSequence; |
| 33 using testing::Return; | 32 using testing::Return; |
| 34 using testing::WithoutArgs; | 33 using testing::WithoutArgs; |
| 35 | 34 |
| 36 namespace net { | 35 namespace net { |
| 37 namespace tools { | 36 namespace tools { |
| 38 namespace test { | 37 namespace test { |
| 39 namespace { | 38 namespace { |
| 40 | 39 |
| 41 class TestDispatcher : public QuicDispatcher { | 40 class TestDispatcher : public QuicDispatcher { |
| 42 public: | 41 public: |
| 43 explicit TestDispatcher(const QuicConfig& config, | 42 explicit TestDispatcher(const QuicConfig& config, |
| 44 const QuicCryptoServerConfig& crypto_config, | 43 const QuicCryptoServerConfig& crypto_config, |
| 45 EpollServer* eps) | 44 EpollServer* eps) |
| 46 : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), 1, eps) { | 45 : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), eps) { |
| 47 } | 46 } |
| 48 | 47 |
| 49 MOCK_METHOD3(CreateQuicSession, QuicSession*( | 48 MOCK_METHOD3(CreateQuicSession, QuicSession*( |
| 50 QuicGuid guid, | 49 QuicGuid guid, |
| 51 const IPEndPoint& server_address, | 50 const IPEndPoint& server_address, |
| 52 const IPEndPoint& client_address)); | 51 const IPEndPoint& client_address)); |
| 53 using QuicDispatcher::write_blocked_list; | 52 using QuicDispatcher::write_blocked_list; |
| 54 }; | 53 }; |
| 55 | 54 |
| 56 // A Connection class which unregisters the session from the dispatcher | 55 // A Connection class which unregisters the session from the dispatcher |
| 57 // when sending connection close. | 56 // when sending connection close. |
| 58 // It'd be slightly more realistic to do this from the Session but it would | 57 // It'd be slightly more realistic to do this from the Session but it would |
| 59 // involve a lot more mocking. | 58 // involve a lot more mocking. |
| 60 class MockServerConnection : public MockConnection { | 59 class MockServerConnection : public MockConnection { |
| 61 public: | 60 public: |
| 62 MockServerConnection(QuicGuid guid, | 61 MockServerConnection(QuicGuid guid, |
| 63 QuicDispatcher* dispatcher) | 62 QuicDispatcher* dispatcher) |
| 64 : MockConnection(guid, true), | 63 : MockConnection(guid, true), |
| 65 dispatcher_(dispatcher) { | 64 dispatcher_(dispatcher) {} |
| 66 } | 65 |
| 67 void UnregisterOnConnectionClosed() { | 66 void UnregisterOnConnectionClosed() { |
| 68 LOG(ERROR) << "Unregistering " << guid(); | 67 LOG(ERROR) << "Unregistering " << guid(); |
| 69 dispatcher_->OnConnectionClosed(guid(), QUIC_NO_ERROR); | 68 dispatcher_->OnConnectionClosed(guid(), QUIC_NO_ERROR); |
| 70 } | 69 } |
| 71 private: | 70 private: |
| 72 QuicDispatcher* dispatcher_; | 71 QuicDispatcher* dispatcher_; |
| 73 }; | 72 }; |
| 74 | 73 |
| 75 QuicSession* CreateSession(QuicDispatcher* dispatcher, | 74 QuicSession* CreateSession(QuicDispatcher* dispatcher, |
| 76 QuicGuid guid, | 75 QuicGuid guid, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 88 } | 87 } |
| 89 | 88 |
| 90 class QuicDispatcherTest : public ::testing::Test { | 89 class QuicDispatcherTest : public ::testing::Test { |
| 91 public: | 90 public: |
| 92 QuicDispatcherTest() | 91 QuicDispatcherTest() |
| 93 : crypto_config_(QuicCryptoServerConfig::TESTING, | 92 : crypto_config_(QuicCryptoServerConfig::TESTING, |
| 94 QuicRandom::GetInstance()), | 93 QuicRandom::GetInstance()), |
| 95 dispatcher_(config_, crypto_config_, &eps_), | 94 dispatcher_(config_, crypto_config_, &eps_), |
| 96 session1_(NULL), | 95 session1_(NULL), |
| 97 session2_(NULL) { | 96 session2_(NULL) { |
| 97 dispatcher_.Initialize(1); |
| 98 } | 98 } |
| 99 | 99 |
| 100 virtual ~QuicDispatcherTest() {} | 100 virtual ~QuicDispatcherTest() {} |
| 101 | 101 |
| 102 MockConnection* connection1() { | 102 MockConnection* connection1() { |
| 103 return reinterpret_cast<MockConnection*>(session1_->connection()); | 103 return reinterpret_cast<MockConnection*>(session1_->connection()); |
| 104 } | 104 } |
| 105 | 105 |
| 106 MockConnection* connection2() { | 106 MockConnection* connection2() { |
| 107 return reinterpret_cast<MockConnection*>(session2_->connection()); | 107 return reinterpret_cast<MockConnection*>(session2_->connection()); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 195 |
| 196 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), | 196 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), |
| 197 SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 197 SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 198 | 198 |
| 199 dispatcher_.Shutdown(); | 199 dispatcher_.Shutdown(); |
| 200 } | 200 } |
| 201 | 201 |
| 202 class MockTimeWaitListManager : public QuicTimeWaitListManager { | 202 class MockTimeWaitListManager : public QuicTimeWaitListManager { |
| 203 public: | 203 public: |
| 204 MockTimeWaitListManager(QuicPacketWriter* writer, | 204 MockTimeWaitListManager(QuicPacketWriter* writer, |
| 205 QuicServerSessionVisitor* visitor, |
| 205 EpollServer* eps) | 206 EpollServer* eps) |
| 206 : QuicTimeWaitListManager(writer, eps, QuicSupportedVersions()) { | 207 : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { |
| 207 } | 208 } |
| 208 | 209 |
| 209 MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address, | 210 MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address, |
| 210 const IPEndPoint& client_address, | 211 const IPEndPoint& client_address, |
| 211 QuicGuid guid, | 212 QuicGuid guid, |
| 212 QuicPacketSequenceNumber sequence_number)); | 213 QuicPacketSequenceNumber sequence_number)); |
| 213 }; | 214 }; |
| 214 | 215 |
| 215 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 216 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
| 216 MockTimeWaitListManager* time_wait_list_manager = | 217 MockTimeWaitListManager* time_wait_list_manager = |
| 217 new MockTimeWaitListManager( | 218 new MockTimeWaitListManager( |
| 218 QuicDispatcherPeer::GetWriter(&dispatcher_), &eps_); | 219 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 219 // dispatcher takes the ownership of time_wait_list_manager. | 220 // dispatcher takes the ownership of time_wait_list_manager. |
| 220 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 221 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 221 time_wait_list_manager); | 222 time_wait_list_manager); |
| 222 // Create a new session. | 223 // Create a new session. |
| 223 IPEndPoint addr(net::test::Loopback4(), 1); | 224 IPEndPoint addr(net::test::Loopback4(), 1); |
| 224 QuicGuid guid = 1; | 225 QuicGuid guid = 1; |
| 225 EXPECT_CALL(dispatcher_, CreateQuicSession(guid, _, addr)) | 226 EXPECT_CALL(dispatcher_, CreateQuicSession(guid, _, addr)) |
| 226 .WillOnce(testing::Return(CreateSession( | 227 .WillOnce(testing::Return(CreateSession( |
| 227 &dispatcher_, guid, addr, &session1_))); | 228 &dispatcher_, guid, addr, &session1_))); |
| 228 ProcessPacket(addr, guid, true, "foo"); | 229 ProcessPacket(addr, guid, true, "foo"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 250 | 251 |
| 251 // Dispatcher forwards subsequent packets for this guid to the time wait list | 252 // Dispatcher forwards subsequent packets for this guid to the time wait list |
| 252 // manager. | 253 // manager. |
| 253 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); | 254 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); |
| 254 ProcessPacket(addr, guid, true, "foo"); | 255 ProcessPacket(addr, guid, true, "foo"); |
| 255 } | 256 } |
| 256 | 257 |
| 257 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { | 258 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { |
| 258 MockTimeWaitListManager* time_wait_list_manager = | 259 MockTimeWaitListManager* time_wait_list_manager = |
| 259 new MockTimeWaitListManager( | 260 new MockTimeWaitListManager( |
| 260 QuicDispatcherPeer::GetWriter(&dispatcher_), &eps_); | 261 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 261 // dispatcher takes the ownership of time_wait_list_manager. | 262 // dispatcher takes the ownership of time_wait_list_manager. |
| 262 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 263 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 263 time_wait_list_manager); | 264 time_wait_list_manager); |
| 264 | 265 |
| 265 IPEndPoint addr(net::test::Loopback4(), 1); | 266 IPEndPoint addr(net::test::Loopback4(), 1); |
| 266 QuicGuid guid = 1; | 267 QuicGuid guid = 1; |
| 267 // Dispatcher forwards all packets for this guid to the time wait list | 268 // Dispatcher forwards all packets for this guid to the time wait list |
| 268 // manager. | 269 // manager. |
| 269 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); | 270 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); |
| 270 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); | 271 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); |
| 271 string data = "foo"; | 272 string data = "foo"; |
| 272 ProcessPacket(addr, guid, false, "foo"); | 273 ProcessPacket(addr, guid, false, "foo"); |
| 273 } | 274 } |
| 274 | 275 |
| 275 class BlockingWriter : public QuicTestWriter { | 276 class BlockingWriter : public QuicPacketWriterWrapper { |
| 276 public: | 277 public: |
| 277 BlockingWriter() : write_blocked_(false) {} | 278 BlockingWriter() : write_blocked_(false) {} |
| 278 | 279 |
| 279 virtual bool IsWriteBlocked() const OVERRIDE { return write_blocked_; } | 280 virtual bool IsWriteBlocked() const OVERRIDE { return write_blocked_; } |
| 280 virtual void SetWritable() OVERRIDE { write_blocked_ = false; } | 281 virtual void SetWritable() OVERRIDE { write_blocked_ = false; } |
| 281 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE { return false; } | |
| 282 | 282 |
| 283 virtual WriteResult WritePacket( | 283 virtual WriteResult WritePacket( |
| 284 const char* buffer, size_t buf_len, const IPAddressNumber& self_address, | 284 const char* buffer, |
| 285 size_t buf_len, |
| 286 const IPAddressNumber& self_address, |
| 285 const IPEndPoint& peer_address, | 287 const IPEndPoint& peer_address, |
| 286 QuicBlockedWriterInterface* blocked_writer) OVERRIDE { | 288 QuicBlockedWriterInterface* blocked_writer) OVERRIDE { |
| 287 if (write_blocked_) { | 289 if (write_blocked_) { |
| 288 return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN); | 290 return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN); |
| 289 } else { | 291 } else { |
| 290 return writer()->WritePacket(buffer, buf_len, self_address, peer_address, | 292 return QuicPacketWriterWrapper::WritePacket( |
| 291 blocked_writer); | 293 buffer, buf_len, self_address, peer_address, blocked_writer); |
| 292 } | 294 } |
| 293 } | 295 } |
| 294 | 296 |
| 295 bool write_blocked_; | 297 bool write_blocked_; |
| 296 }; | 298 }; |
| 297 | 299 |
| 298 class QuicWriteBlockedListTest : public QuicDispatcherTest { | 300 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { |
| 299 public: | 301 public: |
| 300 virtual void SetUp() { | 302 virtual void SetUp() { |
| 301 writer_ = new BlockingWriter; | 303 writer_ = new BlockingWriter; |
| 302 QuicDispatcherPeer::UseWriter(&dispatcher_, writer_); | 304 QuicDispatcherPeer::UseWriter(&dispatcher_, writer_); |
| 303 | 305 |
| 304 IPEndPoint addr(net::test::Loopback4(), 1); | 306 IPEndPoint addr(net::test::Loopback4(), 1); |
| 305 | 307 |
| 306 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, addr)) | 308 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, addr)) |
| 307 .WillOnce(testing::Return(CreateSession( | 309 .WillOnce(testing::Return(CreateSession( |
| 308 &dispatcher_, 1, addr, &session1_))); | 310 &dispatcher_, 1, addr, &session1_))); |
| 309 ProcessPacket(addr, 1, true, "foo"); | 311 ProcessPacket(addr, 1, true, "foo"); |
| 310 | 312 |
| 311 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, addr)) | 313 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, addr)) |
| 312 .WillOnce(testing::Return(CreateSession( | 314 .WillOnce(testing::Return(CreateSession( |
| 313 &dispatcher_, 2, addr, &session2_))); | 315 &dispatcher_, 2, addr, &session2_))); |
| 314 ProcessPacket(addr, 2, true, "bar"); | 316 ProcessPacket(addr, 2, true, "bar"); |
| 315 | 317 |
| 316 blocked_list_ = dispatcher_.write_blocked_list(); | 318 blocked_list_ = dispatcher_.write_blocked_list(); |
| 317 } | 319 } |
| 318 | 320 |
| 319 virtual void TearDown() { | 321 virtual void TearDown() { |
| 320 EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 322 EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 321 EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 323 EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 322 dispatcher_.Shutdown(); | 324 dispatcher_.Shutdown(); |
| 323 } | 325 } |
| 324 | 326 |
| 325 bool SetBlocked() { | 327 bool SetBlocked() { |
| 326 writer_->write_blocked_ = true;; | 328 writer_->write_blocked_ = true; |
| 327 return true; | 329 return true; |
| 328 } | 330 } |
| 329 | 331 |
| 330 protected: | 332 protected: |
| 331 BlockingWriter* writer_; | 333 BlockingWriter* writer_; |
| 332 QuicDispatcher::WriteBlockedList* blocked_list_; | 334 QuicDispatcher::WriteBlockedList* blocked_list_; |
| 333 }; | 335 }; |
| 334 | 336 |
| 335 TEST_F(QuicWriteBlockedListTest, BasicOnCanWrite) { | 337 TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) { |
| 336 // No OnCanWrite calls because no connections are blocked. | 338 // No OnCanWrite calls because no connections are blocked. |
| 337 dispatcher_.OnCanWrite(); | 339 dispatcher_.OnCanWrite(); |
| 338 | 340 |
| 339 // Register connection 1 for events, and make sure it's nofitied. | 341 // Register connection 1 for events, and make sure it's notified. |
| 340 blocked_list_->insert(make_pair(connection1(), true)); | 342 SetBlocked(); |
| 343 dispatcher_.OnWriteBlocked(connection1()); |
| 341 EXPECT_CALL(*connection1(), OnCanWrite()); | 344 EXPECT_CALL(*connection1(), OnCanWrite()); |
| 342 dispatcher_.OnCanWrite(); | 345 dispatcher_.OnCanWrite(); |
| 343 | 346 |
| 344 // It should get only one notification. | 347 // It should get only one notification. |
| 345 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); | 348 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); |
| 346 EXPECT_FALSE(dispatcher_.OnCanWrite()); | 349 EXPECT_FALSE(dispatcher_.OnCanWrite()); |
| 347 } | 350 } |
| 348 | 351 |
| 349 TEST_F(QuicWriteBlockedListTest, OnCanWriteOrder) { | 352 TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) { |
| 350 // Make sure we handle events in order. | 353 // Make sure we handle events in order. |
| 351 InSequence s; | 354 InSequence s; |
| 352 blocked_list_->insert(make_pair(connection1(), true)); | 355 SetBlocked(); |
| 353 blocked_list_->insert(make_pair(connection2(), true)); | 356 dispatcher_.OnWriteBlocked(connection1()); |
| 357 dispatcher_.OnWriteBlocked(connection2()); |
| 354 EXPECT_CALL(*connection1(), OnCanWrite()); | 358 EXPECT_CALL(*connection1(), OnCanWrite()); |
| 355 EXPECT_CALL(*connection2(), OnCanWrite()); | 359 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 356 dispatcher_.OnCanWrite(); | 360 dispatcher_.OnCanWrite(); |
| 357 | 361 |
| 358 // Check the other ordering. | 362 // Check the other ordering. |
| 359 blocked_list_->insert(make_pair(connection2(), true)); | 363 SetBlocked(); |
| 360 blocked_list_->insert(make_pair(connection1(), true)); | 364 dispatcher_.OnWriteBlocked(connection2()); |
| 365 dispatcher_.OnWriteBlocked(connection1()); |
| 361 EXPECT_CALL(*connection2(), OnCanWrite()); | 366 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 362 EXPECT_CALL(*connection1(), OnCanWrite()); | 367 EXPECT_CALL(*connection1(), OnCanWrite()); |
| 363 dispatcher_.OnCanWrite(); | 368 dispatcher_.OnCanWrite(); |
| 364 } | 369 } |
| 365 | 370 |
| 366 TEST_F(QuicWriteBlockedListTest, OnCanWriteRemove) { | 371 TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) { |
| 367 // Add and remove one connction. | 372 // Add and remove one connction. |
| 368 blocked_list_->insert(make_pair(connection1(), true)); | 373 SetBlocked(); |
| 374 dispatcher_.OnWriteBlocked(connection1()); |
| 369 blocked_list_->erase(connection1()); | 375 blocked_list_->erase(connection1()); |
| 370 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); | 376 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); |
| 371 dispatcher_.OnCanWrite(); | 377 dispatcher_.OnCanWrite(); |
| 372 | 378 |
| 373 // Add and remove one connction and make sure it doesn't affect others. | 379 // Add and remove one connction and make sure it doesn't affect others. |
| 374 blocked_list_->insert(make_pair(connection1(), true)); | 380 SetBlocked(); |
| 375 blocked_list_->insert(make_pair(connection2(), true)); | 381 dispatcher_.OnWriteBlocked(connection1()); |
| 382 dispatcher_.OnWriteBlocked(connection2()); |
| 376 blocked_list_->erase(connection1()); | 383 blocked_list_->erase(connection1()); |
| 377 EXPECT_CALL(*connection2(), OnCanWrite()); | 384 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 378 dispatcher_.OnCanWrite(); | 385 dispatcher_.OnCanWrite(); |
| 379 | 386 |
| 380 // Add it, remove it, and add it back and make sure things are OK. | 387 // Add it, remove it, and add it back and make sure things are OK. |
| 381 blocked_list_->insert(make_pair(connection1(), true)); | 388 SetBlocked(); |
| 389 dispatcher_.OnWriteBlocked(connection1()); |
| 382 blocked_list_->erase(connection1()); | 390 blocked_list_->erase(connection1()); |
| 383 blocked_list_->insert(make_pair(connection1(), true)); | 391 dispatcher_.OnWriteBlocked(connection1()); |
| 384 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); | 392 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); |
| 385 dispatcher_.OnCanWrite(); | 393 dispatcher_.OnCanWrite(); |
| 386 } | 394 } |
| 387 | 395 |
| 388 TEST_F(QuicWriteBlockedListTest, DoubleAdd) { | 396 TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) { |
| 389 // Make sure a double add does not necessitate a double remove. | 397 // Make sure a double add does not necessitate a double remove. |
| 390 blocked_list_->insert(make_pair(connection1(), true)); | 398 SetBlocked(); |
| 391 blocked_list_->insert(make_pair(connection1(), true)); | 399 dispatcher_.OnWriteBlocked(connection1()); |
| 400 dispatcher_.OnWriteBlocked(connection1()); |
| 392 blocked_list_->erase(connection1()); | 401 blocked_list_->erase(connection1()); |
| 393 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); | 402 EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); |
| 394 dispatcher_.OnCanWrite(); | 403 dispatcher_.OnCanWrite(); |
| 395 | 404 |
| 396 // Make sure a double add does not result in two OnCanWrite calls. | 405 // Make sure a double add does not result in two OnCanWrite calls. |
| 397 blocked_list_->insert(make_pair(connection1(), true)); | 406 SetBlocked(); |
| 398 blocked_list_->insert(make_pair(connection1(), true)); | 407 dispatcher_.OnWriteBlocked(connection1()); |
| 408 dispatcher_.OnWriteBlocked(connection1()); |
| 399 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); | 409 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); |
| 400 dispatcher_.OnCanWrite(); | 410 dispatcher_.OnCanWrite(); |
| 401 } | 411 } |
| 402 | 412 |
| 403 TEST_F(QuicWriteBlockedListTest, OnCanWriteHandleBlock) { | 413 TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) { |
| 404 // Finally make sure if we write block on a write call, we stop calling. | 414 // Finally make sure if we write block on a write call, we stop calling. |
| 405 InSequence s; | 415 InSequence s; |
| 406 blocked_list_->insert(make_pair(connection1(), true)); | 416 SetBlocked(); |
| 407 blocked_list_->insert(make_pair(connection2(), true)); | 417 dispatcher_.OnWriteBlocked(connection1()); |
| 418 dispatcher_.OnWriteBlocked(connection2()); |
| 408 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( | 419 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( |
| 409 Invoke(this, &QuicWriteBlockedListTest::SetBlocked)); | 420 Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); |
| 410 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 421 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 411 dispatcher_.OnCanWrite(); | 422 dispatcher_.OnCanWrite(); |
| 412 | 423 |
| 413 // And we'll resume where we left off when we get another call. | 424 // And we'll resume where we left off when we get another call. |
| 414 EXPECT_CALL(*connection2(), OnCanWrite()); | 425 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 415 dispatcher_.OnCanWrite(); | 426 dispatcher_.OnCanWrite(); |
| 416 } | 427 } |
| 417 | 428 |
| 418 TEST_F(QuicWriteBlockedListTest, LimitedWrites) { | 429 TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) { |
| 419 // Make sure we call both writers. The first will register for more writing | 430 // Make sure we call both writers. The first will register for more writing |
| 420 // but should not be immediately called due to limits. | 431 // but should not be immediately called due to limits. |
| 421 InSequence s; | 432 InSequence s; |
| 422 blocked_list_->insert(make_pair(connection1(), true)); | 433 SetBlocked(); |
| 423 blocked_list_->insert(make_pair(connection2(), true)); | 434 dispatcher_.OnWriteBlocked(connection1()); |
| 435 dispatcher_.OnWriteBlocked(connection2()); |
| 424 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(Return(true)); | 436 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(Return(true)); |
| 425 EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce(Return(false)); | 437 EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce(Return(false)); |
| 426 dispatcher_.OnCanWrite(); | 438 dispatcher_.OnCanWrite(); |
| 427 | 439 |
| 428 // Now call OnCanWrite again, and connection1 should get its second chance | 440 // Now call OnCanWrite again, and connection1 should get its second chance |
| 429 EXPECT_CALL(*connection1(), OnCanWrite()); | 441 EXPECT_CALL(*connection1(), OnCanWrite()); |
| 430 dispatcher_.OnCanWrite(); | 442 dispatcher_.OnCanWrite(); |
| 431 } | 443 } |
| 432 | 444 |
| 433 TEST_F(QuicWriteBlockedListTest, TestWriteLimits) { | 445 TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) { |
| 434 // Finally make sure if we write block on a write call, we stop calling. | 446 // Finally make sure if we write block on a write call, we stop calling. |
| 435 InSequence s; | 447 InSequence s; |
| 436 blocked_list_->insert(make_pair(connection1(), true)); | 448 SetBlocked(); |
| 437 blocked_list_->insert(make_pair(connection2(), true)); | 449 dispatcher_.OnWriteBlocked(connection1()); |
| 450 dispatcher_.OnWriteBlocked(connection2()); |
| 438 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( | 451 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( |
| 439 Invoke(this, &QuicWriteBlockedListTest::SetBlocked)); | 452 Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); |
| 440 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 453 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 441 dispatcher_.OnCanWrite(); | 454 dispatcher_.OnCanWrite(); |
| 442 | 455 |
| 443 // And we'll resume where we left off when we get another call. | 456 // And we'll resume where we left off when we get another call. |
| 444 EXPECT_CALL(*connection2(), OnCanWrite()); | 457 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 445 dispatcher_.OnCanWrite(); | 458 dispatcher_.OnCanWrite(); |
| 446 } | 459 } |
| 447 | 460 |
| 448 } // namespace | 461 } // namespace |
| 449 } // namespace test | 462 } // namespace test |
| 450 } // namespace tools | 463 } // namespace tools |
| 451 } // namespace net | 464 } // namespace net |
| OLD | NEW |