1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_dispatcher.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/crypto/crypto_handshake.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/crypto/crypto_server_config.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/quic/crypto/quic_random.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_crypto_stream.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/flip_server/epoll_server.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_time_wait_list_manager.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_utils.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::StringPiece; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::EpollServer; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::test::MockSession; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::tools::test::MockConnection; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::_; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::DoAll; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::Invoke; 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::InSequence; 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::Return; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::WithoutArgs; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcherPeer { 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static void SetTimeWaitListManager( 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicTimeWaitListManager* time_wait_list_manager) { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher->time_wait_list_manager_.reset(time_wait_list_manager); 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static void SetWriteBlocked(QuicDispatcher* dispatcher) { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher->write_blocked_ = true; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestDispatcher : public QuicDispatcher { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit TestDispatcher(const QuicConfig& config, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicCryptoServerConfig& crypto_config, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : QuicDispatcher(config, crypto_config, 1, eps) {} 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD4(CreateQuicSession, QuicSession*( 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& client_address, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int fd, 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps)); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) using QuicDispatcher::write_blocked_list; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A Connection class which unregisters the session from the dispatcher 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when sending connection close. 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// It'd be slightly more realistic to do this from the Session but it would 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// involve a lot more mocking. 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockServerConnection : public MockConnection { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockServerConnection(QuicGuid guid, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint address, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int fd, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : MockConnection(guid, address, fd, eps, true), 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_(dispatcher) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UnregisterOnConnectionClose() { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unregistering " << guid(); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_->OnConnectionClose(guid(), QUIC_NO_ERROR); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher_; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicSession* CreateSession(QuicDispatcher* dispatcher, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& addr, 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockSession** session, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps) { 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockServerConnection* connection = 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new MockServerConnection(guid, addr, 0, eps, dispatcher); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *session = new MockSession(connection, true); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WithoutArgs(Invoke( 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) connection, &MockServerConnection::UnregisterOnConnectionClose))); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessUdpPacket(_, addr, _)); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *session; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcherTest : public ::testing::Test { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcherTest() 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : crypto_config_(QuicCryptoServerConfig::TESTING, 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicRandom::GetInstance()), 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_(config_, crypto_config_, &eps_), 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session1_(NULL), 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session2_(NULL) { 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~QuicDispatcherTest() {} 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnection* connection1() { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return reinterpret_cast<MockConnection*>(session1_->connection()); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnection* connection2() { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return reinterpret_cast<MockConnection*>(session2_->connection()); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ProcessPacket(IPEndPoint addr, 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const string& data) { 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicEncryptedPacket packet(data.data(), data.length()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.ProcessPacket(IPEndPoint(), addr, guid, packet); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ValidatePacket(const QuicEncryptedPacket& packet) { 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(packet.AsStringPiece().find(data_) != StringPiece::npos); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPAddressNumber Loopback4() { 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::IPAddressNumber addr; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(net::ParseIPLiteralToNumber("127.0.0.1", &addr)); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return addr; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer eps_; 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicConfig config_; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCryptoServerConfig crypto_config_; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestDispatcher dispatcher_; 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockSession* session1_; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockSession* session2_; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string data_; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, ProcessPackets) { 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint addr(Loopback4(), 1); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(1, addr, _, &eps_)) 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, 1, addr, &session1_, &eps_))); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 1, "foo"); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(2, addr, _, &eps_)) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, 2, addr, &session2_, &eps_))); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 2, "bar"); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) data_ = "eep"; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessUdpPacket(_, _, _)).Times(1). 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WillOnce(testing::WithArgs<2>(Invoke( 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, &QuicDispatcherTest::ValidatePacket))); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 1, "eep"); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, Shutdown) { 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint addr(Loopback4(), 1); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_)) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, 1, addr, &session1_, &eps_))); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 1, "foo"); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendConnectionClose(QUIC_PEER_GOING_AWAY)); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.Shutdown(); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockTimeWaitListManager : public QuicTimeWaitListManager { 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockTimeWaitListManager(QuicPacketWriter* writer, 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps) 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : QuicTimeWaitListManager(writer, eps) { 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address, 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& client_address, 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicEncryptedPacket& packet)); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, TimeWaitListManager) { 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockTimeWaitListManager* time_wait_list_manager = 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new MockTimeWaitListManager(&dispatcher_, &eps_); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // dispatcher takes the ownership of time_wait_list_manager. 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_wait_list_manager); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create a new session. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint addr(Loopback4(), 1); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid = 1; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(guid, addr, _, &eps_)) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, guid, addr, &session1_, &eps_))); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, guid, "foo"); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Close the connection by sending public reset packet. 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicPublicResetPacket packet; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.public_header.guid = guid; 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.public_header.reset_flag = true; 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.public_header.version_flag = false; 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.rejected_sequence_number = 19191; 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.nonce_proof = 132232; 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<QuicEncryptedPacket> encrypted( 2212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch QuicFramer::BuildPublicResetPacket(packet)); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*session1_, ConnectionClose(QUIC_PUBLIC_RESET, true)).Times(1) 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(WithoutArgs(Invoke( 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<MockServerConnection*>(session1_->connection()), 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &MockServerConnection::UnregisterOnConnectionClose))); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessUdpPacket(_, _, _)) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(Invoke( 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<MockConnection*>(session1_->connection()), 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &MockConnection::ReallyProcessUdpPacket)); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.ProcessPacket(IPEndPoint(), addr, guid, *encrypted); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(time_wait_list_manager->IsGuidInTimeWait(guid)); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Dispatcher forwards subsequent packets for this guid to the time wait list 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // manager. 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, guid, "foo"); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WriteBlockedListTest : public QuicDispatcherTest { 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() { 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint addr(Loopback4(), 1); 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_)) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, 1, addr, &session1_, &eps_))); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 1, "foo"); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(_, addr, _, &eps_)) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &dispatcher_, 2, addr, &session2_, &eps_))); 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessPacket(addr, 2, "bar"); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_ = dispatcher_.write_blocked_list(); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void TearDown() { 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.Shutdown(); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool SetBlocked() { 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcherPeer::SetWriteBlocked(&dispatcher_); 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher::WriteBlockedList* blocked_list_; 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, BasicOnCanWrite) { 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No OnCanWrite calls because no connections are blocked. 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Register connection 1 for events, and make sure it's nofitied. 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It should get only one notification. 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(dispatcher_.OnCanWrite()); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, OnCanWriteOrder) { 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure we handle events in order. 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check the other ordering. 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, OnCanWriteRemove) { 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add and remove one connction. 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->RemoveBlockedObject(connection1()); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add and remove one connction and make sure it doesn't affect others. 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->RemoveBlockedObject(connection1()); 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add it, remove it, and add it back and make sure things are OK. 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->RemoveBlockedObject(connection1()); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, DoubleAdd) { 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure a double add does not necessitate a double remove. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->RemoveBlockedObject(connection1()); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure a double add does not result in two OnCanWrite calls. 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, OnCanWriteHandleBlock) { 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Finally make sure if we write block on a write call, we stop calling. 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Invoke(this, &WriteBlockedListTest::SetBlocked)); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // And we'll resume where we left off when we get another call. 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, LimitedWrites) { 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure we call both writers. The first will register for more writing 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // but should not be immediately called due to limits. 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce(Return(true)); 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce(Return(false)); 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now call OnCanWrite again, and connection1 should get its second chance 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WriteBlockedListTest, TestWriteLimits) { 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Finally make sure if we write block on a write call, we stop calling. 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection1()); 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blocked_list_->AddBlockedObject(connection2()); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Invoke(this, &WriteBlockedListTest::SetBlocked)); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // And we'll resume where we left off when we get another call. 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace test 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace tools 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 391