// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/quic_proxy_client_socket.h"

#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_cache.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_response_headers.h"
#include "net/http/transport_security_state.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
#include "net/quic/crypto/proof_verifier_chromium.h"
#include "net/quic/mock_crypto_client_stream_factory.h"
#include "net/quic/mock_quic_data.h"
#include "net/quic/quic_chromium_alarm_factory.h"
#include "net/quic/quic_chromium_client_session.h"
#include "net/quic/quic_chromium_connection_helper.h"
#include "net/quic/quic_chromium_packet_writer.h"
#include "net/quic/quic_http_utils.h"
#include "net/quic/quic_server_info.h"
#include "net/quic/quic_stream_factory.h"
#include "net/quic/quic_test_packet_maker.h"
#include "net/quic/test_task_runner.h"
#include "net/socket/socket_test_util.h"
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/third_party/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quic/core/quic_utils.h"
#include "net/third_party/quic/core/tls_client_handshaker.h"
#include "net/third_party/quic/test_tools/crypto_test_utils.h"
#include "net/third_party/quic/test_tools/mock_clock.h"
#include "net/third_party/quic/test_tools/mock_random.h"
#include "net/third_party/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quic/test_tools/quic_test_utils.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "starboard/memory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::AnyNumber;
using testing::Return;

namespace {

static const char kOriginHost[] = "www.google.com";
static const int kOriginPort = 443;
static const char kProxyUrl[] = "https://myproxy:6121/";
static const char kProxyHost[] = "myproxy";
static const int kProxyPort = 6121;
static const char kUserAgent[] = "Mozilla/1.0";
static const char kRedirectUrl[] = "https://example.com/";

static const char kMsg1[] = "\0hello!\xff";
static const int kLen1 = 8;
static const char kMsg2[] = "\0a2345678\0";
static const int kLen2 = 10;
static const char kMsg3[] = "bye!";
static const int kLen3 = 4;
static const char kMsg33[] = "bye!bye!";
static const int kLen33 = kLen3 + kLen3;
static const char kMsg333[] = "bye!bye!bye!";
static const int kLen333 = kLen3 + kLen3 + kLen3;

}  // anonymous namespace

namespace net {
namespace test {

class QuicProxyClientSocketTest
    : public ::testing::TestWithParam<
          std::tuple<quic::QuicTransportVersion, bool>>,
      public WithScopedTaskEnvironment {
 protected:
  static const bool kFin = true;
  static const bool kIncludeVersion = true;
  static const bool kIncludeDiversificationNonce = true;
  static const bool kIncludeCongestionFeedback = true;
  static const bool kSendFeedback = true;

  static size_t GetStreamFrameDataLengthFromPacketLength(
      quic::QuicByteCount packet_length,
      quic::QuicTransportVersion version,
      bool include_version,
      bool include_diversification_nonce,
      quic::QuicConnectionIdLength connection_id_length,
      quic::QuicPacketNumberLength packet_number_length,
      quic::QuicStreamOffset offset) {
    quic::QuicVariableLengthIntegerLength retry_token_length_length =
        quic::VARIABLE_LENGTH_INTEGER_LENGTH_0;
    quic::QuicVariableLengthIntegerLength length_length =
        quic::QuicVersionHasLongHeaderLengths(version) && include_version
            ? quic::VARIABLE_LENGTH_INTEGER_LENGTH_2
            : quic::VARIABLE_LENGTH_INTEGER_LENGTH_0;
    size_t min_data_length = 1;
    size_t min_packet_length =
        quic::NullEncrypter(quic::Perspective::IS_CLIENT)
            .GetCiphertextSize(min_data_length) +
        quic::QuicPacketCreator::StreamFramePacketOverhead(
            version, quic::PACKET_8BYTE_CONNECTION_ID,
            quic::PACKET_0BYTE_CONNECTION_ID, include_version,
            include_diversification_nonce, packet_number_length,
            retry_token_length_length, length_length, offset);

    DCHECK(packet_length >= min_packet_length);
    return min_data_length + packet_length - min_packet_length;
  }

  QuicProxyClientSocketTest()
      : version_(std::get<0>(GetParam())),
        client_data_stream_id1_(quic::QuicUtils::GetHeadersStreamId(version_) +
                                quic::QuicUtils::StreamIdDelta(version_)),
        client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
        crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
                       quic::TlsClientHandshaker::CreateSslCtx()),
        connection_id_(quic::test::TestConnectionId(2)),
        client_maker_(version_,
                      connection_id_,
                      &clock_,
                      kProxyHost,
                      quic::Perspective::IS_CLIENT,
                      client_headers_include_h2_stream_dependency_),
        server_maker_(version_,
                      connection_id_,
                      &clock_,
                      kProxyHost,
                      quic::Perspective::IS_SERVER,
                      false),
        random_generator_(0),
        header_stream_offset_(0),
        response_offset_(0),
        user_agent_(kUserAgent),
        proxy_host_port_(kProxyHost, kProxyPort),
        endpoint_host_port_(kOriginHost, kOriginPort),
        host_resolver_(new MockCachingHostResolver()),
#if defined(COBALT_QUIC46)
        http_auth_handler_factory_(
            HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())) {
#else
        http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()) {
#endif
    IPAddress ip(192, 0, 2, 33);
    peer_addr_ = IPEndPoint(ip, 443);
    clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
  }

  void SetUp() override {}

  void TearDown() override {
    sock_.reset();
    EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
    EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
  }

