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" 110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/quic/crypto/quic_crypto_server_config.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/quic/crypto/quic_random.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_crypto_stream.h" 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_flags.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/epoll_server/epoll_server.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/tools/quic/quic_packet_writer_wrapper.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_time_wait_list_manager.h" 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/tools/quic/test_tools/quic_dispatcher_peer.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/test_tools/quic_test_utils.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::StringPiece; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::EpollServer; 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using net::test::ConstructEncryptedPacket; 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using net::test::MockSession; 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using net::test::ValueRestore; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using net::tools::test::MockConnection; 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using std::make_pair; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::DoAll; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::InSequence; 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using testing::Invoke; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using testing::WithoutArgs; 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using testing::_; 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestDispatcher : public QuicDispatcher { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit TestDispatcher(const QuicConfig& config, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicCryptoServerConfig& crypto_config, 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps) 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : QuicDispatcher(config, 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch crypto_config, 50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch QuicSupportedVersions(), 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new QuicDispatcher::DefaultPacketWriterFactory(), 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) eps) { 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MOCK_METHOD3(CreateQuicSession, QuicSession*( 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const IPEndPoint& server_address, 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const IPEndPoint& client_address)); 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch using QuicDispatcher::current_server_address; 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch using QuicDispatcher::current_client_address; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A Connection class which unregisters the session from the dispatcher 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when sending connection close. 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// It'd be slightly more realistic to do this from the Session but it would 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// involve a lot more mocking. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MockServerConnection : public MockConnection { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MockServerConnection(QuicConnectionId connection_id, 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : MockConnection(connection_id, true), 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_(dispatcher) {} 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void UnregisterOnConnectionClosed() { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Unregistering " << connection_id(); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicSession* CreateSession(QuicDispatcher* dispatcher, 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id, 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IPEndPoint& client_address, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MockSession** session) { 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MockServerConnection* connection = 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new MockServerConnection(connection_id, dispatcher); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *session = new MockSession(connection); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WithoutArgs(Invoke( 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) connection, &MockServerConnection::UnregisterOnConnectionClosed))); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessUdpPacket(_, client_address, _)); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *session; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcherTest : public ::testing::Test { 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcherTest() 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : crypto_config_(QuicCryptoServerConfig::TESTING, 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QuicRandom::GetInstance()), 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_(config_, crypto_config_, &eps_), 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session1_(NULL), 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session2_(NULL) { 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.Initialize(1); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~QuicDispatcherTest() {} 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnection* connection1() { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return reinterpret_cast<MockConnection*>(session1_->connection()); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockConnection* connection2() { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return reinterpret_cast<MockConnection*>(session2_->connection()); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void ProcessPacket(IPEndPoint client_address, 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id, 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool has_version_flag, 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const string& data) { 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) connection_id, has_version_flag, false, 1, data)); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data_ = string(packet->data(), packet->length()); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) dispatcher_.ProcessPacket(server_address_, client_address, *packet); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ValidatePacket(const QuicEncryptedPacket& packet) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(data_, packet.AsStringPiece()); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer eps_; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicConfig config_; 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicCryptoServerConfig crypto_config_; 138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint server_address_; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestDispatcher dispatcher_; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockSession* session1_; 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockSession* session2_; 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string data_; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, ProcessPackets) { 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint client_address(net::test::Loopback4(), 1); 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPAddressNumber any4; 148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); 149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch server_address_ = IPEndPoint(any4, 5); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address)) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, 1, client_address, &session1_))); 154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 1, true, "foo"); 155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_EQ(client_address, dispatcher_.current_client_address()); 156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_EQ(server_address_, dispatcher_.current_server_address()); 157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(2, _, client_address)) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, 2, client_address, &session2_))); 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 2, true, "bar"); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 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))); 168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 1, false, "eep"); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, Shutdown) { 172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint client_address(net::test::Loopback4(), 1); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, 1, client_address, &session1_))); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 1, true, "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, 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicServerSessionVisitor* visitor, 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* eps) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MOCK_METHOD5(ProcessPacket, void(const IPEndPoint& server_address, 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& client_address, 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id, 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch QuicPacketSequenceNumber sequence_number, 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const QuicEncryptedPacket& packet)); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicDispatcherTest, TimeWaitListManager) { 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockTimeWaitListManager* time_wait_list_manager = 2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) new MockTimeWaitListManager( 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // dispatcher takes the ownership of time_wait_list_manager. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_wait_list_manager); 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create a new session. 209e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint client_address(net::test::Loopback4(), 1); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id = 1; 211e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, client_address)) 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 213e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, connection_id, client_address, &session1_))); 214e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, connection_id, true, "foo"); 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Close the connection by sending public reset packet. 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicPublicResetPacket packet; 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) packet.public_header.connection_id = connection_id; 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.public_header.reset_flag = true; 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.public_header.version_flag = false; 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.rejected_sequence_number = 19191; 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet.nonce_proof = 132232; 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<QuicEncryptedPacket> encrypted( 2242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch QuicFramer::BuildPublicResetPacket(packet)); 2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)).Times(1) 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(WithoutArgs(Invoke( 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<MockServerConnection*>(session1_->connection()), 2281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &MockServerConnection::UnregisterOnConnectionClosed))); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ProcessUdpPacket(_, _, _)) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(Invoke( 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<MockConnection*>(session1_->connection()), 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &MockConnection::ReallyProcessUdpPacket)); 234e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dispatcher_.ProcessPacket(IPEndPoint(), client_address, *encrypted); 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(time_wait_list_manager->IsConnectionIdInTimeWait(connection_id)); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatcher forwards subsequent packets for this connection_id to the time 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // wait list manager. 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*time_wait_list_manager, 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ProcessPacket(_, _, connection_id, _, _)).Times(1); 241e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, connection_id, true, "foo"); 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MockTimeWaitListManager* time_wait_list_manager = 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new MockTimeWaitListManager( 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // dispatcher takes the ownership of time_wait_list_manager. 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) time_wait_list_manager); 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 252e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint client_address(net::test::Loopback4(), 1); 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) QuicConnectionId connection_id = 1; 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatcher forwards all packets for this connection_id to the time wait 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // list manager. 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*time_wait_list_manager, 2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ProcessPacket(_, _, connection_id, _, _)).Times(1); 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) string data = "foo"; 260e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, connection_id, false, "foo"); 261e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 262e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BlockingWriter : public QuicPacketWriterWrapper { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BlockingWriter() : write_blocked_(false) {} 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool IsWriteBlocked() const OVERRIDE { return write_blocked_; } 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetWritable() OVERRIDE { write_blocked_ = false; } 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual WriteResult WritePacket( 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* buffer, 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t buf_len, 273e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IPAddressNumber& self_client_address, 274e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IPEndPoint& peer_client_address) OVERRIDE { 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // It would be quite possible to actually implement this method here with 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // the fake blocked status, but it would be significantly more work in 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Chromium, and since it's not called anyway, don't bother. 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOG(DFATAL) << "Not supported"; 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return WriteResult(); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool write_blocked_; 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() { 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writer_ = new BlockingWriter; 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicDispatcherPeer::SetPacketWriterFactory(&dispatcher_, 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new TestWriterFactory()); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicDispatcherPeer::UseWriter(&dispatcher_, writer_); 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 293e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint client_address(net::test::Loopback4(), 1); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 297e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, 1, client_address, &session1_))); 298e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 1, true, "foo"); 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) .WillOnce(testing::Return(CreateSession( 302e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &dispatcher_, 2, client_address, &session2_))); 303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ProcessPacket(client_address, 2, true, "bar"); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(&dispatcher_); 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void TearDown() { 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.Shutdown(); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetBlocked() { 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) writer_->write_blocked_ = true; 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void BlockConnection2() { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writer_->write_blocked_ = true; 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BlockingWriter* writer_; 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher::WriteBlockedList* blocked_list_; 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, BasicOnCanWrite) { 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No OnCanWrite calls because no connections are blocked. 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Register connection 1 for events, and make sure it's notified. 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It should get only one notification. 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dispatcher_.OnCanWrite(); 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(dispatcher_.HasPendingWrites()); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteOrder) { 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure we handle events in order. 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check the other ordering. 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteRemove) { 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add and remove one connction. 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) blocked_list_->erase(connection1()); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add and remove one connction and make sure it doesn't affect others. 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) blocked_list_->erase(connection1()); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add it, remove it, and add it back and make sure things are OK. 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) blocked_list_->erase(connection1()); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, DoubleAdd) { 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure a double add does not necessitate a double remove. 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) blocked_list_->erase(connection1()); 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(0); 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure a double add does not result in two OnCanWrite calls. 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) { 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Finally make sure if we write block on a write call, we stop calling. 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // And we'll resume where we left off when we get another call. 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) { 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure we call both writers. The first will register for more writing 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // but should not be immediately called due to limits. 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()); 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).WillOnce( 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Invoke(this, &QuicDispatcherWriteBlockedListTest::BlockConnection2)); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(dispatcher_.HasPendingWrites()); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now call OnCanWrite again, and connection1 should get its second chance 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(dispatcher_.HasPendingWrites()); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) { 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Finally make sure if we write block on a write call, we stop calling. 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) InSequence s; 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBlocked(); 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection1()); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dispatcher_.OnWriteBlocked(connection2()); 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_TRUE(dispatcher_.HasPendingWrites()); 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // And we'll resume where we left off when we get another call. 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*connection2(), OnCanWrite()); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_.OnCanWrite(); 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_FALSE(dispatcher_.HasPendingWrites()); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace test 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace tools 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 462