  void Initialize() {
    std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
        mock_quic_data_.InitializeAndGetSequencedSocketData(),
        net_log_.bound().net_log()));
    socket->Connect(peer_addr_);
    runner_ = new TestTaskRunner(&clock_);
    send_algorithm_ = new quic::test::MockSendAlgorithm();
    EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
    EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
        .Times(testing::AtLeast(1));
    EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
        .WillRepeatedly(Return(quic::kMaxPacketSize));
    EXPECT_CALL(*send_algorithm_, PacingRate(_))
        .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
    EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
        .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
    EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
    EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
        .Times(AnyNumber());
    helper_.reset(
        new QuicChromiumConnectionHelper(&clock_, &random_generator_));
    alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));

    QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
        socket.get(), base::ThreadTaskRunnerHandle::Get().get());
    quic::QuicConnection* connection = new quic::QuicConnection(
        connection_id_,
        quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
        helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
        quic::Perspective::IS_CLIENT,
        quic::test::SupportedVersions(
            quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
    connection->set_visitor(&visitor_);
    quic::test::QuicConnectionPeer::SetSendAlgorithm(connection,
                                                     send_algorithm_);

    // Load a certificate that is valid for *.example.org
    scoped_refptr<X509Certificate> test_cert(
        ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
    EXPECT_TRUE(test_cert.get());

    verify_details_.cert_verify_result.verified_cert = test_cert;
    verify_details_.cert_verify_result.is_issued_by_known_root = true;
    crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);

    base::TimeTicks dns_end = base::TimeTicks::Now();
    base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);

    session_.reset(new QuicChromiumClientSession(
        connection, std::move(socket),
        /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
        &transport_security_state_, /*ssl_config_service=*/nullptr,
        base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
        QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
                       SocketTag()),
        /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
        /*migrate_session_on_network_change_v2=*/false,
        /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
        quic::QuicTime::Delta::FromMilliseconds(
            kDefaultRetransmittableOnWireTimeoutMillisecs),
        /*migrate_idle_session=*/true,
        base::TimeDelta::FromSeconds(kDefaultIdleSessionMigrationPeriodSeconds),
        base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
        kMaxMigrationsToNonDefaultNetworkOnWriteError,
        kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
        kQuicYieldAfterPacketsRead,
        quic::QuicTime::Delta::FromMilliseconds(
            kQuicYieldAfterDurationMilliseconds),
        /*go_away_on_path_degrading*/ false,
        client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
        quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
        dns_start, dns_end, &push_promise_index_, nullptr,
        base::DefaultTickClock::GetInstance(),
        base::ThreadTaskRunnerHandle::Get().get(),
        /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));

    writer->set_delegate(session_.get());

    session_handle_ =
        session_->CreateHandle(HostPortPair("mail.example.org", 80));

    session_->Initialize();
    TestCompletionCallback callback;
    EXPECT_THAT(session_->CryptoConnect(callback.callback()), IsOk());
    EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());

    EXPECT_THAT(session_handle_->RequestStream(true, callback.callback(),
                                               TRAFFIC_ANNOTATION_FOR_TESTS),
                IsOk());
    std::unique_ptr<QuicChromiumClientStream::Handle> stream_handle =
        session_handle_->ReleaseStream();
    EXPECT_TRUE(stream_handle->IsOpen());

    sock_.reset(new QuicProxyClientSocket(
        std::move(stream_handle), std::move(session_handle_), user_agent_,
        endpoint_host_port_, net_log_.bound(),
        new HttpAuthController(
            HttpAuth::AUTH_PROXY,
            GURL("https://" + proxy_host_port_.ToString()), &http_auth_cache_,
#if defined(COBALT_QUIC46)
            http_auth_handler_factory_.get())));
#else
            http_auth_handler_factory_.get(), host_resolver_.get())));
#endif

    session_->StartReading();
  }

  void PopulateConnectRequestIR(spdy::SpdyHeaderBlock* block) {
    (*block)[":method"] = "CONNECT";
    (*block)[":authority"] = endpoint_host_port_.ToString();
    (*block)["user-agent"] = kUserAgent;
  }

  // Helper functions for constructing packets sent by the client

  std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
      uint64_t packet_number) {
    return client_maker_.MakeInitialSettingsPacket(packet_number,
                                                   &header_stream_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
      uint64_t packet_number,
      quic::QuicRstStreamErrorCode error_code,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked) {
    return client_maker_.MakeAckAndRstPacket(
        packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
        largest_received, smallest_received, least_unacked, kSendFeedback);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstOnlyPacket(
      uint64_t packet_number,
      quic::QuicRstStreamErrorCode error_code,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked,
      size_t bytes_written) {
    return client_maker_.MakeAckAndRstPacket(
        packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
        largest_received, smallest_received, least_unacked, kSendFeedback,
        bytes_written,
        /*include_stop_sending=*/false);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
      uint64_t packet_number,
      quic::QuicRstStreamErrorCode error_code,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked,
      size_t bytes_written) {
    return client_maker_.MakeAckAndRstPacket(
        packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
        largest_received, smallest_received, least_unacked, kSendFeedback,
        bytes_written,
        /*include_stop_sending_if_v99=*/true);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
      uint64_t packet_number,
      quic::QuicRstStreamErrorCode error_code,
      size_t bytes_written) {
    return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
                                       client_data_stream_id1_, error_code,
                                       bytes_written,
                                       /*include_stop_sending_if_v99=*/true);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
      uint64_t packet_number,
      RequestPriority request_priority = LOWEST) {
    spdy::SpdyHeaderBlock block;
    PopulateConnectRequestIR(&block);
    return client_maker_.MakeRequestHeadersPacket(
        packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
        ConvertRequestPriorityToQuicPriority(request_priority),
        std::move(block), 0, nullptr, &header_stream_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
      uint64_t packet_number) {
    spdy::SpdyHeaderBlock block;
    PopulateConnectRequestIR(&block);
    block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
    return client_maker_.MakeRequestHeadersPacket(
        packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
        ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
        nullptr, &header_stream_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
      uint64_t packet_number,
      quic::QuicStreamOffset offset,
      quic::QuicStringPiece data) {
    return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
                                        !kIncludeVersion, !kFin, offset, data);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructMultipleDataFramesPacket(
      uint64_t packet_number,
      quic::QuicStreamOffset offset,
      const std::vector<std::string> data_writes) {
    return client_maker_.MakeMultipleDataFramesPacket(
        packet_number, client_data_stream_id1_, !kIncludeVersion, !kFin, offset,
        data_writes);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
      uint64_t packet_number,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked,
      quic::QuicStreamOffset offset,
      quic::QuicStringPiece data) {
    return client_maker_.MakeAckAndDataPacket(
        packet_number, !kIncludeVersion, client_data_stream_id1_,
        largest_received, smallest_received, least_unacked, !kFin, offset,
        data);
  }

  std::unique_ptr<quic::QuicReceivedPacket>
  ConstructAckAndMultipleDataFramesPacket(
      uint64_t packet_number,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked,
      quic::QuicStreamOffset offset,
      const std::vector<std::string> data_writes) {
    return client_maker_.MakeAckAndMultipleDataFramesPacket(
        packet_number, !kIncludeVersion, client_data_stream_id1_,
        largest_received, smallest_received, least_unacked, !kFin, offset,
        data_writes);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
      uint64_t packet_number,
      uint64_t largest_received,
      uint64_t smallest_received,
      uint64_t least_unacked) {
    return client_maker_.MakeAckPacket(packet_number, largest_received,
                                       smallest_received, least_unacked,
                                       kSendFeedback);
  }

  // Helper functions for constructing packets sent by the server

  std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
      uint64_t packet_number,
      quic::QuicRstStreamErrorCode error_code,
      size_t bytes_written) {
    return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
                                       client_data_stream_id1_, error_code,
                                       bytes_written,
                                       /*include_stop_sending_if_v99=*/true);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
      uint64_t packet_number,
      quic::QuicStreamOffset offset,
      quic::QuicStringPiece data) {
    return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
                                        !kIncludeVersion, !kFin, offset, data);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
      uint64_t packet_number,
      quic::QuicStreamOffset offset,
      quic::QuicStringPiece data) {
    return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
                                        !kIncludeVersion, kFin, offset, data);
  }

  std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
      uint64_t packet_number,
      bool fin) {
    spdy::SpdyHeaderBlock block;
    block[":status"] = "200";

    return server_maker_.MakeResponseHeadersPacket(
        packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
        std::move(block), nullptr, &response_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket>
  ConstructServerConnectAuthReplyPacket(uint64_t packet_number, bool fin) {
    spdy::SpdyHeaderBlock block;
    block[":status"] = "407";
    block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
    return server_maker_.MakeResponseHeadersPacket(
        packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
        std::move(block), nullptr, &response_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket>
  ConstructServerConnectRedirectReplyPacket(uint64_t packet_number, bool fin) {
    spdy::SpdyHeaderBlock block;
    block[":status"] = "302";
    block["location"] = kRedirectUrl;
    block["set-cookie"] = "foo=bar";
    return server_maker_.MakeResponseHeadersPacket(
        packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
        std::move(block), nullptr, &response_offset_);
  }

  std::unique_ptr<quic::QuicReceivedPacket>
  ConstructServerConnectErrorReplyPacket(uint64_t packet_number, bool fin) {
    spdy::SpdyHeaderBlock block;
    block[":status"] = "500";

    return server_maker_.MakeResponseHeadersPacket(
        packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
        std::move(block), nullptr, &response_offset_);
  }

  void AssertConnectSucceeds() {
    TestCompletionCallback callback;
    ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
    ASSERT_THAT(callback.WaitForResult(), IsOk());
  }

  void AssertConnectFails(int result) {
    TestCompletionCallback callback;
    ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
    ASSERT_EQ(result, callback.WaitForResult());
  }

  void ResumeAndRun() {
    // Run until the pause, if the provider isn't paused yet.
    SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
    data->RunUntilPaused();
    data->Resume();
    base::RunLoop().RunUntilIdle();
  }

  void AssertWriteReturns(const char* data, int len, int rv) {
    scoped_refptr<IOBufferWithSize> buf =
        base::MakeRefCounted<IOBufferWithSize>(len);
    SbMemoryCopy(buf->data(), data, len);
    EXPECT_EQ(rv,
              sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
                           TRAFFIC_ANNOTATION_FOR_TESTS));
  }

  void AssertSyncWriteSucceeds(const char* data, int len) {
    scoped_refptr<IOBufferWithSize> buf =
        base::MakeRefCounted<IOBufferWithSize>(len);
    SbMemoryCopy(buf->data(), data, len);
    EXPECT_EQ(len,
              sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
                           TRAFFIC_ANNOTATION_FOR_TESTS));
  }

  void AssertSyncReadEquals(const char* data, int len) {
    scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
    ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
    ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
    ASSERT_TRUE(sock_->IsConnected());
  }

  void AssertAsyncReadEquals(const char* data, int len) {
    scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
    ASSERT_EQ(ERR_IO_PENDING,
              sock_->Read(buf.get(), len, read_callback_.callback()));
    EXPECT_TRUE(sock_->IsConnected());

    ResumeAndRun();

    EXPECT_EQ(len, read_callback_.WaitForResult());
    EXPECT_TRUE(sock_->IsConnected());
    ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
  }

  void AssertReadStarts(const char* data, int len) {
    // Issue the read, which will be completed asynchronously.
    read_buf_ = base::MakeRefCounted<IOBuffer>(len);
    ASSERT_EQ(ERR_IO_PENDING,
              sock_->Read(read_buf_.get(), len, read_callback_.callback()));
    EXPECT_TRUE(sock_->IsConnected());
  }

  void AssertReadReturns(const char* data, int len) {
    EXPECT_TRUE(sock_->IsConnected());

    // Now the read will return.
    EXPECT_EQ(len, read_callback_.WaitForResult());
    ASSERT_EQ(spdy::SpdyString(data, len),
              spdy::SpdyString(read_buf_->data(), len));
  }

  quic::QuicString ConstructDataHeader(size_t body_len) {
    if (version_ != quic::QUIC_VERSION_99) {
      return "";
    }
    quic::HttpEncoder encoder;
    std::unique_ptr<char[]> buffer;
    auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
    return quic::QuicString(buffer.get(), header_length);
  }

  const quic::QuicTransportVersion version_;
  const quic::QuicStreamId client_data_stream_id1_;
  const bool client_headers_include_h2_stream_dependency_;

  // order of destruction of these members matter
  quic::MockClock clock_;
  MockQuicData mock_quic_data_;
  std::unique_ptr<QuicChromiumConnectionHelper> helper_;
  std::unique_ptr<QuicChromiumClientSession> session_;
  std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
  std::unique_ptr<QuicProxyClientSocket> sock_;

  BoundTestNetLog net_log_;

  quic::test::MockSendAlgorithm* send_algorithm_;
  scoped_refptr<TestTaskRunner> runner_;

  std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
  testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
  TransportSecurityState transport_security_state_;
  quic::QuicCryptoClientConfig crypto_config_;
  quic::QuicClientPushPromiseIndex push_promise_index_;

  const quic::QuicConnectionId connection_id_;
  QuicTestPacketMaker client_maker_;
  QuicTestPacketMaker server_maker_;
  IPEndPoint peer_addr_;
  quic::test::MockRandom random_generator_;
  ProofVerifyDetailsChromium verify_details_;
  MockCryptoClientStreamFactory crypto_client_stream_factory_;
  quic::QuicStreamOffset header_stream_offset_;
  quic::QuicStreamOffset response_offset_;

  std::string user_agent_;
  HostPortPair proxy_host_port_;
  HostPortPair endpoint_host_port_;
  HttpAuthCache http_auth_cache_;
  std::unique_ptr<MockHostResolverBase> host_resolver_;
  std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;

  TestCompletionCallback read_callback_;
  scoped_refptr<IOBuffer> read_buf_;

  TestCompletionCallback write_callback_;

  DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocketTest);
};

TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  ASSERT_FALSE(sock_->IsConnected());

  AssertConnectSucceeds();

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != nullptr);
  ASSERT_EQ(200, response->headers->response_code());
}

TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC,
                          ConstructServerConnectAuthReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != nullptr);
  ASSERT_EQ(407, response->headers->response_code());
}

TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectAuthRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  // Add auth to cache
  const base::string16 kFoo(base::ASCIIToUTF16("foo"));
  const base::string16 kBar(base::ASCIIToUTF16("bar"));
  http_auth_cache_.Add(GURL(kProxyUrl), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
                       "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar),
                       "/");

  AssertConnectSucceeds();

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != nullptr);
  ASSERT_EQ(200, response->headers->response_code());
}

TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC,
                          ConstructServerConnectRedirectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT);

  const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
  ASSERT_TRUE(response != nullptr);

  const HttpResponseHeaders* headers = response->headers.get();
  ASSERT_EQ(302, headers->response_code());
  ASSERT_FALSE(headers->HasHeader("set-cookie"));
  ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));

  std::string location;
  ASSERT_TRUE(headers->IsRedirect(&location));
  ASSERT_EQ(location, kRedirectUrl);
}

TEST_P(QuicProxyClientSocketTest, ConnectFails) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, 0);  // EOF

  Initialize();

  ASSERT_FALSE(sock_->IsConnected());

  AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);

  ASSERT_FALSE(sock_->IsConnected());
}

TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  EXPECT_TRUE(sock_->WasEverUsed());  // Used due to crypto handshake
  AssertConnectSucceeds();
  EXPECT_TRUE(sock_->WasEverUsed());
  sock_->Disconnect();
  EXPECT_TRUE(sock_->WasEverUsed());
}

TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
  mock_quic_data_.AddRead(ASYNC, 0);               // EOF

  Initialize();

  IPEndPoint addr;
  EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));

  AssertConnectSucceeds();
  EXPECT_TRUE(sock_->IsConnected());
  EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());

  ResumeAndRun();

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));

  sock_->Disconnect();

  EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
}

TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  EXPECT_FALSE(sock_->IsConnectedAndIdle());

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnectedAndIdle());

  // The next read is consumed and buffered.
  ResumeAndRun();

  EXPECT_FALSE(sock_->IsConnectedAndIdle());

  AssertSyncReadEquals(kMsg1, kLen1);

  EXPECT_TRUE(sock_->IsConnectedAndIdle());
}

TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen333);
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 2, 0, header + quic::QuicString(kMsg333, kLen333)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  EXPECT_EQ(0, sock_->GetTotalReceivedBytes());

  AssertConnectSucceeds();

  EXPECT_EQ(0, sock_->GetTotalReceivedBytes());

  // The next read is consumed and buffered.
  ResumeAndRun();

  EXPECT_EQ(0, sock_->GetTotalReceivedBytes());

  // The payload from the single large data frame will be read across
  // two different reads.
  AssertSyncReadEquals(kMsg33, kLen33);

  EXPECT_EQ((int64_t)(kLen33 + header.length()),
            sock_->GetTotalReceivedBytes());

  AssertSyncReadEquals(kMsg3, kLen3);

  EXPECT_EQ((int64_t)(kLen333 + header.length()),
            sock_->GetTotalReceivedBytes());
}

TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  // Despite setting the priority to HIGHEST, the requets initial priority of
  // LOWEST is used.
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructConnectRequestPacket(2, LOWEST));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  sock_->SetStreamPriority(HIGHEST);
  AssertConnectSucceeds();
}

TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  if (version_ == quic::QUIC_VERSION_99) {
    quic::QuicString header = ConstructDataHeader(kLen1);
    mock_quic_data_.AddWrite(
        SYNCHRONOUS,
        ConstructAckAndMultipleDataFramesPacket(
            3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
    quic::QuicString header2 = ConstructDataHeader(kLen2);
    mock_quic_data_.AddWrite(SYNCHRONOUS,
                             ConstructMultipleDataFramesPacket(
                                 4, kLen1 + header.length(),
                                 {header2, quic::QuicString(kMsg2, kLen2)}));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS,
        ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED,
                           kLen1 + kLen2 + header.length() + header2.length()));
  } else {
    mock_quic_data_.AddWrite(
        SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
                                               quic::QuicString(kMsg1, kLen1)));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS,
        ConstructDataPacket(4, kLen1, quic::QuicString(kMsg2, kLen2)));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS,
        ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
  }

  Initialize();

  AssertConnectSucceeds();

  AssertSyncWriteSucceeds(kMsg1, kLen1);
  AssertSyncWriteSucceeds(kMsg2, kLen2);
}

TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
  int write_packet_index = 1;
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructSettingsPacket(write_packet_index++));
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructConnectRequestPacket(write_packet_index++));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  quic::QuicString header = ConstructDataHeader(kLen1);
  if (version_ != quic::QUIC_VERSION_99) {
    mock_quic_data_.AddWrite(
        SYNCHRONOUS, ConstructAckAndDataPacket(write_packet_index++, 1, 1, 1, 0,
                                               quic::QuicString(kMsg1, kLen1)));
  } else {
    mock_quic_data_.AddWrite(SYNCHRONOUS,
                             ConstructAckAndMultipleDataFramesPacket(
                                 write_packet_index++, 1, 1, 1, 0,
                                 {header, quic::QuicString(kMsg1, kLen1)}));
  }

  // Expect |kNumDataPackets| data packets, each containing the max possible
  // amount of data.
  int numDataPackets = 3;
  std::string data(numDataPackets * quic::kDefaultMaxPacketSize, 'x');
  quic::QuicStreamOffset offset = kLen1 + header.length();

  if (version_ == quic::QUIC_VERSION_99) {
    numDataPackets++;
  }
  size_t total_data_length = 0;
  for (int i = 0; i < numDataPackets; ++i) {
    size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
        quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
        !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
        quic::PACKET_1BYTE_PACKET_NUMBER, offset);
    if (version_ == quic::QUIC_VERSION_99 && i == 0) {
      // 3973 is the data frame length from packet length.
      quic::QuicString header2 = ConstructDataHeader(3973);
      mock_quic_data_.AddWrite(
          SYNCHRONOUS,
          ConstructMultipleDataFramesPacket(
              write_packet_index++, offset,
              {header2,
               quic::QuicString(data.c_str(), max_packet_data_length - 7)}));
      offset += max_packet_data_length - header2.length() - 1;
    } else if (version_ == quic::QUIC_VERSION_99 && i == numDataPackets - 1) {
      mock_quic_data_.AddWrite(
          SYNCHRONOUS, ConstructDataPacket(write_packet_index++, offset,
                                           quic::QuicString(data.c_str(), 7)));
      offset += 7;
    } else {
      mock_quic_data_.AddWrite(
          SYNCHRONOUS,
          ConstructDataPacket(
              write_packet_index++, offset,
              quic::QuicString(data.c_str(), max_packet_data_length)));
      offset += max_packet_data_length;
    }
    if (i != 3) {
      total_data_length += max_packet_data_length;
    }
  }

  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(write_packet_index++,
                                      quic::QUIC_STREAM_CANCELLED, offset));

  Initialize();

  AssertConnectSucceeds();

  // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
  // ACK and STOP_WAITING from being bundled with the subsequent large write.
  // This allows the test code for computing the size of data sent in each
  // packet to not become too complicated.
  AssertSyncWriteSucceeds(kMsg1, kLen1);

  // Make large write that should be split up
  AssertSyncWriteSucceeds(data.c_str(), total_data_length);
}

// ----------- Read

TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();
  AssertSyncReadEquals(kMsg1, kLen1);
}

TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header2 = ConstructDataHeader(kLen2);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen1 + header.length(),
                                     header2 + quic::QuicString(kMsg2, kLen2)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();
  AssertSyncReadEquals(kMsg1, kLen1);

  ResumeAndRun();
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  quic::QuicString header2 = ConstructDataHeader(kLen2);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen1 + header.length(),
                                     header2 + quic::QuicString(kMsg2, kLen2)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));

  Initialize();

  AssertConnectSucceeds();

  // The next two reads are consumed and buffered.
  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen3);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg3, kLen3)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  quic::QuicString header2 = ConstructDataHeader(kLen3);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen3 + header.length(),
                                     header2 + quic::QuicString(kMsg3, kLen3)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));

  Initialize();

  AssertConnectSucceeds();

  // The next two reads are consumed and buffered.
  ResumeAndRun();
  // The payload from two data frames, each with kMsg3 will be combined
  // together into a single read().
  AssertSyncReadEquals(kMsg33, kLen33);
}

TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  int offset = 0;

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 2, offset, header + quic::QuicString(kMsg1, kLen1)));
  offset += kLen1 + header.length();
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));

  quic::QuicString header2 = ConstructDataHeader(kLen3);
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 3, offset, header2 + quic::QuicString(kMsg3, kLen3)));
  offset += kLen3 + header2.length();
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 4, offset, header2 + quic::QuicString(kMsg3, kLen3)));
  offset += kLen3 + header2.length();
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));

  quic::QuicString header3 = ConstructDataHeader(kLen2);
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 5, offset, header3 + quic::QuicString(kMsg2, kLen2)));
  offset += kLen2 + header3.length();
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 5, 5, 1));

  Initialize();

  AssertConnectSucceeds();

  // The next 4 reads are consumed and buffered.
  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);
  // The payload from two data frames, each with kMsg3 will be combined
  // together into a single read().
  AssertSyncReadEquals(kMsg33, kLen33);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  quic::QuicString header2 = ConstructDataHeader(kLen33);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(3, kLen1 + header.length(),
                                header2 + quic::QuicString(kMsg33, kLen33)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));

  Initialize();

  AssertConnectSucceeds();

  // The next 2 reads are consumed and buffered.
  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);
  // The payload from the single large data frame will be read across
  // two different reads.
  AssertSyncReadEquals(kMsg3, kLen3);
  AssertSyncReadEquals(kMsg3, kLen3);
}

TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen333);
  mock_quic_data_.AddRead(
      ASYNC, ConstructServerDataPacket(
                 2, 0, header + quic::QuicString(kMsg333, kLen333)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  AssertConnectSucceeds();

  // The next read is consumed and buffered.
  ResumeAndRun();

  // The payload from the single large data frame will be read across
  // two different reads.
  AssertSyncReadEquals(kMsg33, kLen33);

  // Now attempt to do a read of more data than remains buffered
  scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen33);
  ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
  ASSERT_EQ(spdy::SpdyString(kMsg3, kLen3),
            spdy::SpdyString(buf->data(), kLen3));
  ASSERT_TRUE(sock_->IsConnected());
}

TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC,
                          ConstructServerConnectAuthReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  quic::QuicString header2 = ConstructDataHeader(kLen2);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen1 + header.length(),
                                     header2 + quic::QuicString(kMsg2, kLen2)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));

  Initialize();

  AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);

  // The next two reads are consumed and buffered.
  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);
  AssertSyncReadEquals(kMsg2, kLen2);
}

TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC,
                          ConstructServerConnectErrorReplyPacket(1, !kFin));
  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      SYNCHRONOUS,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  quic::QuicString header2 = ConstructDataHeader(kLen2);
  mock_quic_data_.AddRead(
      SYNCHRONOUS,
      ConstructServerDataPacket(3, kLen1 + header.length(),
                                header2 + quic::QuicString(kMsg2, kLen2)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
  Initialize();

  AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
}

// ----------- Reads and Writes

TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
  int write_packet_index = 1;
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructSettingsPacket(write_packet_index++));
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructConnectRequestPacket(write_packet_index++));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS,
                           ConstructAckPacket(write_packet_index++, 2, 1, 1));

  quic::QuicString header2 = ConstructDataHeader(kLen2);
  if (version_ == quic::QUIC_VERSION_99) {
    mock_quic_data_.AddWrite(SYNCHRONOUS,
                             ConstructMultipleDataFramesPacket(
                                 write_packet_index++, 0,
                                 {header2, quic::QuicString(kMsg2, kLen2)}));
  } else {
    mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header2.length(),
                                       quic::QuicString(kMsg2, kLen2)));
  }

  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header3 = ConstructDataHeader(kLen3);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen1 + header.length(),
                                     header3 + quic::QuicString(kMsg3, kLen3)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructAckAndRstPacket(write_packet_index++,
                                            quic::QUIC_STREAM_CANCELLED, 3, 3,
                                            1, kLen2 + header2.length()));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);

  AssertReadStarts(kMsg3, kLen3);
  // Read should block until after the write succeeds.

  AssertSyncWriteSucceeds(kMsg2, kLen2);

  ASSERT_FALSE(read_callback_.have_result());
  ResumeAndRun();

  // Now the read will return.
  AssertReadReturns(kMsg3, kLen3);
}

TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header2 = ConstructDataHeader(kLen3);
  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
                                     3, kLen1 + header.length(),
                                     header2 + quic::QuicString(kMsg3, kLen3)));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);

  mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header3 = ConstructDataHeader(kLen2);
  if (version_ != quic::QUIC_VERSION_99) {
    mock_quic_data_.AddWrite(
        ASYNC, ConstructDataPacket(4, 0, quic::QuicString(kMsg2, kLen2)));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS, ConstructAckAndDataPacket(5, 3, 3, 1, kLen2,
                                               quic::QuicString(kMsg2, kLen2)));
  } else {
    mock_quic_data_.AddWrite(
        ASYNC, ConstructMultipleDataFramesPacket(
                   4, 0, {header3, quic::QuicString(kMsg2, kLen2)}));
    mock_quic_data_.AddWrite(
        ASYNC,
        ConstructAckAndDataPacket(5, 3, 3, 1, header3.length() + kLen2,
                                  header3 + quic::QuicString(kMsg2, kLen2)));
  }

  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(6, quic::QUIC_STREAM_CANCELLED,
                                      kLen2 + kLen2 + 2 * header3.length()));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();
  AssertSyncReadEquals(kMsg1, kLen1);

  // Write should block until the next read completes.
  // QuicChromiumClientStream::Handle::WriteStreamData() will only be
  // asynchronous starting with the second time it's called while the UDP socket
  // is write-blocked. Therefore, at least two writes need to be called on
  // |sock_| to get an asynchronous one.
  AssertWriteReturns(kMsg2, kLen2, kLen2);
  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);

  AssertAsyncReadEquals(kMsg3, kLen3);

  ASSERT_FALSE(write_callback_.have_result());

  // Now the write will complete
  ResumeAndRun();
  EXPECT_EQ(kLen2, write_callback_.WaitForResult());
}

// ----------- Reading/Writing on Closed socket

// Reading from an already closed socket should return 0
TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  mock_quic_data_.AddRead(ASYNC, 0);  // EOF

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();

  ASSERT_FALSE(sock_->IsConnected());
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
  ASSERT_FALSE(sock_->IsConnectedAndIdle());
}

// Read pending when socket is closed should return 0
TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  mock_quic_data_.AddRead(ASYNC, 0);  // EOF

  Initialize();

  AssertConnectSucceeds();

  AssertReadStarts(kMsg1, kLen1);

  ResumeAndRun();

  ASSERT_EQ(0, read_callback_.WaitForResult());
}

// Reading from a disconnected socket is an error
TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  AssertConnectSucceeds();

  sock_->Disconnect();

  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Read(nullptr, 1, CompletionOnceCallback()));
}

// Reading data after receiving FIN should return buffered data received before
// FIN, then 0.
TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(ASYNC,
                          ConstructServerDataFinPacket(
                              2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();

  AssertSyncReadEquals(kMsg1, kLen1);
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
  ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));

  sock_->Disconnect();
  ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
            sock_->Read(nullptr, 1, CompletionOnceCallback()));
}

// Calling Write() on a closed socket is an error.
TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  mock_quic_data_.AddRead(ASYNC, 0);  // EOF

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();

  AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
}

// Calling Write() on a disconnected socket is an error.
TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  AssertConnectSucceeds();

  sock_->Disconnect();

  AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
}

// If the socket is closed with a pending Write(), the callback should be called
// with the same error the session was closed with.
TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);

  Initialize();

  AssertConnectSucceeds();

  // QuicChromiumClientStream::Handle::WriteStreamData() will only be
  // asynchronous starting with the second time it's called while the UDP socket
  // is write-blocked. Therefore, at least two writes need to be called on
  // |sock_| to get an asynchronous one.
  AssertWriteReturns(kMsg1, kLen1, kLen1);

  // This second write will be async. This is the pending write that's being
  // tested.
  AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);

  // Make sure the write actually starts.
  base::RunLoop().RunUntilIdle();

  session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
                                quic::QUIC_INTERNAL_ERROR,
                                quic::ConnectionCloseBehavior::SILENT_CLOSE);

  EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
}

TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);

  Initialize();

  AssertConnectSucceeds();

  // QuicChromiumClientStream::Handle::WriteStreamData() will only be
  // asynchronous starting with the second time it's called while the UDP socket
  // is write-blocked. Therefore, at least two writes need to be called on
  // |sock_| to get an asynchronous one.
  AssertWriteReturns(kMsg1, kLen1, kLen1);

  // This second write will be async. This is the pending write that's being
  // tested.
  AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);

  // Make sure the write actually starts.
  base::RunLoop().RunUntilIdle();

  sock_->Disconnect();
  EXPECT_FALSE(sock_->IsConnected());

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_FALSE(write_callback_.have_result());
}

// If the socket is Disconnected with a pending Read(), the callback
// should not be called.
TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS,
      ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));

  Initialize();

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  AssertReadStarts(kMsg1, kLen1);

  sock_->Disconnect();
  EXPECT_FALSE(sock_->IsConnected());

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(sock_->IsConnected());
  EXPECT_FALSE(read_callback_.have_result());
}

// If the socket is Reset when both a read and write are pending,
// both should be called back.
TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  mock_quic_data_.AddRead(
      ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  quic::QuicString header = ConstructDataHeader(kLen2);
  if (version_ != quic::QUIC_VERSION_99) {
    mock_quic_data_.AddWrite(
        ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
                                         quic::QuicString(kMsg2, kLen2)));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
                                              2, 2, 1, kLen2));
  } else {
    mock_quic_data_.AddWrite(
        ASYNC, ConstructAckAndMultipleDataFramesPacket(
                   3, 1, 1, 1, 0, {header, quic::QuicString(kMsg2, kLen2)}));
    mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
                                              4, quic::QUIC_STREAM_CANCELLED, 2,
                                              2, 1, header.length() + kLen2));
  }

  Initialize();

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  AssertReadStarts(kMsg1, kLen1);

  // Write should block until the next read completes.
  // QuicChromiumClientStream::Handle::WriteStreamData() will only be
  // asynchronous starting with the second time it's called while the UDP socket
  // is write-blocked. Therefore, at least two writes need to be called on
  // |sock_| to get an asynchronous one.
  AssertWriteReturns(kMsg2, kLen2, kLen2);

  AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);

  ResumeAndRun();

  EXPECT_TRUE(read_callback_.have_result());
  EXPECT_TRUE(write_callback_.have_result());
}

// Makes sure the proxy client socket's source gets the expected NetLog events
// and only the expected NetLog events (No SpdySession events).
TEST_P(QuicProxyClientSocketTest, NetLog) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  quic::QuicString header = ConstructDataHeader(kLen1);
  mock_quic_data_.AddRead(
      ASYNC,
      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  mock_quic_data_.AddWrite(
      SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));

  Initialize();

  AssertConnectSucceeds();

  ResumeAndRun();
  AssertSyncReadEquals(kMsg1, kLen1);

  NetLogSource sock_source = sock_->NetLog().source();
  sock_.reset();

  TestNetLogEntry::List entry_list;
  net_log_.GetEntriesForSource(sock_source, &entry_list);

  ASSERT_EQ(entry_list.size(), 10u);
  EXPECT_TRUE(
      LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
  EXPECT_TRUE(LogContainsEvent(entry_list, 1,
                               NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
                               NetLogEventPhase::NONE));
  EXPECT_TRUE(LogContainsBeginEvent(
      entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
  EXPECT_TRUE(LogContainsEvent(
      entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
      NetLogEventPhase::NONE));
  EXPECT_TRUE(LogContainsEndEvent(
      entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
  EXPECT_TRUE(LogContainsBeginEvent(
      entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
  EXPECT_TRUE(LogContainsEvent(
      entry_list, 6,
      NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
      NetLogEventPhase::NONE));
  EXPECT_TRUE(LogContainsEndEvent(
      entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
  EXPECT_TRUE(LogContainsEvent(entry_list, 8,
                               NetLogEventType::SOCKET_BYTES_RECEIVED,
                               NetLogEventPhase::NONE));
  EXPECT_TRUE(
      LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
}

// A helper class that will delete |sock| when the callback is invoked.
class DeleteSockCallback : public TestCompletionCallbackBase {
 public:
  explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
      : sock_(sock) {}

  ~DeleteSockCallback() override {}

  CompletionOnceCallback callback() {
    return base::BindOnce(&DeleteSockCallback::OnComplete,
                          base::Unretained(this));
  }

 private:
  void OnComplete(int result) {
    sock_->reset(NULL);
    SetResult(result);
  }

  std::unique_ptr<QuicProxyClientSocket>* sock_;

  DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
};

// If the socket is reset when both a read and write are pending, and the
// read callback causes the socket to be deleted, the write callback should
// not be called.
TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
  mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
  mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause

  mock_quic_data_.AddRead(
      ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
  mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
  if (version_ != quic::QUIC_VERSION_99) {
    mock_quic_data_.AddWrite(
        ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
                                         quic::QuicString(kMsg1, kLen1)));
    mock_quic_data_.AddWrite(
        SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
                                              2, 2, 1, kLen1));
  } else {
    quic::QuicString header = ConstructDataHeader(kLen1);
    mock_quic_data_.AddWrite(
        ASYNC, ConstructAckAndMultipleDataFramesPacket(
                   3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
    mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
                                              4, quic::QUIC_STREAM_CANCELLED, 2,
                                              2, 1, header.length() + kLen1));
  }

  Initialize();

  AssertConnectSucceeds();

  EXPECT_TRUE(sock_->IsConnected());

  DeleteSockCallback read_callback(&sock_);
  scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
  ASSERT_EQ(ERR_IO_PENDING,
            sock_->Read(read_buf.get(), kLen1, read_callback.callback()));

  // QuicChromiumClientStream::Handle::WriteStreamData() will only be
  // asynchronous starting with the second time it's called while the UDP socket
  // is write-blocked. Therefore, at least two writes need to be called on
  // |sock_| to get an asynchronous one.
  AssertWriteReturns(kMsg1, kLen1, kLen1);

  AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);

  ResumeAndRun();

  EXPECT_FALSE(sock_.get());

  EXPECT_EQ(0, read_callback.WaitForResult());
  EXPECT_FALSE(write_callback_.have_result());
}

INSTANTIATE_TEST_SUITE_P(
    VersionIncludeStreamDependencySequence,
    QuicProxyClientSocketTest,
    ::testing::Combine(
        ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
        ::testing::Bool()));

}  // namespace test
}  // namespace net
