// Copyright (c) 2012 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/spdy/spdy_session.h"

#include <algorithm>
#include <string>
#include <utility>

#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "net/base/hex_utils.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/proxy_delegate.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/base/test_data_stream.h"
#include "net/cert/ct_policy_status.h"
#include "net/http/http_request_info.h"
#include "net/log/net_log_event_type.h"
#include "net/log/net_log_source.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/spdy_http_utils.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_session_test_util.h"
#include "net/spdy/spdy_stream.h"
#include "net/spdy/spdy_stream_test_util.h"
#include "net/spdy/spdy_test_util_common.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/quiche/src/spdy/core/spdy_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/platform_test.h"

using net::test::IsError;
using net::test::IsOk;
using net::test::TestServerPushDelegate;
using testing::_;

#if SB_IS(COMPILER_MSVC)
#pragma warning(disable : 4309)
#pragma warning(disable : 4838)
#endif

namespace net {

namespace {

const char kHttpURLFromAnotherOrigin[] = "http://www.example2.org/a.dat";
const char kHttpsURLFromAnotherOrigin[] = "https://www.example2.org/b.dat";
const char kPushedUrl[] = "https://www.example.org/a.dat";

const char kBodyData[] = "Body data";
const size_t kBodyDataSize = arraysize(kBodyData);
const base::StringPiece kBodyDataStringPiece(kBodyData, kBodyDataSize);

static base::TimeDelta g_time_delta;
static base::TimeTicks g_time_now;

base::TimeTicks TheNearFuture() {
  return base::TimeTicks::Now() + g_time_delta;
}

base::TimeTicks SlowReads() {
  g_time_delta +=
      base::TimeDelta::FromMilliseconds(2 * kYieldAfterDurationMilliseconds);
  return base::TimeTicks::Now() + g_time_delta;
}

base::TimeTicks InstantaneousReads() {
  return g_time_now;
}

class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
 public:
  MOCK_METHOD3(IsCTRequiredForHost,
               CTRequirementLevel(const std::string& host,
                                  const X509Certificate* chain,
                                  const HashValueVector& hashes));
};

}  // namespace

class SpdySessionTest : public PlatformTest, public WithScopedTaskEnvironment {
 public:
  // Functions used with RunResumeAfterUnstallTest().

  void StallSessionOnly(SpdyStream* stream) { StallSessionSend(); }

  void StallStreamOnly(SpdyStream* stream) { StallStreamSend(stream); }

  void StallSessionStream(SpdyStream* stream) {
    StallSessionSend();
    StallStreamSend(stream);
  }

  void StallStreamSession(SpdyStream* stream) {
    StallStreamSend(stream);
    StallSessionSend();
  }

  void UnstallSessionOnly(SpdyStream* stream, int32_t delta_window_size) {
    UnstallSessionSend(delta_window_size);
  }

  void UnstallStreamOnly(SpdyStream* stream, int32_t delta_window_size) {
    UnstallStreamSend(stream, delta_window_size);
  }

  void UnstallSessionStream(SpdyStream* stream, int32_t delta_window_size) {
    UnstallSessionSend(delta_window_size);
    UnstallStreamSend(stream, delta_window_size);
  }

  void UnstallStreamSession(SpdyStream* stream, int32_t delta_window_size) {
    UnstallStreamSend(stream, delta_window_size);
    UnstallSessionSend(delta_window_size);
  }

 protected:
  SpdySessionTest()
      : SpdySessionTest(
            base::test::ScopedTaskEnvironment::MainThreadType::IO){};

  explicit SpdySessionTest(
      base::test::ScopedTaskEnvironment::MainThreadType type)
      : WithScopedTaskEnvironment(type),
        old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
            HttpNetworkSession::NORMAL_SOCKET_POOL)),
        old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
            HttpNetworkSession::NORMAL_SOCKET_POOL)),
        test_push_delegate_(nullptr),
        spdy_session_pool_(nullptr),
        test_url_(kDefaultUrl),
        test_server_(test_url_),
        key_(HostPortPair::FromURL(test_url_),
             ProxyServer::Direct(),
             PRIVACY_MODE_DISABLED,
             SocketTag()),
        ssl_(SYNCHRONOUS, OK) {}

  ~SpdySessionTest() override {
    // Important to restore the per-pool limit first, since the pool limit must
    // always be greater than group limit, and the tests reduce both limits.
    ClientSocketPoolManager::set_max_sockets_per_pool(
        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    ClientSocketPoolManager::set_max_sockets_per_group(
        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
  }

  void SetUp() override {
    g_time_delta = base::TimeDelta();
    g_time_now = base::TimeTicks::Now();
    session_deps_.net_log = log_.bound().net_log();
    session_deps_.enable_server_push_cancellation = true;
  }

  void CreateNetworkSession() {
    DCHECK(!http_session_);
    DCHECK(!spdy_session_pool_);
    http_session_ =
        SpdySessionDependencies::SpdyCreateSession(&session_deps_);
    auto test_push_delegate = std::make_unique<TestServerPushDelegate>();
    test_push_delegate_ = test_push_delegate.get();
    http_session_->SetServerPushDelegate(std::move(test_push_delegate));
    spdy_session_pool_ = http_session_->spdy_session_pool();
  }

  void AddSSLSocketData() {
    ssl_.ssl_info.cert =
        ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
    ASSERT_TRUE(ssl_.ssl_info.cert);
    session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
  }

  void CreateSpdySession() {
    DCHECK(!session_);
    session_ =
        ::net::CreateSpdySession(http_session_.get(), key_, log_.bound());
  }

  void CreateTrustedSpdySession() {
    DCHECK(!session_);
    session_ = ::net::CreateTrustedSpdySession(http_session_.get(), key_,
                                               log_.bound());
  }

  void StallSessionSend() {
    // Reduce the send window size to 0 to stall.
    while (session_send_window_size() > 0) {
      DecreaseSendWindowSize(
          std::min(kMaxSpdyFrameChunkSize, session_send_window_size()));
    }
  }

  void UnstallSessionSend(int32_t delta_window_size) {
    IncreaseSendWindowSize(delta_window_size);
  }

  void StallStreamSend(SpdyStream* stream) {
    // Reduce the send window size to 0 to stall.
    while (stream->send_window_size() > 0) {
      stream->DecreaseSendWindowSize(
          std::min(kMaxSpdyFrameChunkSize, stream->send_window_size()));
    }
  }

  void UnstallStreamSend(SpdyStream* stream, int32_t delta_window_size) {
    stream->IncreaseSendWindowSize(delta_window_size);
  }

  void RunResumeAfterUnstallTest(
      const base::Callback<void(SpdyStream*)>& stall_function,
      const base::Callback<void(SpdyStream*, int32_t)>& unstall_function);

  // SpdySession private methods.

  void MaybeSendPrefacePing() { session_->MaybeSendPrefacePing(); }

  void WritePingFrame(spdy::SpdyPingId unique_id, bool is_ack) {
    session_->WritePingFrame(unique_id, is_ack);
  }

  void CheckPingStatus(base::TimeTicks last_check_time) {
    session_->CheckPingStatus(last_check_time);
  }

  bool OnUnknownFrame(spdy::SpdyStreamId stream_id, uint8_t frame_type) {
    return session_->OnUnknownFrame(stream_id, frame_type);
  }

  void IncreaseSendWindowSize(int delta_window_size) {
    session_->IncreaseSendWindowSize(delta_window_size);
  }

  void DecreaseSendWindowSize(int32_t delta_window_size) {
    session_->DecreaseSendWindowSize(delta_window_size);
  }

  void IncreaseRecvWindowSize(int delta_window_size) {
    session_->IncreaseRecvWindowSize(delta_window_size);
  }

  void DecreaseRecvWindowSize(int32_t delta_window_size) {
    session_->DecreaseRecvWindowSize(delta_window_size);
  }

  // Accessors for SpdySession private members.

  void set_in_io_loop(bool in_io_loop) { session_->in_io_loop_ = in_io_loop; }

  void set_stream_hi_water_mark(spdy::SpdyStreamId stream_hi_water_mark) {
    session_->stream_hi_water_mark_ = stream_hi_water_mark;
  }

  void set_last_accepted_push_stream_id(
      spdy::SpdyStreamId last_accepted_push_stream_id) {
    session_->last_accepted_push_stream_id_ = last_accepted_push_stream_id;
  }

  size_t num_pushed_streams() { return session_->num_pushed_streams_; }

  size_t num_active_pushed_streams() {
    return session_->num_active_pushed_streams_;
  }

  size_t max_concurrent_streams() { return session_->max_concurrent_streams_; }

  void set_max_concurrent_streams(size_t max_concurrent_streams) {
    session_->max_concurrent_streams_ = max_concurrent_streams;
  }

  void set_max_concurrent_pushed_streams(size_t max_concurrent_pushed_streams) {
    session_->max_concurrent_pushed_streams_ = max_concurrent_pushed_streams;
  }

  bool ping_in_flight() { return session_->ping_in_flight_; }

  spdy::SpdyPingId next_ping_id() { return session_->next_ping_id_; }

  base::TimeTicks last_read_time() { return session_->last_read_time_; }

  bool check_ping_status_pending() {
    return session_->check_ping_status_pending_;
  }

  int32_t session_send_window_size() {
    return session_->session_send_window_size_;
  }

  int32_t session_recv_window_size() {
    return session_->session_recv_window_size_;
  }

  void set_session_recv_window_size(int32_t session_recv_window_size) {
    session_->session_recv_window_size_ = session_recv_window_size;
  }

  int32_t session_unacked_recv_window_bytes() {
    return session_->session_unacked_recv_window_bytes_;
  }

  int32_t stream_initial_send_window_size() {
    return session_->stream_initial_send_window_size_;
  }

  void set_connection_at_risk_of_loss_time(base::TimeDelta duration) {
    session_->connection_at_risk_of_loss_time_ = duration;
  }

  // Quantities derived from SpdySession private members.

  size_t pending_create_stream_queue_size(RequestPriority priority) {
    DCHECK_GE(priority, MINIMUM_PRIORITY);
    DCHECK_LE(priority, MAXIMUM_PRIORITY);
    return session_->pending_create_stream_queues_[priority].size();
  }

  size_t num_active_streams() { return session_->active_streams_.size(); }

  size_t num_created_streams() { return session_->created_streams_.size(); }

  size_t num_unclaimed_pushed_streams() {
    return spdy_session_pool_->push_promise_index()->CountStreamsForSession(
        session_.get());
  }

  bool has_unclaimed_pushed_stream_for_url(const GURL& url) {
    return spdy_session_pool_->push_promise_index()->FindStream(
               url, session_.get()) != kNoPushedStreamFound;
  }

  // Original socket limits.  Some tests set these.  Safest to always restore
  // them once each test has been run.
  int old_max_group_sockets_;
  int old_max_pool_sockets_;

  SpdyTestUtil spdy_util_;
  SpdySessionDependencies session_deps_;
  std::unique_ptr<HttpNetworkSession> http_session_;
  base::WeakPtr<SpdySession> session_;
  TestServerPushDelegate* test_push_delegate_;
  SpdySessionPool* spdy_session_pool_;
  const GURL test_url_;
  const url::SchemeHostPort test_server_;
  SpdySessionKey key_;
  SSLSocketDataProvider ssl_;
  BoundTestNetLog log_;
};

class SpdySessionTestWithMockTime : public SpdySessionTest {
 protected:
  SpdySessionTestWithMockTime()
      : SpdySessionTest(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME){};
};

// Try to create a SPDY session that will fail during
// initialization. Nothing should blow up.
TEST_F(SpdySessionTest, InitialReadError) {
  CreateNetworkSession();

  session_ = TryCreateFakeSpdySessionExpectingFailure(spdy_session_pool_, key_,
                                                      ERR_CONNECTION_CLOSED);
  EXPECT_TRUE(session_);
  // Flush the read.
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

namespace {

// A helper class that vends a callback that, when fired, destroys a
// given SpdyStreamRequest.
class StreamRequestDestroyingCallback : public TestCompletionCallbackBase {
 public:
  StreamRequestDestroyingCallback() = default;

  ~StreamRequestDestroyingCallback() override = default;

  void SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request) {
    request_ = std::move(request);
  }

  CompletionOnceCallback MakeCallback() {
    return base::BindOnce(&StreamRequestDestroyingCallback::OnComplete,
                          base::Unretained(this));
  }

 private:
  void OnComplete(int result) {
    request_.reset();
    SetResult(result);
  }

  std::unique_ptr<SpdyStreamRequest> request_;
};

}  // namespace

// Request kInitialMaxConcurrentStreams streams.  Request two more
// streams, but have the callback for one destroy the second stream
// request. Close the session. Nothing should blow up. This is a
// regression test for http://crbug.com/250841 .
TEST_F(SpdySessionTest, PendingStreamCancellingAnother) {
  MockRead reads[] = {MockRead(ASYNC, 0, 0), };

  SequencedSocketData data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Create the maximum number of concurrent streams.
  for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
    base::WeakPtr<SpdyStream> spdy_stream =
        CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, MEDIUM, NetLogWithSource());
    ASSERT_TRUE(spdy_stream);
  }

  SpdyStreamRequest request1;
  auto request2 = std::make_unique<SpdyStreamRequest>();

  StreamRequestDestroyingCallback callback1;
  ASSERT_EQ(ERR_IO_PENDING,
            request1.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, MEDIUM, SocketTag(),
                                  NetLogWithSource(), callback1.MakeCallback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  // |callback2| is never called.
  TestCompletionCallback callback2;
  ASSERT_EQ(ERR_IO_PENDING,
            request2->StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
                                   test_url_, MEDIUM, SocketTag(),
                                   NetLogWithSource(), callback2.callback(),
                                   TRAFFIC_ANNOTATION_FOR_TESTS));

  callback1.SetRequestToDestroy(std::move(request2));

  session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");

  EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_ABORTED));
}

// A session receiving a GOAWAY frame with no active streams should close.
TEST_F(SpdySessionTest, GoAwayWithNoActiveStreams) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  MockRead reads[] = {
      CreateMockRead(goaway, 0),
  };
  SequencedSocketData data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the GOAWAY frame.
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);
}

// A session receiving a GOAWAY frame immediately with no active
// streams should then close.
TEST_F(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  MockRead reads[] = {
      CreateMockRead(goaway, 0, SYNCHRONOUS), MockRead(ASYNC, 0, 1)  // EOF
  };
  SequencedSocketData data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(session_);
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(data.AllReadDataConsumed());
}

// A session receiving a GOAWAY frame with active streams should close
// when the last active stream is closed.
TEST_F(SpdySessionTest, GoAwayWithActiveStreams) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3),
      MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5)  // EOF
  };
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy::SpdyHeaderBlock headers2(headers.Clone());

  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_EQ(3u, spdy_stream2->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the GOAWAY frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_FALSE(session_->IsStreamActive(3));
  EXPECT_FALSE(spdy_stream2);
  EXPECT_TRUE(session_->IsStreamActive(1));

  EXPECT_TRUE(session_->IsGoingAway());

  // Should close the session.
  spdy_stream1->Close();
  EXPECT_FALSE(spdy_stream1);

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Regression test for https://crbug.com/547130.
TEST_F(SpdySessionTest, GoAwayWithActiveAndCreatedStream) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(0));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
  };

  // No |req2|, because the second stream will never get activated.
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);
  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  EXPECT_EQ(0u, spdy_stream1->stream_id());

  // Active stream 1.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_TRUE(session_->IsStreamActive(1));

  // Create stream corresponding to the next request.
  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());

  EXPECT_EQ(0u, spdy_stream2->stream_id());

  // Read and process the GOAWAY frame before the second stream could be
  // activated.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(session_);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Have a session receive two GOAWAY frames, with the last one causing
// the last active stream to be closed. The session should then be
// closed after the second GOAWAY frame.
TEST_F(SpdySessionTest, GoAwayTwice) {
  spdy::SpdySerializedFrame goaway1(spdy_util_.ConstructSpdyGoAway(1));
  spdy::SpdySerializedFrame goaway2(spdy_util_.ConstructSpdyGoAway(0));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway1, 3),
      MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(goaway2, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7)  // EOF
  };
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy::SpdyHeaderBlock headers2(headers.Clone());

  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_EQ(3u, spdy_stream2->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the first GOAWAY frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_FALSE(session_->IsStreamActive(3));
  EXPECT_FALSE(spdy_stream2);
  EXPECT_TRUE(session_->IsStreamActive(1));
  EXPECT_TRUE(session_->IsGoingAway());

  // Read and process the second GOAWAY frame, which should close the
  // session.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Have a session with active streams receive a GOAWAY frame and then
// close it. It should handle the close properly (i.e., not try to
// make itself unavailable in its pool twice).
TEST_F(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(goaway, 3),
      MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5)  // EOF
  };
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy::SpdyHeaderBlock headers2(headers.Clone());

  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_EQ(3u, spdy_stream2->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the GOAWAY frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_FALSE(session_->IsStreamActive(3));
  EXPECT_FALSE(spdy_stream2);
  EXPECT_TRUE(session_->IsStreamActive(1));
  EXPECT_TRUE(session_->IsGoingAway());

  session_->CloseSessionOnError(ERR_ABORTED, "Aborting session");
  EXPECT_FALSE(spdy_stream1);

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Process a joint read buffer which causes the session to begin draining, and
// then processes a GOAWAY. The session should gracefully drain. Regression test
// for crbug.com/379469
TEST_F(SpdySessionTest, GoAwayWhileDraining) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  size_t joint_size = goaway.size() * 2 + body.size();

  // Compose interleaved |goaway| and |body| frames into a single read.
  auto buffer = std::make_unique<char[]>(joint_size);
  {
    size_t out = 0;
    SbMemoryCopy(&buffer[out], goaway.data(), goaway.size());
    out += goaway.size();
    SbMemoryCopy(&buffer[out], body.data(), body.size());
    out += body.size();
    SbMemoryCopy(&buffer[out], goaway.data(), goaway.size());
    out += goaway.size();
    ASSERT_EQ(out, joint_size);
  }
  spdy::SpdySerializedFrame joint_frames(buffer.get(), joint_size, false);

  MockRead reads[] = {
      CreateMockRead(resp, 1), CreateMockRead(joint_frames, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  // Stream and session closed gracefully.
  EXPECT_TRUE(delegate.StreamIsClosed());
  EXPECT_THAT(delegate.WaitForClose(), IsOk());
  EXPECT_EQ(kUploadData, delegate.TakeReceivedData());
  EXPECT_FALSE(session_);
}

// Try to create a stream after receiving a GOAWAY frame. It should
// fail.
TEST_F(SpdySessionTest, CreateStreamAfterGoAway) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4)  // EOF
  };
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the GOAWAY frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_TRUE(session_->IsStreamActive(1));

  SpdyStreamRequest stream_request;
  int rv = stream_request.StartRequest(
      SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, SocketTag(),
      NetLogWithSource(), CompletionOnceCallback(),
      TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(rv, IsError(ERR_FAILED));

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Receiving a HEADERS frame after a GOAWAY frame should result in
// the stream being refused.
TEST_F(SpdySessionTest, HeadersAfterGoAway) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(1));
  spdy::SpdySerializedFrame push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kDefaultUrl));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(goaway, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 3), CreateMockRead(push, 4),
      MockRead(ASYNC, 0, 6)  // EOF
  };
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(rst, 5)};
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Read and process the GOAWAY frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_TRUE(session_->IsStreamActive(1));

  // Read and process the HEADERS frame, the subsequent RST_STREAM,
  // and EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kGoingAway), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

// A session observing a network change with active streams should close
// when the last active stream is closed.
TEST_F(SpdySessionTest, NetworkChangeWithActiveStreams) {
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2)  // EOF
  };
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));

  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream->stream_id());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  spdy_session_pool_->OnIPAddressChanged();

  // The SpdySessionPool behavior differs based on how the OSs reacts to
  // network changes; see comment in SpdySessionPool::OnIPAddressChanged().
#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_IOS)
  // For OSs where the TCP connections will close upon relevant network
  // changes, SpdySessionPool doesn't need to force them to close, so in these
  // cases verify the session has become unavailable but remains open and the
  // pre-existing stream is still active.
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_TRUE(session_->IsGoingAway());

  EXPECT_TRUE(session_->IsStreamActive(1));

  // Should close the session.
  spdy_stream->Close();
#endif
  EXPECT_FALSE(spdy_stream);

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTestWithMockTime, ClientPing) {
  session_deps_.enable_ping = true;

  spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(1, true));
  MockRead reads[] = {
      CreateMockRead(read_ping, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };
  spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
  MockWrite writes[] = {
      CreateMockWrite(write_ping, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
  spdy_stream1->SetDelegate(&delegate);

  base::TimeTicks before_ping_time = base::TimeTicks::Now();

  // Negative value means a preface ping will always be sent.
  set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(-1));

  // Send a PING frame.  This posts CheckPingStatus() with delay.
  MaybeSendPrefacePing();

  EXPECT_TRUE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_TRUE(check_ping_status_pending());

  // MaybeSendPrefacePing() should not send another PING frame if there is
  // already one in flight.
  MaybeSendPrefacePing();

  EXPECT_TRUE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_TRUE(check_ping_status_pending());

  // Run posted CheckPingStatus() task.
  FastForwardUntilNoTasksRemain();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_FALSE(check_ping_status_pending());
  EXPECT_GE(last_read_time(), before_ping_time);

  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  EXPECT_FALSE(MainThreadHasPendingTask());
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);
  EXPECT_FALSE(spdy_stream1);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

TEST_F(SpdySessionTest, ServerPing) {
  spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(2, false));
  MockRead reads[] = {
      CreateMockRead(read_ping), MockRead(SYNCHRONOUS, 0, 0)  // EOF
  };
  spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(2, true));
  MockWrite writes[] = {
      CreateMockWrite(write_ping),
  };
  StaticSocketDataProvider data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
  spdy_stream1->SetDelegate(&delegate);

  // Flush the read completion task.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_FALSE(session_);
  EXPECT_FALSE(spdy_stream1);
}

// Cause a ping to be sent out while producing a write. The write loop
// should handle this properly, i.e. another DoWriteLoop task should
// not be posted. This is a regression test for
// http://crbug.com/261043 .
TEST_F(SpdySessionTest, PingAndWriteLoop) {
  session_deps_.enable_ping = true;
  session_deps_.time_func = TheNearFuture;

  spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(write_ping, 1),
  };

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Shift time so that a ping will be sent out.
  g_time_delta = base::TimeDelta::FromSeconds(11);

  base::RunLoop().RunUntilIdle();
  session_->CloseSessionOnError(ERR_ABORTED, "Aborting");

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, StreamIdSpaceExhausted) {
  const spdy::SpdyStreamId kLastStreamId = 0x7fffffff;

  // Test setup: |stream_hi_water_mark_| and |max_concurrent_streams_| are
  // fixed to allow for two stream ID assignments, and three concurrent
  // streams. Four streams are started, and two are activated. Verify the
  // session goes away, and that the created (but not activated) and
  // stalled streams are aborted. Also verify the activated streams complete,
  // at which point the session closes.

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM));

  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, kLastStreamId - 2));
  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, kLastStreamId));

  spdy::SpdySerializedFrame body1(
      spdy_util_.ConstructSpdyDataFrame(kLastStreamId - 2, true));
  spdy::SpdySerializedFrame body2(
      spdy_util_.ConstructSpdyDataFrame(kLastStreamId, true));

  MockRead reads[] = {
      CreateMockRead(resp1, 2),           CreateMockRead(resp2, 3),
      MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(body1, 5),
      CreateMockRead(body2, 6),           MockRead(ASYNC, 0, 7)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Fix stream_hi_water_mark_ to allow for two stream activations.
  set_stream_hi_water_mark(kLastStreamId - 2);
  // Fix max_concurrent_streams to allow for three stream creations.
  set_max_concurrent_streams(3);

  // Create three streams synchronously, and begin a fourth (which is stalled).
  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(stream1);
  stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate2(stream2);
  stream2->SetDelegate(&delegate2);

  base::WeakPtr<SpdyStream> stream3 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate3(stream3);
  stream3->SetDelegate(&delegate3);

  SpdyStreamRequest request4;
  TestCompletionCallback callback4;
  EXPECT_EQ(ERR_IO_PENDING,
            request4.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                  test_url_, MEDIUM, SocketTag(),
                                  NetLogWithSource(), callback4.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  // Streams 1-3 were created. 4th is stalled. No streams are active yet.
  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(3u, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));

  // Activate stream 1. One ID remains available.
  stream1->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
                              NO_MORE_DATA_TO_SEND);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kLastStreamId - 2u, stream1->stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(2u, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));

  // Activate stream 2. ID space is exhausted.
  stream2->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
                              NO_MORE_DATA_TO_SEND);
  base::RunLoop().RunUntilIdle();

  // Active streams remain active.
  EXPECT_EQ(kLastStreamId, stream2->stream_id());
  EXPECT_EQ(2u, num_active_streams());

  // Session is going away. Created and stalled streams were aborted.
  EXPECT_TRUE(session_->IsGoingAway());
  EXPECT_THAT(delegate3.WaitForClose(), IsError(ERR_ABORTED));
  EXPECT_THAT(callback4.WaitForResult(), IsError(ERR_ABORTED));
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));

  // Read responses on remaining active streams.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_THAT(delegate1.WaitForClose(), IsOk());
  EXPECT_EQ(kUploadData, delegate1.TakeReceivedData());
  EXPECT_THAT(delegate2.WaitForClose(), IsOk());
  EXPECT_EQ(kUploadData, delegate2.TakeReceivedData());

  // Session was destroyed.
  EXPECT_FALSE(session_);
}

// Regression test for https://crbug.com/481009.
TEST_F(SpdySessionTest, MaxConcurrentStreamsZero) {

  // Receive SETTINGS frame that sets max_concurrent_streams to zero.
  spdy::SettingsMap settings_zero;
  settings_zero[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 0;
  spdy::SpdySerializedFrame settings_frame_zero(
      spdy_util_.ConstructSpdySettings(settings_zero));

  // Acknowledge it.
  spdy::SpdySerializedFrame settings_ack0(
      spdy_util_.ConstructSpdySettingsAck());

  // Receive SETTINGS frame that sets max_concurrent_streams to one.
  spdy::SettingsMap settings_one;
  settings_one[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 1;
  spdy::SpdySerializedFrame settings_frame_one(
      spdy_util_.ConstructSpdySettings(settings_one));

  // Acknowledge it.
  spdy::SpdySerializedFrame settings_ack1(
      spdy_util_.ConstructSpdySettingsAck());

  // Request and response.
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));

  MockRead reads[] = {CreateMockRead(settings_frame_zero, 0),
                      MockRead(ASYNC, ERR_IO_PENDING, 2),
                      CreateMockRead(settings_frame_one, 3),
                      CreateMockRead(resp, 6),
                      CreateMockRead(body, 7),
                      MockRead(ASYNC, 0, 8)};

  MockWrite writes[] = {CreateMockWrite(settings_ack0, 1),
                        CreateMockWrite(settings_ack1, 4),
                        CreateMockWrite(req, 5)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  // Create session.
  CreateNetworkSession();
  CreateSpdySession();

  // Receive SETTINGS frame that sets max_concurrent_streams to zero.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, max_concurrent_streams());

  // Start request.
  SpdyStreamRequest request;
  TestCompletionCallback callback;
  int rv = request.StartRequest(
      SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, SocketTag(),
      NetLogWithSource(), callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  // Stream is stalled.
  EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));
  EXPECT_EQ(0u, num_created_streams());

  // Receive SETTINGS frame that sets max_concurrent_streams to one.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, max_concurrent_streams());

  // Stream is created.
  EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
  EXPECT_EQ(1u, num_created_streams());

  EXPECT_THAT(callback.WaitForResult(), IsOk());

  // Send request.
  base::WeakPtr<SpdyStream> stream = request.ReleaseStream();
  test::StreamDelegateDoNothing delegate(stream);
  stream->SetDelegate(&delegate);
  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  EXPECT_THAT(delegate.WaitForClose(), IsOk());
  EXPECT_EQ("hello!", delegate.TakeReceivedData());

  // Finish async network reads/writes.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());

  // Session is destroyed.
  EXPECT_FALSE(session_);
}

// Verifies that an unstalled pending stream creation racing with a new stream
// creation doesn't violate the maximum stream concurrency. Regression test for
// crbug.com/373858.
TEST_F(SpdySessionTest, UnstallRacesWithStreamCreation) {
  MockRead reads[] = {
      MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Fix max_concurrent_streams to allow for one open stream.
  set_max_concurrent_streams(1);

  // Create two streams: one synchronously, and one which stalls.
  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());

  SpdyStreamRequest request2;
  TestCompletionCallback callback2;
  EXPECT_EQ(ERR_IO_PENDING,
            request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                  test_url_, MEDIUM, SocketTag(),
                                  NetLogWithSource(), callback2.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));

  // Cancel the first stream. A callback to unstall the second stream was
  // posted. Don't run it yet.
  stream1->Cancel(ERR_ABORTED);

  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));

  // Create a third stream prior to the second stream's callback.
  base::WeakPtr<SpdyStream> stream3 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());

  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));

  // Now run the message loop. The unstalled stream will re-stall itself.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(MEDIUM));

  // Cancel the third stream and run the message loop. Verify that the second
  // stream creation now completes.
  stream3->Cancel(ERR_ABORTED);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(MEDIUM));
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
}

TEST_F(SpdySessionTest, CancelPushAfterSessionGoesAway) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 2)};

  spdy::SpdySerializedFrame push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdySerializedFrame push_body(
      spdy_util_.ConstructSpdyDataFrame(2, false));
  MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 3),
                      MockRead(ASYNC, ERR_IO_PENDING, 4),
                      MockRead(ASYNC, 0, 5)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  // Verify that there is one unclaimed push stream.
  const GURL pushed_url(kPushedUrl);
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());
  EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));

  // Unclaimed push body consumes bytes from the session window.
  EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
            session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Read and process EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  // Cancel the push after session goes away. The test must not crash.
  EXPECT_FALSE(session_);
  EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));

  histogram_tester.ExpectBucketCount("Net.SpdyStreamsPushedPerSession", 1, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
                                     6, 1);
}

TEST_F(SpdySessionTestWithMockTime, CancelPushAfterExpired) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
      CreateMockWrite(rst, 5),
  };

  spdy::SpdySerializedFrame push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdySerializedFrame push_body(
      spdy_util_.ConstructSpdyDataFrame(2, false));
  MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
                      MockRead(ASYNC, ERR_IO_PENDING, 4),
                      MockRead(ASYNC, 0, 6)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  RunUntilIdle();

  // Verify that there is one unclaimed push stream.
  const GURL pushed_url(kPushedUrl);
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());
  EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));

  // Unclaimed push body consumes bytes from the session window.
  EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
            session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Fast forward to CancelPushedStreamIfUnclaimed() that was posted with a
  // delay.
  FastForwardUntilNoTasksRemain();
  RunUntilIdle();

  // Verify that pushed stream is cancelled.
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  // Verify that the session window reclaimed the evicted stream body.
  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());

  // Try to cancel the expired push after its expiration: must not crash.
  EXPECT_TRUE(session_);
  EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  // Read and process EOF.
  data.Resume();
  RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount("Net.SpdyStreamsPushedPerSession", 1, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
                                     6, 1);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kTimeout), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

TEST_F(SpdySessionTestWithMockTime, ClaimPushedStreamBeforeExpires) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3)};

  spdy::SpdySerializedFrame push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdySerializedFrame push_body(
      spdy_util_.ConstructSpdyDataFrame(2, false));
  MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
                      MockRead(ASYNC, ERR_IO_PENDING, 4),
                      MockRead(ASYNC, 0, 5)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  RunUntilIdle();

  // Verify that there is one unclaimed push stream.
  const GURL pushed_url(kPushedUrl);
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());
  EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));

  // Unclaimed push body consumes bytes from the session window.
  EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
            session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Claim pushed stream from Http2PushPromiseIndex.
  HttpRequestInfo push_request;
  push_request.url = pushed_url;
  push_request.method = "GET";
  base::WeakPtr<SpdySession> session_with_pushed_stream;
  spdy::SpdyStreamId pushed_stream_id;
  spdy_session_pool_->push_promise_index()->ClaimPushedStream(
      key_, pushed_url, push_request, &session_with_pushed_stream,
      &pushed_stream_id);
  EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
  EXPECT_EQ(2u, pushed_stream_id);

  // Verify that pushed stream is claimed.
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  SpdyStream* spdy_stream2;
  int rv = session_->GetPushedStream(pushed_url, pushed_stream_id, MEDIUM,
                                     &spdy_stream2);
  ASSERT_THAT(rv, IsOk());
  ASSERT_TRUE(spdy_stream2);

  test::StreamDelegateDoNothing delegate2(spdy_stream2->GetWeakPtr());
  spdy_stream2->SetDelegate(&delegate2);

  // Fast forward to CancelPushedStreamIfUnclaimed() that was posted with a
  // delay.  CancelPushedStreamIfUnclaimed() must be a no-op.
  FastForwardUntilNoTasksRemain();
  RunUntilIdle();
  EXPECT_TRUE(session_);

  // Read and process EOF.
  data.Resume();
  RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount("Net.SpdyStreamsPushedPerSession", 1, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
                                     0, 1);
}

TEST_F(SpdySessionTest, CancelPushBeforeClaimed) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
                        CreateMockWrite(rst, 5)};

  spdy::SpdySerializedFrame push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdySerializedFrame push_body(
      spdy_util_.ConstructSpdyDataFrame(2, false));
  MockRead reads[] = {CreateMockRead(push, 1), CreateMockRead(push_body, 2),
                      MockRead(ASYNC, ERR_IO_PENDING, 4),
                      MockRead(ASYNC, 0, 6)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  // Verify that there is one unclaimed push stream.
  const GURL pushed_url(kPushedUrl);
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());
  EXPECT_TRUE(has_unclaimed_pushed_stream_for_url(pushed_url));

  // Unclaimed push body consumes bytes from the session window.
  EXPECT_EQ(kDefaultInitialWindowSize - kUploadDataSize,
            session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Cancel the push before it is claimed.  This normally happens because
  // resource is found in cache.
  EXPECT_TRUE(test_push_delegate_->CancelPush(pushed_url));
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());
  EXPECT_FALSE(has_unclaimed_pushed_stream_for_url(pushed_url));

  // Verify that the session window reclaimed the evicted stream body.
  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());

  EXPECT_TRUE(session_);

  // Read and process EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount("Net.SpdyStreamsPushedPerSession", 1, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedBytes", 6, 1);
  histogram_tester.ExpectBucketCount("Net.SpdySession.PushedAndUnclaimedBytes",
                                     6, 1);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kAlreadyInCache), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

TEST_F(SpdySessionTestWithMockTime, FailedPing) {
  session_deps_.enable_ping = true;
  session_deps_.time_func = TheNearFuture;

  MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};  // Stall forever.
  spdy::SpdySerializedFrame write_ping(spdy_util_.ConstructSpdyPing(1, false));
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Failed ping."));
  MockWrite writes[] = {CreateMockWrite(write_ping), CreateMockWrite(goaway)};

  StaticSocketDataProvider data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
  spdy_stream1->SetDelegate(&delegate);

  // Negative value means a preface ping will always be sent.
  set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(-1));

  // Send a PING frame.  This posts CheckPingStatus() with delay.
  MaybeSendPrefacePing();
  EXPECT_TRUE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_TRUE(check_ping_status_pending());

  // Assert session is not closed.
  EXPECT_TRUE(session_->IsAvailable());
  EXPECT_LT(0u, num_active_streams() + num_created_streams());
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Run CheckPingStatus() and make it believe hung_interval has passed.
  g_time_delta = base::TimeDelta::FromSeconds(15);
  FastForwardUntilNoTasksRemain();
  base::RunLoop().RunUntilIdle();

  // Since no response to PING has been received,
  // CheckPingStatus() closes the connection.
  EXPECT_FALSE(MainThreadHasPendingTask());
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);
  EXPECT_FALSE(spdy_stream1);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Regression test for https://crbug.com/784975.
TEST_F(SpdySessionTestWithMockTime, NoPingSentWhenCheckPingPending) {
  session_deps_.enable_ping = true;
  session_deps_.time_func = TheNearFuture;

  spdy::SpdySerializedFrame read_ping(spdy_util_.ConstructSpdyPing(1, true));
  MockRead reads[] = {CreateMockRead(read_ping, 1),
                      MockRead(ASYNC, ERR_IO_PENDING, 2),
                      MockRead(ASYNC, 0, 3)};

  spdy::SpdySerializedFrame write_ping0(spdy_util_.ConstructSpdyPing(1, false));
  MockWrite writes[] = {CreateMockWrite(write_ping0, 0)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Negative value means a preface ping will always be sent.
  set_connection_at_risk_of_loss_time(base::TimeDelta::FromSeconds(-1));

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  test::StreamDelegateSendImmediate delegate(spdy_stream1, nullptr);
  spdy_stream1->SetDelegate(&delegate);

  EXPECT_FALSE(ping_in_flight());
  EXPECT_EQ(1u, next_ping_id());
  EXPECT_FALSE(check_ping_status_pending());

  // Send preface ping and post CheckPingStatus() task with delay.
  MaybeSendPrefacePing();

  EXPECT_TRUE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_TRUE(check_ping_status_pending());

  // Read PING ACK.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(ping_in_flight());
  EXPECT_TRUE(check_ping_status_pending());

  // Fast forward mock time so that normally another ping would be sent out.
  // However, since CheckPingStatus() is still pending, no new ping is sent.
  g_time_delta = base::TimeDelta::FromSeconds(15);
  MaybeSendPrefacePing();

  EXPECT_FALSE(ping_in_flight());
  EXPECT_EQ(2u, next_ping_id());
  EXPECT_TRUE(check_ping_status_pending());

  // Run CheckPingStatus().
  FastForwardUntilNoTasksRemain();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(check_ping_status_pending());

  // Read EOF.
  data.Resume();
  EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  // Finish going away.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Request kInitialMaxConcurrentStreams + 1 streams.  Receive a
// settings frame increasing the max concurrent streams by 1.  Make
// sure nothing blows up. This is a regression test for
// http://crbug.com/57331 .
TEST_F(SpdySessionTest, OnSettings) {
  const spdy::SpdySettingsId kSpdySettingsId =
      spdy::SETTINGS_MAX_CONCURRENT_STREAMS;

  spdy::SettingsMap new_settings;
  const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
  new_settings[kSpdySettingsId] = max_concurrent_streams;
  spdy::SpdySerializedFrame settings_frame(
      spdy_util_.ConstructSpdySettings(new_settings));
  MockRead reads[] = {
      CreateMockRead(settings_frame, 0), MockRead(ASYNC, ERR_IO_PENDING, 2),
      MockRead(ASYNC, 0, 3),
  };

  spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  MockWrite writes[] = {CreateMockWrite(settings_ack, 1)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Create the maximum number of concurrent streams.
  for (size_t i = 0; i < kInitialMaxConcurrentStreams; ++i) {
    base::WeakPtr<SpdyStream> spdy_stream =
        CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, MEDIUM, NetLogWithSource());
    ASSERT_TRUE(spdy_stream);
  }

  StreamReleaserCallback stream_releaser;
  SpdyStreamRequest request;
  ASSERT_EQ(ERR_IO_PENDING,
            request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                 MEDIUM, SocketTag(), NetLogWithSource(),
                                 stream_releaser.MakeCallback(&request),
                                 TRAFFIC_ANNOTATION_FOR_TESTS));

  base::RunLoop().RunUntilIdle();

  EXPECT_THAT(stream_releaser.WaitForResult(), IsOk());

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Create one more stream than maximum number of concurrent streams,
// so that one of them is pending.  Cancel one stream, which should trigger the
// creation of the pending stream.  Then cancel that one immediately as well,
// and make sure this does not lead to a crash.
// This is a regression test for https://crbug.com/63532.
TEST_F(SpdySessionTest, CancelPendingCreateStream) {
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Leave room for only one more stream to be created.
  for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
    base::WeakPtr<SpdyStream> spdy_stream =
        CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, MEDIUM, NetLogWithSource());
    ASSERT_TRUE(spdy_stream);
  }

  // Create 2 more streams.  First will succeed.  Second will be pending.
  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);

  // Use unique_ptr to let us invalidate the memory when we want to, to trigger
  // an error in memory corruption detectors if the callback is invoked when
  // it's not supposed to be.
  auto callback = std::make_unique<TestCompletionCallback>();

  SpdyStreamRequest request;
  ASSERT_THAT(
      request.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                           MEDIUM, SocketTag(), NetLogWithSource(),
                           callback->callback(), TRAFFIC_ANNOTATION_FOR_TESTS),
      IsError(ERR_IO_PENDING));

  // Release the first one, this will allow the second to be created.
  spdy_stream1->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream1);

  request.CancelRequest();
  callback.reset();

  // Should not crash when running the pending callback.
  base::RunLoop().RunUntilIdle();
}

TEST_F(SpdySessionTest, Initialize) {
  MockRead reads[] = {
    MockRead(ASYNC, 0, 0)  // EOF
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Flush the read completion task.
  base::RunLoop().RunUntilIdle();

  TestNetLogEntry::List entries;
  log_.GetEntries(&entries);
  EXPECT_LT(0u, entries.size());

  // Check that we logged HTTP2_SESSION_INITIALIZED correctly.
  int pos = ExpectLogContainsSomewhere(
      entries, 0, NetLogEventType::HTTP2_SESSION_INITIALIZED,
      NetLogEventPhase::NONE);
  EXPECT_LT(0, pos);

  TestNetLogEntry entry = entries[pos];
  NetLogSource socket_source;
  EXPECT_TRUE(
      NetLogSource::FromEventParameters(entry.params.get(), &socket_source));
  EXPECT_TRUE(socket_source.IsValid());
  EXPECT_NE(log_.bound().source().id, socket_source.id);
}

TEST_F(SpdySessionTest, NetLogOnSessionGoaway) {
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      42, spdy::ERROR_CODE_ENHANCE_YOUR_CALM, "foo"));
  MockRead reads[] = {
      CreateMockRead(goaway), MockRead(SYNCHRONOUS, 0, 0)  // EOF
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Flush the read completion task.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);

  // Check that the NetLog was filled reasonably.
  TestNetLogEntry::List entries;
  log_.GetEntries(&entries);
  EXPECT_LT(0u, entries.size());

  int pos = ExpectLogContainsSomewhere(
      entries, 0, NetLogEventType::HTTP2_SESSION_RECV_GOAWAY,
      NetLogEventPhase::NONE);
  TestNetLogEntry entry = entries[pos];
  int last_accepted_stream_id;
  ASSERT_TRUE(entry.GetIntegerValue("last_accepted_stream_id",
                                    &last_accepted_stream_id));
  EXPECT_EQ(42, last_accepted_stream_id);
  int active_streams;
  ASSERT_TRUE(entry.GetIntegerValue("active_streams", &active_streams));
  EXPECT_EQ(0, active_streams);
  int unclaimed_streams;
  ASSERT_TRUE(entry.GetIntegerValue("unclaimed_streams", &unclaimed_streams));
  EXPECT_EQ(0, unclaimed_streams);
  std::string error_code;
  ASSERT_TRUE(entry.GetStringValue("error_code", &error_code));
  EXPECT_EQ("11 (ENHANCE_YOUR_CALM)", error_code);
  std::string debug_data;
  ASSERT_TRUE(entry.GetStringValue("debug_data", &debug_data));
  EXPECT_EQ("foo", debug_data);

  // Check that we logged SPDY_SESSION_CLOSE correctly.
  pos = ExpectLogContainsSomewhere(
      entries, 0, NetLogEventType::HTTP2_SESSION_CLOSE, NetLogEventPhase::NONE);
  entry = entries[pos];
  int net_error_code = 0;
  ASSERT_TRUE(entry.GetNetErrorCode(&net_error_code));
  EXPECT_THAT(net_error_code, IsOk());
}

TEST_F(SpdySessionTest, NetLogOnSessionEOF) {
  MockRead reads[] = {
      MockRead(SYNCHRONOUS, 0, 0)  // EOF
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Flush the read completion task.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));
  EXPECT_FALSE(session_);

  // Check that the NetLog was filled reasonably.
  TestNetLogEntry::List entries;
  log_.GetEntries(&entries);
  EXPECT_LT(0u, entries.size());

  // Check that we logged SPDY_SESSION_CLOSE correctly.
  int pos = ExpectLogContainsSomewhere(
      entries, 0, NetLogEventType::HTTP2_SESSION_CLOSE, NetLogEventPhase::NONE);

  if (pos < static_cast<int>(entries.size())) {
    TestNetLogEntry entry = entries[pos];
    int error_code = 0;
    ASSERT_TRUE(entry.GetNetErrorCode(&error_code));
    EXPECT_THAT(error_code, IsError(ERR_CONNECTION_CLOSED));
  } else {
    ADD_FAILURE();
  }
}

TEST_F(SpdySessionTest, HeadersCompressionHistograms) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2)  // EOF
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Write request headers & capture resulting histogram update.
  base::HistogramTester histogram_tester;

  base::RunLoop().RunUntilIdle();
  // Regression test of compression performance under the request fixture.
  histogram_tester.ExpectBucketCount("Net.SpdyHeadersCompressionPercentage", 76,
                                     1);

  // Read and process EOF.
  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Queue up a low-priority HEADERS followed by a high-priority
// one. The high priority one should still send first and receive
// first.
TEST_F(SpdySessionTest, OutOfOrderHeaders) {
  // Construct the request.
  spdy::SpdySerializedFrame req_highest(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  spdy::SpdySerializedFrame req_lowest(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  MockWrite writes[] = {
      CreateMockWrite(req_highest, 0), CreateMockWrite(req_lowest, 1),
  };

  spdy::SpdySerializedFrame resp_highest(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body_highest(
      spdy_util_.ConstructSpdyDataFrame(1, true));
  spdy::SpdySerializedFrame resp_lowest(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  spdy::SpdySerializedFrame body_lowest(
      spdy_util_.ConstructSpdyDataFrame(3, true));
  MockRead reads[] = {
      CreateMockRead(resp_highest, 2), CreateMockRead(body_highest, 3),
      CreateMockRead(resp_lowest, 4), CreateMockRead(body_lowest, 5),
      MockRead(ASYNC, 0, 6)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream_lowest =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream_lowest);
  EXPECT_EQ(0u, spdy_stream_lowest->stream_id());
  test::StreamDelegateDoNothing delegate_lowest(spdy_stream_lowest);
  spdy_stream_lowest->SetDelegate(&delegate_lowest);

  base::WeakPtr<SpdyStream> spdy_stream_highest =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, HIGHEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream_highest);
  EXPECT_EQ(0u, spdy_stream_highest->stream_id());
  test::StreamDelegateDoNothing delegate_highest(spdy_stream_highest);
  spdy_stream_highest->SetDelegate(&delegate_highest);

  // Queue the lower priority one first.

  spdy::SpdyHeaderBlock headers_lowest(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream_lowest->SendRequestHeaders(std::move(headers_lowest),
                                         NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers_highest(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream_highest->SendRequestHeaders(std::move(headers_highest),
                                          NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(spdy_stream_lowest);
  EXPECT_FALSE(spdy_stream_highest);
  EXPECT_EQ(3u, delegate_lowest.stream_id());
  EXPECT_EQ(1u, delegate_highest.stream_id());
}

TEST_F(SpdySessionTest, CancelStream) {
  // Request 1, at HIGHEST priority, will be cancelled before it writes data.
  // Request 2, at LOWEST priority, will be a full request and will be id 1.
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  MockWrite writes[] = {
      CreateMockWrite(req2, 0),
  };

  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
  MockRead reads[] = {
      CreateMockRead(resp2, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(body2, 3), MockRead(ASYNC, 0, 4)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, HIGHEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(0u, spdy_stream2->stream_id());
  test::StreamDelegateDoNothing delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  EXPECT_EQ(0u, spdy_stream1->stream_id());

  spdy_stream1->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream1);

  EXPECT_EQ(0u, delegate1.stream_id());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0u, delegate1.stream_id());
  EXPECT_EQ(1u, delegate2.stream_id());

  spdy_stream2->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream2);
}

// Create two streams that are set to re-close themselves on close,
// and then close the session. Nothing should blow up. Also a
// regression test for http://crbug.com/139518 .
TEST_F(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) {
  // No actual data will be sent.
  MockWrite writes[] = {
    MockWrite(ASYNC, 0, 1)  // EOF
  };

  MockRead reads[] = {
    MockRead(ASYNC, 0, 0)  // EOF
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                HIGHEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  test::ClosingDelegate delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  test::ClosingDelegate delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  // Ensure that the streams have not yet been activated and assigned an id.
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  // Ensure we don't crash while closing the session.
  session_->CloseSessionOnError(ERR_ABORTED, std::string());

  EXPECT_FALSE(spdy_stream1);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_TRUE(delegate1.StreamIsClosed());
  EXPECT_TRUE(delegate2.StreamIsClosed());

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Create two streams that are set to close each other on close, and
// then close the session. Nothing should blow up.
TEST_F(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) {
  SequencedSocketData data;
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                HIGHEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  // Make |spdy_stream1| close |spdy_stream2|.
  test::ClosingDelegate delegate1(spdy_stream2);
  spdy_stream1->SetDelegate(&delegate1);

  // Make |spdy_stream2| close |spdy_stream1|.
  test::ClosingDelegate delegate2(spdy_stream1);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  // Ensure that the streams have not yet been activated and assigned an id.
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  // Ensure we don't crash while closing the session.
  session_->CloseSessionOnError(ERR_ABORTED, std::string());

  EXPECT_FALSE(spdy_stream1);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_TRUE(delegate1.StreamIsClosed());
  EXPECT_TRUE(delegate2.StreamIsClosed());

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Create two streams that are set to re-close themselves on close,
// activate them, and then close the session. Nothing should blow up.
TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  test::ClosingDelegate delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  test::ClosingDelegate delegate2(spdy_stream2);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  // Ensure that the streams have not yet been activated and assigned an id.
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_EQ(3u, spdy_stream2->stream_id());

  // Ensure we don't crash while closing the session.
  session_->CloseSessionOnError(ERR_ABORTED, std::string());

  EXPECT_FALSE(spdy_stream1);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_TRUE(delegate1.StreamIsClosed());
  EXPECT_TRUE(delegate2.StreamIsClosed());

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Create two streams that are set to close each other on close,
// activate them, and then close the session. Nothing should blow up.
TEST_F(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  // Make |spdy_stream1| close |spdy_stream2|.
  test::ClosingDelegate delegate1(spdy_stream2);
  spdy_stream1->SetDelegate(&delegate1);

  // Make |spdy_stream2| close |spdy_stream1|.
  test::ClosingDelegate delegate2(spdy_stream1);
  spdy_stream2->SetDelegate(&delegate2);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  // Ensure that the streams have not yet been activated and assigned an id.
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  EXPECT_EQ(0u, spdy_stream2->stream_id());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream1->stream_id());
  EXPECT_EQ(3u, spdy_stream2->stream_id());

  // Ensure we don't crash while closing the session.
  session_->CloseSessionOnError(ERR_ABORTED, std::string());

  EXPECT_FALSE(spdy_stream1);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_TRUE(delegate1.StreamIsClosed());
  EXPECT_TRUE(delegate2.StreamIsClosed());

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Delegate that closes a given session when the stream is closed.
class SessionClosingDelegate : public test::StreamDelegateDoNothing {
 public:
  SessionClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
                         const base::WeakPtr<SpdySession>& session_to_close)
      : StreamDelegateDoNothing(stream),
        session_to_close_(session_to_close) {}

  ~SessionClosingDelegate() override = default;

  void OnClose(int status) override {
    session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error");
  }

 private:
  base::WeakPtr<SpdySession> session_to_close_;
};

// Close an activated stream that closes its session. Nothing should
// blow up. This is a regression test for https://crbug.com/263691.
TEST_F(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      0, spdy::ERROR_CODE_PROTOCOL_ERROR, "Error"));
  // The GOAWAY has higher-priority than the RST_STREAM, and is written first
  // despite being queued second.
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(goaway, 1),
      CreateMockWrite(rst, 3),
  };

  MockRead reads[] = {
      MockRead(ASYNC, 0, 2)  // EOF
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  EXPECT_EQ(0u, spdy_stream->stream_id());

  SessionClosingDelegate delegate(spdy_stream, session_);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  EXPECT_EQ(0u, spdy_stream->stream_id());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream->stream_id());

  // Ensure we don't crash while closing the stream (which closes the
  // session).
  spdy_stream->Cancel(ERR_ABORTED);

  EXPECT_FALSE(spdy_stream);
  EXPECT_TRUE(delegate.StreamIsClosed());

  // Write the RST_STREAM & GOAWAY.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

TEST_F(SpdySessionTest, VerifyDomainAuthentication) {
  SequencedSocketData data;
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
  EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
  EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.com"));
  EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.google.com"));
}

TEST_F(SpdySessionTest, ConnectionPooledWithTlsChannelId) {
  SequencedSocketData data;
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  ssl_.ssl_info.channel_id_sent = true;
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_TRUE(session_->VerifyDomainAuthentication("www.example.org"));
  EXPECT_TRUE(session_->VerifyDomainAuthentication("mail.example.org"));
  EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.example.com"));
  EXPECT_FALSE(session_->VerifyDomainAuthentication("mail.google.com"));
}

TEST_F(SpdySessionTest, CloseTwoStalledCreateStream) {
  // TODO(rtenneti): Define a helper class/methods and move the common code in
  // this file.
  spdy::SettingsMap new_settings;
  const spdy::SpdySettingsId kSpdySettingsId1 =
      spdy::SETTINGS_MAX_CONCURRENT_STREAMS;
  const uint32_t max_concurrent_streams = 1;
  new_settings[kSpdySettingsId1] = max_concurrent_streams;

  spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy_util_.UpdateWithStreamDestruction(1);
  spdy::SpdySerializedFrame req2(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST));
  spdy_util_.UpdateWithStreamDestruction(3);
  spdy::SpdySerializedFrame req3(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST));
  MockWrite writes[] = {
      CreateMockWrite(settings_ack, 1), CreateMockWrite(req1, 2),
      CreateMockWrite(req2, 5), CreateMockWrite(req3, 8),
  };

  // Set up the socket so we read a SETTINGS frame that sets max concurrent
  // streams to 1.
  spdy::SpdySerializedFrame settings_frame(
      spdy_util_.ConstructSpdySettings(new_settings));

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));

  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));

  spdy::SpdySerializedFrame resp3(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 5));
  spdy::SpdySerializedFrame body3(spdy_util_.ConstructSpdyDataFrame(5, true));

  MockRead reads[] = {
      CreateMockRead(settings_frame, 0),
      CreateMockRead(resp1, 3),
      CreateMockRead(body1, 4),
      CreateMockRead(resp2, 6),
      CreateMockRead(body2, 7),
      CreateMockRead(resp3, 9),
      CreateMockRead(body3, 10),
      MockRead(ASYNC, ERR_IO_PENDING, 11),
      MockRead(ASYNC, 0, 12)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Read the settings frame.
  base::RunLoop().RunUntilIdle();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  TestCompletionCallback callback2;
  SpdyStreamRequest request2;
  ASSERT_EQ(ERR_IO_PENDING,
            request2.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                  test_url_, LOWEST, SocketTag(),
                                  NetLogWithSource(), callback2.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  TestCompletionCallback callback3;
  SpdyStreamRequest request3;
  ASSERT_EQ(ERR_IO_PENDING,
            request3.StartRequest(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                  test_url_, LOWEST, SocketTag(),
                                  NetLogWithSource(), callback3.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated and then closed.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream1);
  EXPECT_EQ(1u, delegate1.stream_id());

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));

  // Pump loop for SpdySession::ProcessPendingStreamRequests() to
  // create the 2nd stream.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));

  base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream();
  test::StreamDelegateDoNothing delegate2(stream2);
  stream2->SetDelegate(&delegate2);
  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND);

  // Run until 2nd stream is activated and then closed.
  EXPECT_EQ(0u, delegate2.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(stream2);
  EXPECT_EQ(3u, delegate2.stream_id());

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));

  // Pump loop for SpdySession::ProcessPendingStreamRequests() to
  // create the 3rd stream.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));

  base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream();
  test::StreamDelegateDoNothing delegate3(stream3);
  stream3->SetDelegate(&delegate3);
  spdy::SpdyHeaderBlock headers3(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  stream3->SendRequestHeaders(std::move(headers3), NO_MORE_DATA_TO_SEND);

  // Run until 2nd stream is activated and then closed.
  EXPECT_EQ(0u, delegate3.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(stream3);
  EXPECT_EQ(5u, delegate3.stream_id());

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));

  data.Resume();
  base::RunLoop().RunUntilIdle();
}

TEST_F(SpdySessionTest, CancelTwoStalledCreateStream) {
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Leave room for only one more stream to be created.
  for (size_t i = 0; i < kInitialMaxConcurrentStreams - 1; ++i) {
    base::WeakPtr<SpdyStream> spdy_stream =
        CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, MEDIUM, NetLogWithSource());
    ASSERT_TRUE(spdy_stream);
  }

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  TestCompletionCallback callback2;
  SpdyStreamRequest request2;
  ASSERT_EQ(ERR_IO_PENDING,
            request2.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, LOWEST, SocketTag(),
                                  NetLogWithSource(), callback2.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  TestCompletionCallback callback3;
  SpdyStreamRequest request3;
  ASSERT_EQ(ERR_IO_PENDING,
            request3.StartRequest(SPDY_BIDIRECTIONAL_STREAM, session_,
                                  test_url_, LOWEST, SocketTag(),
                                  NetLogWithSource(), callback3.callback(),
                                  TRAFFIC_ANNOTATION_FOR_TESTS));

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
  EXPECT_EQ(2u, pending_create_stream_queue_size(LOWEST));

  // Cancel the first stream; this will allow the second stream to be created.
  EXPECT_TRUE(spdy_stream1);
  spdy_stream1->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream1);

  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
  EXPECT_EQ(1u, pending_create_stream_queue_size(LOWEST));

  // Cancel the second stream; this will allow the third stream to be created.
  base::WeakPtr<SpdyStream> spdy_stream2 = request2.ReleaseStream();
  spdy_stream2->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(kInitialMaxConcurrentStreams, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));

  // Cancel the third stream.
  base::WeakPtr<SpdyStream> spdy_stream3 = request3.ReleaseStream();
  spdy_stream3->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream3);
  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(kInitialMaxConcurrentStreams - 1, num_created_streams());
  EXPECT_EQ(0u, pending_create_stream_queue_size(LOWEST));
}

// Test that SpdySession::DoReadLoop reads data from the socket
// without yielding.  This test makes 32k - 1 bytes of data available
// on the socket for reading. It then verifies that it has read all
// the available data without yielding.
TEST_F(SpdySessionTest, ReadDataWithoutYielding) {
  session_deps_.time_func = InstantaneousReads;

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  // Build buffer of size kYieldAfterBytesRead / 4
  // (-spdy_data_frame_size).
  ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
  const int kPayloadSize = kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
  TestDataStream test_stream;
  scoped_refptr<IOBuffer> payload =
      base::MakeRefCounted<IOBuffer>(kPayloadSize);
  char* payload_data = payload->data();
  test_stream.GetBytes(payload_data, kPayloadSize);

  spdy::SpdySerializedFrame partial_data_frame(
      spdy_util_.ConstructSpdyDataFrame(
          1, base::StringPiece(payload_data, kPayloadSize), /*fin=*/false));
  spdy::SpdySerializedFrame finish_data_frame(spdy_util_.ConstructSpdyDataFrame(
      1, base::StringPiece(payload_data, kPayloadSize - 1), /*fin=*/true));

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
  // bytes.
  MockRead reads[] = {
      CreateMockRead(resp1, 1),
      MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(partial_data_frame, 3),
      CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
      CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
      CreateMockRead(finish_data_frame, 6, SYNCHRONOUS),
      MockRead(ASYNC, 0, 7)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Set up the TaskObserver to verify SpdySession::DoReadLoop doesn't
  // post a task.
  SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");

  // Run until 1st read.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(0u, observer.executed_count());

  // Read all the data and verify SpdySession::DoReadLoop has not
  // posted a task.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream1);

  // Verify task observer's executed_count is zero, which indicates DoRead read
  // all the available data.
  EXPECT_EQ(0u, observer.executed_count());
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Test that SpdySession::DoReadLoop yields if more than
// |kYieldAfterDurationMilliseconds| has passed.  This test uses a mock time
// function that makes the response frame look very slow to read.
TEST_F(SpdySessionTest, TestYieldingSlowReads) {
  session_deps_.time_func = SlowReads;

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  MockRead reads[] = {
      CreateMockRead(resp1, 1), MockRead(ASYNC, 0, 2)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Set up the TaskObserver to verify that SpdySession::DoReadLoop posts a
  // task.
  SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");

  EXPECT_EQ(0u, delegate1.stream_id());
  EXPECT_EQ(0u, observer.executed_count());

  // Read all the data and verify that SpdySession::DoReadLoop has posted a
  // task.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_FALSE(spdy_stream1);

  // Verify task that the observer's executed_count is 1, which indicates DoRead
  // has posted only one task and thus yielded though there is data available
  // for it to read.
  EXPECT_EQ(1u, observer.executed_count());
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Regression test for https://crbug.com/531570.
// Test the case where DoRead() takes long but returns synchronously.
TEST_F(SpdySessionTest, TestYieldingSlowSynchronousReads) {
  session_deps_.time_func = SlowReads;

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  spdy::SpdySerializedFrame partial_data_frame(
      spdy_util_.ConstructSpdyDataFrame(1, "foo ", /*fin=*/false));
  spdy::SpdySerializedFrame finish_data_frame(
      spdy_util_.ConstructSpdyDataFrame(1, "bar", /*fin=*/true));

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  MockRead reads[] = {
      CreateMockRead(resp1, 1),
      MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(partial_data_frame, 3, ASYNC),
      CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
      CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
      CreateMockRead(finish_data_frame, 6, SYNCHRONOUS),
      MockRead(ASYNC, 0, 7)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Run until 1st read.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());

  // Read all the data and verify SpdySession::DoReadLoop has posted a task.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ("foo foo foo bar", delegate1.TakeReceivedData());
  EXPECT_FALSE(spdy_stream1);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Test that SpdySession::DoReadLoop yields while reading the
// data. This test makes 32k + 1 bytes of data available on the socket
// for reading. It then verifies that DoRead has yielded even though
// there is data available for it to read (i.e, socket()->Read didn't
// return ERR_IO_PENDING during socket reads).
TEST_F(SpdySessionTest, TestYieldingDuringReadData) {
  session_deps_.time_func = InstantaneousReads;

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  // Build buffer of size kYieldAfterBytesRead / 4
  // (-spdy_data_frame_size).
  ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
  const int kPayloadSize = kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
  TestDataStream test_stream;
  scoped_refptr<IOBuffer> payload =
      base::MakeRefCounted<IOBuffer>(kPayloadSize);
  char* payload_data = payload->data();
  test_stream.GetBytes(payload_data, kPayloadSize);

  spdy::SpdySerializedFrame partial_data_frame(
      spdy_util_.ConstructSpdyDataFrame(
          1, base::StringPiece(payload_data, kPayloadSize), /*fin=*/false));
  spdy::SpdySerializedFrame finish_data_frame(
      spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true));

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
  MockRead reads[] = {
      CreateMockRead(resp1, 1),
      MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(partial_data_frame, 3),
      CreateMockRead(partial_data_frame, 4, SYNCHRONOUS),
      CreateMockRead(partial_data_frame, 5, SYNCHRONOUS),
      CreateMockRead(partial_data_frame, 6, SYNCHRONOUS),
      CreateMockRead(finish_data_frame, 7, SYNCHRONOUS),
      MockRead(ASYNC, 0, 8)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Set up the TaskObserver to verify SpdySession::DoReadLoop posts a task.
  SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");

  // Run until 1st read.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(0u, observer.executed_count());

  // Read all the data and verify SpdySession::DoReadLoop has posted a task.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream1);

  // Verify task observer's executed_count is 1, which indicates DoRead has
  // posted only one task and thus yielded though there is data available for it
  // to read.
  EXPECT_EQ(1u, observer.executed_count());
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Test that SpdySession::DoReadLoop() tests interactions of yielding
// + async, by doing the following MockReads.
//
// MockRead of SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K
// ASYNC 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 8K, SYNCHRONOUS 2K.
//
// The above reads 26K synchronously. Since that is less that 32K, we
// will attempt to read again. However, that DoRead() will return
// ERR_IO_PENDING (because of async read), so DoReadLoop() will
// yield. When we come back, DoRead() will read the results from the
// async read, and rest of the data synchronously.
TEST_F(SpdySessionTest, TestYieldingDuringAsyncReadData) {
  session_deps_.time_func = InstantaneousReads;

  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  // Build buffer of size kYieldAfterBytesRead / 4
  // (-spdy_data_frame_size).
  ASSERT_EQ(32 * 1024, kYieldAfterBytesRead);
  TestDataStream test_stream;
  const int kEightKPayloadSize =
      kYieldAfterBytesRead / 4 - spdy::kFrameHeaderSize;
  scoped_refptr<IOBuffer> eightk_payload =
      base::MakeRefCounted<IOBuffer>(kEightKPayloadSize);
  char* eightk_payload_data = eightk_payload->data();
  test_stream.GetBytes(eightk_payload_data, kEightKPayloadSize);

  // Build buffer of 2k size.
  TestDataStream test_stream2;
  const int kTwoKPayloadSize = kEightKPayloadSize - 6 * 1024;
  scoped_refptr<IOBuffer> twok_payload =
      base::MakeRefCounted<IOBuffer>(kTwoKPayloadSize);
  char* twok_payload_data = twok_payload->data();
  test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);

  spdy::SpdySerializedFrame eightk_data_frame(spdy_util_.ConstructSpdyDataFrame(
      1, base::StringPiece(eightk_payload_data, kEightKPayloadSize),
      /*fin=*/false));
  spdy::SpdySerializedFrame twok_data_frame(spdy_util_.ConstructSpdyDataFrame(
      1, base::StringPiece(twok_payload_data, kTwoKPayloadSize),
      /*fin=*/false));
  spdy::SpdySerializedFrame finish_data_frame(
      spdy_util_.ConstructSpdyDataFrame(1, "h", /*fin=*/true));

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

  MockRead reads[] = {
      CreateMockRead(resp1, 1),
      MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(eightk_data_frame, 3),
      CreateMockRead(eightk_data_frame, 4, SYNCHRONOUS),
      CreateMockRead(eightk_data_frame, 5, SYNCHRONOUS),
      CreateMockRead(twok_data_frame, 6, SYNCHRONOUS),
      CreateMockRead(eightk_data_frame, 7, ASYNC),
      CreateMockRead(eightk_data_frame, 8, SYNCHRONOUS),
      CreateMockRead(eightk_data_frame, 9, SYNCHRONOUS),
      CreateMockRead(eightk_data_frame, 10, SYNCHRONOUS),
      CreateMockRead(twok_data_frame, 11, SYNCHRONOUS),
      CreateMockRead(finish_data_frame, 12, SYNCHRONOUS),
      MockRead(ASYNC, 0, 13)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Set up the TaskObserver to monitor SpdySession::DoReadLoop
  // posting of tasks.
  SpdySessionTestTaskObserver observer("spdy_session.cc", "DoReadLoop");

  // Run until 1st read.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(0u, observer.executed_count());

  // Read all the data and verify SpdySession::DoReadLoop has posted a
  // task.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream1);

  // Verify task observer's executed_count is 1, which indicates DoRead has
  // posted only one task and thus yielded though there is data available for
  // it to read.
  EXPECT_EQ(1u, observer.executed_count());
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Send a GoAway frame when SpdySession is in DoReadLoop. Make sure
// nothing blows up.
TEST_F(SpdySessionTest, GoAwayWhileInDoReadLoop) {
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0),
  };

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(0));

  MockRead reads[] = {
      CreateMockRead(resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(body1, 3), CreateMockRead(goaway, 4),
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND);

  // Run until 1st read.
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, spdy_stream1->stream_id());

  // Run until GoAway.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream1);
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
  EXPECT_FALSE(session_);
}

// Within this framework, a SpdySession should be initialized with
// flow control disabled for protocol version 2, with flow control
// enabled only for streams for protocol version 3, and with flow
// control enabled for streams and sessions for higher versions.
TEST_F(SpdySessionTest, ProtocolNegotiation) {
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 0, 0)  // EOF
  };
  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  CreateNetworkSession();
  session_ = CreateFakeSpdySession(spdy_session_pool_, key_);

  EXPECT_EQ(kDefaultInitialWindowSize, session_send_window_size());
  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());
}

// Tests the case of a non-SPDY request closing an idle SPDY session when no
// pointers to the idle session are currently held.
TEST_F(SpdySessionTest, CloseOneIdleConnection) {
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  ClientSocketPoolManager::set_max_sockets_per_pool(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);

  MockRead reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };
  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();

  TransportClientSocketPool* pool =
      http_session_->GetTransportSocketPool(
          HttpNetworkSession::NORMAL_SOCKET_POOL);

  // Create an idle SPDY session.
  CreateSpdySession();
  EXPECT_FALSE(pool->IsStalled());

  // Trying to create a new connection should cause the pool to be stalled, and
  // post a task asynchronously to try and close the session.
  TestCompletionCallback callback2;
  HostPortPair host_port2("2.com", 80);
  scoped_refptr<TransportSocketParams> params2(new TransportSocketParams(
      host_port2, false, OnHostResolutionCallback(),
      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
  auto connection2 = std::make_unique<ClientSocketHandle>();
  EXPECT_EQ(
      ERR_IO_PENDING,
      connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
                        SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                        callback2.callback(), pool, NetLogWithSource()));
  EXPECT_TRUE(pool->IsStalled());

  // The socket pool should close the connection asynchronously and establish a
  // new connection.
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
  EXPECT_FALSE(pool->IsStalled());
  EXPECT_FALSE(session_);
}

// Tests the case of a non-SPDY request closing an idle SPDY session when no
// pointers to the idle session are currently held, in the case the SPDY session
// has an alias.
TEST_F(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  ClientSocketPoolManager::set_max_sockets_per_pool(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);

  MockRead reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };
  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  session_deps_.host_resolver->set_synchronous_mode(true);
  session_deps_.host_resolver->rules()->AddIPLiteralRule(
      "www.example.org", "192.168.0.2", std::string());
  session_deps_.host_resolver->rules()->AddIPLiteralRule(
      "mail.example.org", "192.168.0.2", std::string());
  // Not strictly needed.
  session_deps_.host_resolver->rules()->AddIPLiteralRule("3.com", "192.168.0.3",
                                                         std::string());

  CreateNetworkSession();

  TransportClientSocketPool* pool =
      http_session_->GetTransportSocketPool(
          HttpNetworkSession::NORMAL_SOCKET_POOL);

  // Create an idle SPDY session.
  SpdySessionKey key1(HostPortPair("www.example.org", 80),
                      ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
                      SocketTag());
  base::WeakPtr<SpdySession> session1 =
      ::net::CreateSpdySession(http_session_.get(), key1, NetLogWithSource());
  EXPECT_FALSE(pool->IsStalled());

  // Set up an alias for the idle SPDY session, increasing its ref count to 2.
  SpdySessionKey key2(HostPortPair("mail.example.org", 80),
                      ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
                      SocketTag());
  HostResolver::RequestInfo info(key2.host_port_pair());
  AddressList addresses;
  std::unique_ptr<HostResolver::Request> request;
  // Pre-populate the DNS cache, since a cached entry is required in order to
  // create the alias.
  int rv = session_deps_.host_resolver->Resolve(
      info, DEFAULT_PRIORITY, &addresses, CompletionOnceCallback(), &request,
      NetLogWithSource());
  EXPECT_THAT(rv, IsOk());

  // Get a session for |key2|, which should return the session created earlier.
  base::WeakPtr<SpdySession> session2 =
      spdy_session_pool_->FindAvailableSession(
          key2, /* enable_ip_based_pooling = */ true,
          /* is_websocket = */ false, NetLogWithSource());
  ASSERT_EQ(session1.get(), session2.get());
  EXPECT_FALSE(pool->IsStalled());

  // Trying to create a new connection should cause the pool to be stalled, and
  // post a task asynchronously to try and close the session.
  TestCompletionCallback callback3;
  HostPortPair host_port3("3.com", 80);
  scoped_refptr<TransportSocketParams> params3(new TransportSocketParams(
      host_port3, false, OnHostResolutionCallback(),
      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
  auto connection3 = std::make_unique<ClientSocketHandle>();
  EXPECT_EQ(
      ERR_IO_PENDING,
      connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
                        SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                        callback3.callback(), pool, NetLogWithSource()));
  EXPECT_TRUE(pool->IsStalled());

  // The socket pool should close the connection asynchronously and establish a
  // new connection.
  EXPECT_THAT(callback3.WaitForResult(), IsOk());
  EXPECT_FALSE(pool->IsStalled());
  EXPECT_FALSE(session1);
  EXPECT_FALSE(session2);
}

// Tests that when a SPDY session becomes idle, it closes itself if there is
// a lower layer pool stalled on the per-pool socket limit.
TEST_F(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) {
  ClientSocketPoolManager::set_max_sockets_per_group(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
  ClientSocketPoolManager::set_max_sockets_per_pool(
      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);

  MockRead reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };
  spdy::SpdySerializedFrame req1(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame cancel1(
      spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
  MockWrite writes[] = {
      CreateMockWrite(req1, 1), CreateMockWrite(cancel1, 1),
  };
  StaticSocketDataProvider data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  MockRead http_reads[] = {
    MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };
  StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&http_data);

  AddSSLSocketData();

  CreateNetworkSession();

  TransportClientSocketPool* pool =
      http_session_->GetTransportSocketPool(
          HttpNetworkSession::NORMAL_SOCKET_POOL);

  // Create a SPDY session.
  CreateSpdySession();
  EXPECT_FALSE(pool->IsStalled());

  // Create a stream using the session, and send a request.

  TestCompletionCallback callback1;
  base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
      SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY,
      NetLogWithSource());
  ASSERT_TRUE(spdy_stream1.get());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  EXPECT_EQ(ERR_IO_PENDING, spdy_stream1->SendRequestHeaders(
                                std::move(headers1), NO_MORE_DATA_TO_SEND));

  base::RunLoop().RunUntilIdle();

  // Trying to create a new connection should cause the pool to be stalled, and
  // post a task asynchronously to try and close the session.
  TestCompletionCallback callback2;
  HostPortPair host_port2("2.com", 80);
  scoped_refptr<TransportSocketParams> params2(new TransportSocketParams(
      host_port2, false, OnHostResolutionCallback(),
      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
  auto connection2 = std::make_unique<ClientSocketHandle>();
  EXPECT_EQ(
      ERR_IO_PENDING,
      connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
                        SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
                        callback2.callback(), pool, NetLogWithSource()));
  EXPECT_TRUE(pool->IsStalled());

  // Running the message loop should cause the socket pool to ask the SPDY
  // session to close an idle socket, but since the socket is in use, nothing
  // happens.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(pool->IsStalled());
  EXPECT_FALSE(callback2.have_result());

  // Cancelling the request should result in the session's socket being
  // closed, since the pool is stalled.
  ASSERT_TRUE(spdy_stream1.get());
  spdy_stream1->Cancel(ERR_ABORTED);
  base::RunLoop().RunUntilIdle();
  ASSERT_FALSE(pool->IsStalled());
  EXPECT_THAT(callback2.WaitForResult(), IsOk());
}

// Verify that SpdySessionKey and therefore SpdySession is different when
// privacy mode is enabled or disabled.
TEST_F(SpdySessionTest, SpdySessionKeyPrivacyMode) {
  CreateNetworkSession();

  HostPortPair host_port_pair("www.example.org", 443);
  SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
                                     PRIVACY_MODE_ENABLED, SocketTag());
  SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
                                      PRIVACY_MODE_DISABLED, SocketTag());

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));

  // Add SpdySession with PrivacyMode Enabled to the pool.
  base::WeakPtr<SpdySession> session_privacy_enabled =
      CreateFakeSpdySession(spdy_session_pool_, key_privacy_enabled);

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));

  // Add SpdySession with PrivacyMode Disabled to the pool.
  base::WeakPtr<SpdySession> session_privacy_disabled =
      CreateFakeSpdySession(spdy_session_pool_, key_privacy_disabled);

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));

  session_privacy_enabled->CloseSessionOnError(ERR_ABORTED, std::string());
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));

  session_privacy_disabled->CloseSessionOnError(ERR_ABORTED, std::string());
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_enabled));
  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_privacy_disabled));
}

// Delegate that creates another stream when its stream is closed.
class StreamCreatingDelegate : public test::StreamDelegateDoNothing {
 public:
  StreamCreatingDelegate(const base::WeakPtr<SpdyStream>& stream,
                         const base::WeakPtr<SpdySession>& session)
      : StreamDelegateDoNothing(stream),
        session_(session) {}

  ~StreamCreatingDelegate() override = default;

  void OnClose(int status) override {
    GURL url(kDefaultUrl);
    ignore_result(CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
                                            session_, url, MEDIUM,
                                            NetLogWithSource()));
  }

 private:
  const base::WeakPtr<SpdySession> session_;
};

// Create another stream in response to a stream being reset. Nothing
// should blow up. This is a regression test for
// http://crbug.com/263690 .
TEST_F(SpdySessionTest, CreateStreamOnStreamReset) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };

  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(rst, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4)  // EOF
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  EXPECT_EQ(0u, spdy_stream->stream_id());

  StreamCreatingDelegate delegate(spdy_stream, session_);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  EXPECT_EQ(0u, spdy_stream->stream_id());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1u, spdy_stream->stream_id());

  // Cause the stream to be reset, which should cause another stream
  // to be created.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(spdy_stream);
  EXPECT_TRUE(delegate.StreamIsClosed());
  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, UpdateStreamsSendWindowSize) {
  // Set spdy::SETTINGS_INITIAL_WINDOW_SIZE to a small number so that
  // WINDOW_UPDATE gets sent.
  spdy::SettingsMap new_settings;
  int32_t window_size = 1;
  new_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = window_size;

  // Set up the socket so we read a SETTINGS frame that sets
  // INITIAL_WINDOW_SIZE.
  spdy::SpdySerializedFrame settings_frame(
      spdy_util_.ConstructSpdySettings(new_settings));
  MockRead reads[] = {
      CreateMockRead(settings_frame, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
      MockRead(ASYNC, 0, 2)  // EOF
  };

  spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  MockWrite writes[] = {
      CreateMockWrite(settings_ack, 3),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  TestCompletionCallback callback1;
  EXPECT_NE(spdy_stream1->send_window_size(), window_size);

  // Process the SETTINGS frame.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(stream_initial_send_window_size(), window_size);
  EXPECT_EQ(spdy_stream1->send_window_size(), window_size);

  // Release the first one, this will allow the second to be created.
  spdy_stream1->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream1);

  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(spdy_stream2);
  EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
  spdy_stream2->Cancel(ERR_ABORTED);
  EXPECT_FALSE(spdy_stream2);

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// SpdySession::{Increase,Decrease}RecvWindowSize should properly
// adjust the session receive window size. In addition,
// SpdySession::IncreaseRecvWindowSize should trigger
// sending a WINDOW_UPDATE frame for a large enough delta.
TEST_F(SpdySessionTest, AdjustRecvWindowSize) {
  const int32_t initial_window_size = kDefaultInitialWindowSize;
  const int32_t delta_window_size = 100;

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2)  // EOF
  };
  spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
      spdy::kSessionFlowControlStreamId,
      initial_window_size + delta_window_size));
  MockWrite writes[] = {
      CreateMockWrite(window_update, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  IncreaseRecvWindowSize(delta_window_size);
  EXPECT_EQ(initial_window_size + delta_window_size,
            session_recv_window_size());
  EXPECT_EQ(delta_window_size, session_unacked_recv_window_bytes());

  // Should trigger sending a WINDOW_UPDATE frame.
  IncreaseRecvWindowSize(initial_window_size);
  EXPECT_EQ(initial_window_size + delta_window_size + initial_window_size,
            session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  base::RunLoop().RunUntilIdle();

  // DecreaseRecvWindowSize() expects |in_io_loop_| to be true.
  set_in_io_loop(true);
  DecreaseRecvWindowSize(initial_window_size + delta_window_size +
                         initial_window_size);
  set_in_io_loop(false);
  EXPECT_EQ(0, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// SpdySession::{Increase,Decrease}SendWindowSize should properly
// adjust the session send window size when the "enable_spdy_31" flag
// is set.
TEST_F(SpdySessionTest, AdjustSendWindowSize) {
  MockRead reads[] = {
    MockRead(SYNCHRONOUS, 0, 0)  // EOF
  };
  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  CreateNetworkSession();
  session_ = CreateFakeSpdySession(spdy_session_pool_, key_);

  const int32_t initial_window_size = kDefaultInitialWindowSize;
  const int32_t delta_window_size = 100;

  EXPECT_EQ(initial_window_size, session_send_window_size());

  IncreaseSendWindowSize(delta_window_size);
  EXPECT_EQ(initial_window_size + delta_window_size,
            session_send_window_size());

  DecreaseSendWindowSize(delta_window_size);
  EXPECT_EQ(initial_window_size, session_send_window_size());
}

// Incoming data for an inactive stream should not cause the session
// receive window size to decrease, but it should cause the unacked
// bytes to increase.
TEST_F(SpdySessionTest, SessionFlowControlInactiveStream) {
  spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyDataFrame(1, false));
  MockRead reads[] = {
      CreateMockRead(resp, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
      MockRead(ASYNC, 0, 2)  // EOF
  };
  SequencedSocketData data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(kUploadDataSize, session_unacked_recv_window_bytes());

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// The frame header is not included in flow control, but frame payload
// (including optional pad length and padding) is.
TEST_F(SpdySessionTest, SessionFlowControlPadding) {
  const int padding_length = 42;
  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyDataFrame(1, kUploadData, false, padding_length));
  MockRead reads[] = {
      CreateMockRead(resp, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
      MockRead(ASYNC, 0, 2)  // EOF
  };
  SequencedSocketData data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kDefaultInitialWindowSize, session_recv_window_size());
  EXPECT_EQ(kUploadDataSize + padding_length,
            session_unacked_recv_window_bytes());

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Peer sends more data than stream level receiving flow control window.
TEST_F(SpdySessionTest, StreamFlowControlTooMuchData) {
  const int32_t stream_max_recv_window_size = 1024;
  const int32_t data_frame_size = 2 * stream_max_recv_window_size;

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
      1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(rst, 4),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  const std::string payload(data_frame_size, 'a');
  spdy::SpdySerializedFrame data_frame(
      spdy_util_.ConstructSpdyDataFrame(1, payload, false));
  MockRead reads[] = {
      CreateMockRead(resp, 1),       MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(data_frame, 3), MockRead(ASYNC, ERR_IO_PENDING, 5),
      MockRead(ASYNC, 0, 6),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
      stream_max_recv_window_size;
  CreateNetworkSession();

  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());

  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
                                std::move(headers), NO_MORE_DATA_TO_SEND));

  // Request and response.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, spdy_stream->stream_id());

  // Too large data frame causes flow control error, should close stream.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream);

  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Regression test for a bug that was caused by including unsent WINDOW_UPDATE
// deltas in the receiving window size when checking incoming frames for flow
// control errors at session level.
TEST_F(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
  const int32_t session_max_recv_window_size = 500;
  const int32_t first_data_frame_size = 200;
  const int32_t second_data_frame_size = 400;

  // First data frame should not trigger a WINDOW_UPDATE.
  ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size);
  // Second data frame would be fine had there been a WINDOW_UPDATE.
  ASSERT_GT(session_max_recv_window_size, second_data_frame_size);
  // But in fact, the two data frames together overflow the receiving window at
  // session level.
  ASSERT_LT(session_max_recv_window_size,
            first_data_frame_size + second_data_frame_size);

  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
      "delta_window_size is 400 in DecreaseRecvWindowSize, which is larger "
      "than the receive window size of 500"));
  MockWrite writes[] = {
      CreateMockWrite(goaway, 4),
  };

  const std::string first_data_frame(first_data_frame_size, 'a');
  spdy::SpdySerializedFrame first(
      spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false));
  const std::string second_data_frame(second_data_frame_size, 'b');
  spdy::SpdySerializedFrame second(
      spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false));
  MockRead reads[] = {
      CreateMockRead(first, 0), MockRead(ASYNC, ERR_IO_PENDING, 1),
      CreateMockRead(second, 2), MockRead(ASYNC, 0, 3),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  // Setting session level receiving window size to smaller than initial is not
  // possible via SpdySessionPoolPeer.
  set_session_recv_window_size(session_max_recv_window_size);

  // First data frame is immediately consumed and does not trigger
  // WINDOW_UPDATE.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(first_data_frame_size, session_unacked_recv_window_bytes());
  EXPECT_EQ(session_max_recv_window_size, session_recv_window_size());
  EXPECT_TRUE(session_->IsAvailable());

  // Second data frame overflows receiving window, causes session to close.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(session_->IsDraining());
}

// Regression test for a bug that was caused by including unsent WINDOW_UPDATE
// deltas in the receiving window size when checking incoming data frames for
// flow control errors at stream level.
TEST_F(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
  const int32_t stream_max_recv_window_size = 500;
  const int32_t first_data_frame_size = 200;
  const int32_t second_data_frame_size = 400;

  // First data frame should not trigger a WINDOW_UPDATE.
  ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size);
  // Second data frame would be fine had there been a WINDOW_UPDATE.
  ASSERT_GT(stream_max_recv_window_size, second_data_frame_size);
  // But in fact, they should overflow the receiving window at stream level.
  ASSERT_LT(stream_max_recv_window_size,
            first_data_frame_size + second_data_frame_size);

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame rst(spdy_util_.ConstructSpdyRstStream(
      1, spdy::ERROR_CODE_FLOW_CONTROL_ERROR));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(rst, 6),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  const std::string first_data_frame(first_data_frame_size, 'a');
  spdy::SpdySerializedFrame first(
      spdy_util_.ConstructSpdyDataFrame(1, first_data_frame, false));
  const std::string second_data_frame(second_data_frame_size, 'b');
  spdy::SpdySerializedFrame second(
      spdy_util_.ConstructSpdyDataFrame(1, second_data_frame, false));
  MockRead reads[] = {
      CreateMockRead(resp, 1),   MockRead(ASYNC, ERR_IO_PENDING, 2),
      CreateMockRead(first, 3),  MockRead(ASYNC, ERR_IO_PENDING, 4),
      CreateMockRead(second, 5), MockRead(ASYNC, ERR_IO_PENDING, 7),
      MockRead(ASYNC, 0, 8),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
      stream_max_recv_window_size;
  CreateNetworkSession();

  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
                                std::move(headers), NO_MORE_DATA_TO_SEND));

  // Request and response.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(spdy_stream->IsLocallyClosed());
  EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());

  // First data frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(spdy_stream->IsLocallyClosed());
  EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size,
            spdy_stream->recv_window_size());

  // Consume first data frame.  This does not trigger a WINDOW_UPDATE.
  std::string received_data = delegate.TakeReceivedData();
  EXPECT_EQ(static_cast<size_t>(first_data_frame_size), received_data.size());
  EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());

  // Second data frame overflows receiving window, causes the stream to close.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(spdy_stream.get());

  // RST_STREAM
  EXPECT_TRUE(session_);
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// A delegate that drops any received data.
class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
 public:
  DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
                           base::StringPiece data)
      : StreamDelegateSendImmediate(stream, data) {}

  ~DropReceivedDataDelegate() override = default;

  // Drop any received data.
  void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {}
};

// Send data back and forth but use a delegate that drops its received
// data. The receive window should still increase to its original
// value, i.e. we shouldn't "leak" receive window bytes.
TEST_F(SpdySessionTest, SessionFlowControlNoReceiveLeaks) {
  const int32_t kMsgDataSize = 100;
  const std::string msg_data(kMsgDataSize, 'a');

  spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
  spdy::SpdySerializedFrame msg(
      spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(msg, 2),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame echo(
      spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
  spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
      spdy::kSessionFlowControlStreamId, kMsgDataSize));
  MockRead reads[] = {
      CreateMockRead(resp, 1), CreateMockRead(echo, 3),
      MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(stream);
  EXPECT_EQ(0u, stream->stream_id());

  DropReceivedDataDelegate delegate(stream, msg_data);
  stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
  EXPECT_EQ(ERR_IO_PENDING,
            stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));

  const int32_t initial_window_size = kDefaultInitialWindowSize;
  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());

  stream->Close();
  EXPECT_FALSE(stream);

  EXPECT_THAT(delegate.WaitForClose(), IsOk());

  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Send data back and forth but close the stream before its data frame
// can be written to the socket. The send window should then increase
// to its original value, i.e. we shouldn't "leak" send window bytes.
TEST_F(SpdySessionTest, SessionFlowControlNoSendLeaks) {
  const int32_t kMsgDataSize = 100;
  const std::string msg_data(kMsgDataSize, 'a');

  spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(stream);
  EXPECT_EQ(0u, stream->stream_id());

  test::StreamDelegateSendImmediate delegate(stream, msg_data);
  stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
  EXPECT_EQ(ERR_IO_PENDING,
            stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));

  const int32_t initial_window_size = kDefaultInitialWindowSize;
  EXPECT_EQ(initial_window_size, session_send_window_size());

  // Write request.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(initial_window_size, session_send_window_size());

  // Read response, but do not run the message loop, so that the body is not
  // written to the socket.
  data.Resume();

  EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());

  // Closing the stream should increase the session's send window.
  stream->Close();
  EXPECT_FALSE(stream);

  EXPECT_EQ(initial_window_size, session_send_window_size());

  EXPECT_THAT(delegate.WaitForClose(), IsOk());

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Send data back and forth; the send and receive windows should
// change appropriately.
TEST_F(SpdySessionTest, SessionFlowControlEndToEnd) {
  const int32_t kMsgDataSize = 100;
  const std::string msg_data(kMsgDataSize, 'a');

  spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kMsgDataSize, MEDIUM, nullptr, 0));
  spdy::SpdySerializedFrame msg(
      spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(msg, 2),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame echo(
      spdy_util_.ConstructSpdyDataFrame(1, msg_data, false));
  spdy::SpdySerializedFrame window_update(spdy_util_.ConstructSpdyWindowUpdate(
      spdy::kSessionFlowControlStreamId, kMsgDataSize));
  MockRead reads[] = {
      CreateMockRead(resp, 1),
      MockRead(ASYNC, ERR_IO_PENDING, 3),
      CreateMockRead(echo, 4),
      MockRead(ASYNC, ERR_IO_PENDING, 5),
      CreateMockRead(window_update, 6),
      MockRead(ASYNC, ERR_IO_PENDING, 7),
      MockRead(ASYNC, 0, 8)  // EOF
  };

  // Create SpdySession and SpdyStream and send the request.
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream =
      CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session_, test_url_,
                                MEDIUM, NetLogWithSource());
  ASSERT_TRUE(stream);
  EXPECT_EQ(0u, stream->stream_id());

  test::StreamDelegateSendImmediate delegate(stream, msg_data);
  stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kMsgDataSize));
  EXPECT_EQ(ERR_IO_PENDING,
            stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));

  const int32_t initial_window_size = kDefaultInitialWindowSize;
  EXPECT_EQ(initial_window_size, session_send_window_size());
  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Send request and message.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Read echo.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(initial_window_size - kMsgDataSize, session_send_window_size());
  EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  // Read window update.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(initial_window_size, session_send_window_size());
  EXPECT_EQ(initial_window_size - kMsgDataSize, session_recv_window_size());
  EXPECT_EQ(0, session_unacked_recv_window_bytes());

  EXPECT_EQ(msg_data, delegate.TakeReceivedData());

  // Draining the delegate's read queue should increase the session's
  // receive window.
  EXPECT_EQ(initial_window_size, session_send_window_size());
  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());

  stream->Close();
  EXPECT_FALSE(stream);

  EXPECT_THAT(delegate.WaitForClose(), IsOk());

  EXPECT_EQ(initial_window_size, session_send_window_size());
  EXPECT_EQ(initial_window_size, session_recv_window_size());
  EXPECT_EQ(kMsgDataSize, session_unacked_recv_window_bytes());

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

// Given a stall function and an unstall function, runs a test to make
// sure that a stream resumes after unstall.
void SpdySessionTest::RunResumeAfterUnstallTest(
    const base::Callback<void(SpdyStream*)>& stall_function,
    const base::Callback<void(SpdyStream*, int32_t)>& unstall_function) {
  spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame body(
      spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(body, 1),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame echo(
      spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false));
  MockRead reads[] = {
      CreateMockRead(resp, 2), MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream);

  test::StreamDelegateWithBody delegate(stream, kBodyDataStringPiece);
  stream->SetDelegate(&delegate);

  EXPECT_FALSE(stream->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING,
            stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream->url().spec());

  stall_function.Run(stream.get());

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(stream->send_stalled_by_flow_control());

  unstall_function.Run(stream.get(), kBodyDataSize);

  EXPECT_FALSE(stream->send_stalled_by_flow_control());

  EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  EXPECT_TRUE(delegate.send_headers_completed());
  EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate.TakeReceivedData());

  // Run SpdySession::PumpWriteLoop which destroys |session_|.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(session_);
  EXPECT_TRUE(data.AllWriteDataConsumed());
}

// Run the resume-after-unstall test with all possible stall and
// unstall sequences.

TEST_F(SpdySessionTest, ResumeAfterUnstallSession) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallSessionOnly,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallSessionOnly,
                 base::Unretained(this)));
}

// Equivalent to
// SpdyStreamTest.ResumeAfterSendWindowSizeIncrease.
TEST_F(SpdySessionTest, ResumeAfterUnstallStream) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallStreamOnly,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallStreamOnly,
                 base::Unretained(this)));
}

TEST_F(SpdySessionTest, StallSessionStreamResumeAfterUnstallSessionStream) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallSessionStream,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallSessionStream,
                 base::Unretained(this)));
}

TEST_F(SpdySessionTest, StallStreamSessionResumeAfterUnstallSessionStream) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallStreamSession,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallSessionStream,
                 base::Unretained(this)));
}

TEST_F(SpdySessionTest, StallStreamSessionResumeAfterUnstallStreamSession) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallStreamSession,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallStreamSession,
                 base::Unretained(this)));
}

TEST_F(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) {
  RunResumeAfterUnstallTest(
      base::Bind(&SpdySessionTest::StallSessionStream,
                 base::Unretained(this)),
      base::Bind(&SpdySessionTest::UnstallStreamSession,
                 base::Unretained(this)));
}

// Cause a stall by reducing the flow control send window to 0. The
// streams should resume in priority order when that window is then
// increased.
TEST_F(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
  spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 3, kBodyDataSize, MEDIUM, nullptr, 0));
  spdy::SpdySerializedFrame body1(
      spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
  spdy::SpdySerializedFrame body2(
      spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
      CreateMockWrite(body2, 2), CreateMockWrite(body1, 3),
  };

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  MockRead reads[] = {
      CreateMockRead(resp1, 4), CreateMockRead(resp2, 5),
      MockRead(ASYNC, 0, 6)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream1);

  test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
  stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, MEDIUM, NetLogWithSource());
  ASSERT_TRUE(stream2);

  test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
  stream2->SetDelegate(&delegate2);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  StallSessionSend();

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream1->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, stream1->stream_id());
  EXPECT_TRUE(stream1->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream2->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, stream2->stream_id());
  EXPECT_TRUE(stream2->send_stalled_by_flow_control());

  // This should unstall only stream2.
  UnstallSessionSend(kBodyDataSize);

  EXPECT_TRUE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  // This should then unstall stream1.
  UnstallSessionSend(kBodyDataSize);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  base::RunLoop().RunUntilIdle();

  EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
  EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  EXPECT_TRUE(delegate1.send_headers_completed());
  EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate1.TakeReceivedData());

  EXPECT_TRUE(delegate2.send_headers_completed());
  EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate2.TakeReceivedData());

  EXPECT_FALSE(session_);
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// An upload stream is stalled when the session gets unstalled, then the session
// is stalled again when the stream gets unstalled.  The stream should not fail.
// Regression test for https://crbug.com/761919.
TEST_F(SpdySessionTest, ResumeSessionWithStalledStream) {
  spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame body1(
      spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
  spdy::SpdySerializedFrame body2(
      spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, true));
  MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
                        CreateMockWrite(body1, 2), CreateMockWrite(body2, 3)};

  spdy::SpdySerializedFrame resp1(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(resp2, 5),
                      MockRead(ASYNC, 0, 6)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream1);

  test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
  stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream2);

  test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
  stream2->SetDelegate(&delegate2);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  StallSessionSend();

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream1->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, stream1->stream_id());
  EXPECT_TRUE(stream1->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream2->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, stream2->stream_id());
  EXPECT_TRUE(stream2->send_stalled_by_flow_control());

  StallStreamSend(stream1.get());

  // At this point, both |session| and |stream1| are stalled
  // by their respective flow control mechanisms.  Now unstall the session.
  // This calls session->ResumeSendStalledStreams(), which calls
  // stream1->PossiblyResumeIfSendStalled().  However, |stream1| is stalled, so
  // no data are sent on that stream.  At this point, |stream1| should not be
  // removed from session_->stream_send_unstall_queue_.
  // Then stream2->PossiblyResumeIfSendStalled() is called,
  // data are sent on |stream2|, and |session_| stalls again.
  UnstallSessionSend(kBodyDataSize);

  EXPECT_TRUE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  // Make sure that the session is stalled.  Otherwise
  // stream1->PossiblyResumeIfSendStalled() would resume the stream as soon as
  // the stream is unstalled, hiding the bug.
  EXPECT_TRUE(session_->IsSendStalled());
  UnstallStreamSend(stream1.get(), kBodyDataSize);

  // Finally, unstall session.
  UnstallSessionSend(kBodyDataSize);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  base::RunLoop().RunUntilIdle();

  EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
  EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  EXPECT_TRUE(delegate1.send_headers_completed());
  EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate1.TakeReceivedData());

  EXPECT_TRUE(delegate2.send_headers_completed());
  EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate2.TakeReceivedData());

  EXPECT_FALSE(session_);
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

// Delegate that closes a given stream after sending its body.
class StreamClosingDelegate : public test::StreamDelegateWithBody {
 public:
  StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
                        base::StringPiece data)
      : StreamDelegateWithBody(stream, data) {}

  ~StreamClosingDelegate() override = default;

  void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
    stream_to_close_ = stream_to_close;
  }

  void OnDataSent() override {
    test::StreamDelegateWithBody::OnDataSent();
    if (stream_to_close_.get()) {
      stream_to_close_->Close();
      EXPECT_FALSE(stream_to_close_);
    }
  }

 private:
  base::WeakPtr<SpdyStream> stream_to_close_;
};

// Cause a stall by reducing the flow control send window to
// 0. Unstalling the session should properly handle deleted streams.
TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
  spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame req3(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 5, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame body2(
      spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
      CreateMockWrite(req3, 2), CreateMockWrite(body2, 3),
  };

  spdy::SpdySerializedFrame resp2(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
  MockRead reads[] = {
      CreateMockRead(resp2, 4), MockRead(ASYNC, ERR_IO_PENDING, 5),
      MockRead(ASYNC, 0, 6)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream1);

  test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
  stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream2);

  StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
  stream2->SetDelegate(&delegate2);

  base::WeakPtr<SpdyStream> stream3 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream3);

  test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
  stream3->SetDelegate(&delegate3);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());
  EXPECT_FALSE(stream3->send_stalled_by_flow_control());

  StallSessionSend();

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream1->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, stream1->stream_id());
  EXPECT_TRUE(stream1->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream2->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, stream2->stream_id());
  EXPECT_TRUE(stream2->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers3(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream3->SendRequestHeaders(std::move(headers3),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream3->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(5u, stream3->stream_id());
  EXPECT_TRUE(stream3->send_stalled_by_flow_control());

  spdy::SpdyStreamId stream_id1 = stream1->stream_id();
  spdy::SpdyStreamId stream_id2 = stream2->stream_id();
  spdy::SpdyStreamId stream_id3 = stream3->stream_id();

  // Close stream1 preemptively.
  session_->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
  EXPECT_FALSE(stream1);

  EXPECT_FALSE(session_->IsStreamActive(stream_id1));
  EXPECT_TRUE(session_->IsStreamActive(stream_id2));
  EXPECT_TRUE(session_->IsStreamActive(stream_id3));

  // Unstall stream2, which should then close stream3.
  delegate2.set_stream_to_close(stream3);
  UnstallSessionSend(kBodyDataSize);

  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(stream3);

  EXPECT_FALSE(stream2->send_stalled_by_flow_control());
  EXPECT_FALSE(session_->IsStreamActive(stream_id1));
  EXPECT_TRUE(session_->IsStreamActive(stream_id2));
  EXPECT_FALSE(session_->IsStreamActive(stream_id3));

  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(stream2);
  EXPECT_FALSE(session_);

  EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
  EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
  EXPECT_THAT(delegate3.WaitForClose(), IsOk());

  EXPECT_TRUE(delegate1.send_headers_completed());
  EXPECT_EQ(std::string(), delegate1.TakeReceivedData());

  EXPECT_TRUE(delegate2.send_headers_completed());
  EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
  EXPECT_EQ(std::string(), delegate2.TakeReceivedData());

  EXPECT_TRUE(delegate3.send_headers_completed());
  EXPECT_EQ(std::string(), delegate3.TakeReceivedData());

  EXPECT_TRUE(data.AllWriteDataConsumed());
}

// Cause a stall by reducing the flow control send window to
// 0. Unstalling the session should properly handle the session itself
// being closed.
TEST_F(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
  spdy::SpdySerializedFrame req1(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 1, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost(
      kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0));
  spdy::SpdySerializedFrame body1(
      spdy_util_.ConstructSpdyDataFrame(1, kBodyDataStringPiece, false));
  MockWrite writes[] = {
      CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
  };

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream1);

  test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
  stream1->SetDelegate(&delegate1);

  base::WeakPtr<SpdyStream> stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(stream2);

  test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
  stream2->SetDelegate(&delegate2);

  EXPECT_FALSE(stream1->send_stalled_by_flow_control());
  EXPECT_FALSE(stream2->send_stalled_by_flow_control());

  StallSessionSend();

  spdy::SpdyHeaderBlock headers1(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream1->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, stream1->stream_id());
  EXPECT_TRUE(stream1->send_stalled_by_flow_control());

  spdy::SpdyHeaderBlock headers2(
      spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize));
  EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2),
                                                        MORE_DATA_TO_SEND));
  EXPECT_EQ(kDefaultUrl, stream2->url().spec());

  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, stream2->stream_id());
  EXPECT_TRUE(stream2->send_stalled_by_flow_control());

  EXPECT_TRUE(HasSpdySession(spdy_session_pool_, key_));

  // Unstall stream1.
  UnstallSessionSend(kBodyDataSize);

  // Close the session (since we can't do it from within the delegate
  // method, since it's in the stream's loop).
  session_->CloseSessionOnError(ERR_CONNECTION_CLOSED, "Closing session");
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  EXPECT_FALSE(HasSpdySession(spdy_session_pool_, key_));

  EXPECT_THAT(delegate1.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));
  EXPECT_THAT(delegate2.WaitForClose(), IsError(ERR_CONNECTION_CLOSED));

  EXPECT_TRUE(delegate1.send_headers_completed());
  EXPECT_EQ(std::string(), delegate1.TakeReceivedData());

  EXPECT_TRUE(delegate2.send_headers_completed());
  EXPECT_EQ(std::string(), delegate2.TakeReceivedData());

  EXPECT_TRUE(data.AllWriteDataConsumed());
}

TEST_F(SpdySessionTest, GoAwayOnSessionFlowControlError) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      0, spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
      "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than "
      "the receive window size of 1"));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(goaway, 4),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
      CreateMockRead(body, 3),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Write request.
  base::RunLoop().RunUntilIdle();

  // Put session on the edge of overflowing it's recv window.
  set_session_recv_window_size(1);

  // Read response headers & body. Body overflows the session window, and a
  // goaway is written.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_THAT(delegate.WaitForClose(), IsError(ERR_SPDY_FLOW_CONTROL_ERROR));
  EXPECT_FALSE(session_);
}

// Regression. Sorta. Push streams and client streams were sharing a single
// limit for a long time.
TEST_F(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) {
  spdy::SettingsMap new_settings;
  new_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 2;
  spdy::SpdySerializedFrame settings_frame(
      spdy_util_.ConstructSpdySettings(new_settings));
  spdy::SpdySerializedFrame pushed(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  MockRead reads[] = {
      CreateMockRead(settings_frame, 0),
      MockRead(ASYNC, ERR_IO_PENDING, 3),
      CreateMockRead(pushed, 4),
      MockRead(ASYNC, ERR_IO_PENDING, 6),
      MockRead(ASYNC, 0, 7),
  };

  spdy::SpdySerializedFrame settings_ack(spdy_util_.ConstructSpdySettingsAck());
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  MockWrite writes[] = {
      CreateMockWrite(settings_ack, 1), CreateMockWrite(req, 2),
      CreateMockWrite(priority, 5),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  // Read the settings frame.
  base::RunLoop().RunUntilIdle();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Run until pushed stream is created.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Second stream should not be stalled, although we have 2 active streams, but
  // one of them is push stream and should not be taken into account when we
  // create streams on the client.
  base::WeakPtr<SpdyStream> spdy_stream2 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  EXPECT_TRUE(spdy_stream2);
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame push_a(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdySerializedFrame push_b(spdy_util_.ConstructSpdyPush(
      nullptr, 0, 4, 1, "https://www.example.org/b.dat"));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_a, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(push_b, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 8), MockRead(ASYNC, 0, 9),
  };

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority_a(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame priority_b(
      spdy_util_.ConstructSpdyPriority(4, 2, IDLE, true));
  spdy::SpdySerializedFrame rst_b(
      spdy_util_.ConstructSpdyRstStream(4, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(priority_a, 3),
      CreateMockWrite(priority_b, 6), CreateMockWrite(rst_b, 7),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  set_max_concurrent_pushed_streams(1);

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Run until pushed stream is created.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Reset incoming pushed stream.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kTooManyPushedStreams), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

// Tests that HTTP SPDY push streams that advertise an origin different from the
// associated stream are accepted from a trusted SPDY proxy.
TEST_F(SpdySessionTest, TrustedSpdyProxy) {
  base::HistogramTester histogram_tester;

  // Origin of kDefaultUrl should be different from the origin of
  // kHttpURLFromAnotherOrigin and kHttpsURLFromAnotherOrigin.
  ASSERT_NE(GURL(kDefaultUrl).host(), GURL(kHttpURLFromAnotherOrigin).host());
  ASSERT_NE(GURL(kDefaultUrl).host(), GURL(kHttpsURLFromAnotherOrigin).host());

  // cross_origin_push contains HTTP resource for an origin different from the
  // origin of kDefaultUrl, and should be accepted.
  spdy::SpdySerializedFrame cross_origin_push(spdy_util_.ConstructSpdyPush(
      nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
  // cross_origin_https_push contains HTTPS resource, and should be refused.
  spdy::SpdySerializedFrame cross_origin_https_push(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 4, 1,
                                   kHttpsURLFromAnotherOrigin));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1),
      CreateMockRead(cross_origin_push, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 4),
      CreateMockRead(cross_origin_https_push, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 7),
      MockRead(ASYNC, 0, 8),
  };

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority_http(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame rst_https(
      spdy_util_.ConstructSpdyRstStream(4, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(priority_http, 3),
      CreateMockWrite(rst_https, 6),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateTrustedSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  EXPECT_EQ(0u, spdy_stream->stream_id());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Run until pushed stream is created.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Reset incoming pushed stream.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kNonHttpSchemeFromTrustedProxy),
      1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

// Tests that if the SPDY trusted proxy is not set, then push streams that
// advertise an origin different from the associated stream are refused.
TEST_F(SpdySessionTest, TrustedSpdyProxyNotSet) {
  base::HistogramTester histogram_tester;

  // Origin of kDefaultUrl should be different from the origin of
  // kHttpURLFromAnotherOrigin.
  ASSERT_NE(GURL(kDefaultUrl).host(), GURL(kHttpURLFromAnotherOrigin).host());

  // cross_origin_push contains resource for an origin different from the
  // origin of kDefaultUrl, and should be refused.
  spdy::SpdySerializedFrame cross_origin_push(spdy_util_.ConstructSpdyPush(
      nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(cross_origin_push, 2),
      MockRead(ASYNC, 0, 4),
  };

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(rst, 3),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  EXPECT_EQ(0u, spdy_stream->stream_id());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kNonHttpsPushedScheme), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

TEST_F(SpdySessionTest, IgnoreReservedRemoteStreamsCount) {
  base::HistogramTester histogram_tester;

  spdy::SpdySerializedFrame push_a(
      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kPushedUrl));
  spdy::SpdyHeaderBlock push_headers;
  push_headers[":method"] = "GET";
  spdy_util_.AddUrlToHeaderBlock("https://www.example.org/b.dat",
                                 &push_headers);
  spdy::SpdySerializedFrame push_b(
      spdy_util_.ConstructSpdyPushPromise(1, 4, std::move(push_headers)));
  spdy::SpdySerializedFrame headers_b(
      spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1),  CreateMockRead(push_a, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 4),  CreateMockRead(push_b, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 7),  CreateMockRead(headers_b, 8),
      MockRead(ASYNC, ERR_IO_PENDING, 10), MockRead(ASYNC, 0, 11),
  };

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority_a(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame priority_b(
      spdy_util_.ConstructSpdyPriority(4, 2, IDLE, true));
  spdy::SpdySerializedFrame rst_b(
      spdy_util_.ConstructSpdyRstStream(4, spdy::ERROR_CODE_REFUSED_STREAM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(priority_a, 3),
      CreateMockWrite(priority_b, 6), CreateMockWrite(rst_b, 9),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();
  set_max_concurrent_pushed_streams(1);

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Run until pushed stream is created.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Accept promised stream. It should not count towards pushed stream limit.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(3u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(2u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Reset last pushed stream upon headers reception as it is going to be 2nd,
  // while we accept only one.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(1u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(session_);

  histogram_tester.ExpectBucketCount(
      "Net.SpdyPushedStreamFate",
      static_cast<int>(SpdyPushedStreamFate::kTooManyPushedStreams), 1);
  histogram_tester.ExpectTotalCount("Net.SpdyPushedStreamFate", 1);
}

TEST_F(SpdySessionTest, CancelReservedStreamOnHeadersReceived) {
  spdy::SpdyHeaderBlock push_headers;
  push_headers[":method"] = "GET";
  spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_headers);
  spdy::SpdySerializedFrame push_promise(
      spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
  spdy::SpdySerializedFrame headers_frame(
      spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_promise, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(headers_frame, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8),
  };

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  MockWrite writes[] = {
      CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
      CreateMockWrite(rst, 6),
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Run until 1st stream is activated.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  // Run until pushed stream is created.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());

  // Claim pushed stream from Http2PushPromiseIndex.
  const GURL pushed_url(kPushedUrl);
  HttpRequestInfo push_request;
  push_request.url = pushed_url;
  push_request.method = "GET";
  base::WeakPtr<SpdySession> session_with_pushed_stream;
  spdy::SpdyStreamId pushed_stream_id;
  spdy_session_pool_->push_promise_index()->ClaimPushedStream(
      key_, pushed_url, push_request, &session_with_pushed_stream,
      &pushed_stream_id);
  EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
  EXPECT_EQ(2u, pushed_stream_id);
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  SpdyStream* pushed_stream;
  int rv = session_->GetPushedStream(pushed_url, pushed_stream_id, IDLE,
                                     &pushed_stream);
  ASSERT_THAT(rv, IsOk());
  ASSERT_TRUE(pushed_stream);
  test::StreamDelegateCloseOnHeaders delegate2(pushed_stream->GetWeakPtr());
  pushed_stream->SetDelegate(&delegate2);

  // Receive headers for pushed stream. Delegate will cancel the stream, ensure
  // that all our counters are in consistent state.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

TEST_F(SpdySessionTest, GetPushedStream) {
  spdy::SpdyHeaderBlock push_headers;
  push_headers[":method"] = "GET";
  spdy_util_.AddUrlToHeaderBlock(kPushedUrl, &push_headers);
  spdy::SpdySerializedFrame push_promise(
      spdy_util_.ConstructSpdyPushPromise(1, 2, std::move(push_headers)));
  spdy::SpdySerializedFrame headers_frame(
      spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(push_promise, 2),
      MockRead(ASYNC, ERR_IO_PENDING, 4), CreateMockRead(headers_frame, 5),
      MockRead(ASYNC, ERR_IO_PENDING, 7), MockRead(ASYNC, 0, 8)};

  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
  spdy::SpdySerializedFrame priority(
      spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_CANCEL));
  MockWrite writes[] = {CreateMockWrite(req, 0), CreateMockWrite(priority, 3),
                        CreateMockWrite(rst, 6)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, LOWEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream1);
  EXPECT_EQ(0u, spdy_stream1->stream_id());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  EXPECT_EQ(0u, num_active_streams());
  EXPECT_EQ(1u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  // Activate first request.
  EXPECT_EQ(0u, delegate1.stream_id());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, delegate1.stream_id());
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // No streams are pushed yet, therefore GetPushedStream() should return an
  // error.
  const GURL pushed_url(kPushedUrl);
  SpdyStream* pushed_stream;
  int rv = session_->GetPushedStream(pushed_url, 2 /* pushed_stream_id */, IDLE,
                                     &pushed_stream);
  EXPECT_THAT(rv, IsError(ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE));

  // Read PUSH_PROMISE.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(1u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());
  EXPECT_EQ(1u, num_unclaimed_pushed_streams());

  // Claim pushed stream from Http2PushPromiseIndex so that GetPushedStream()
  // can be called.
  HttpRequestInfo push_request;
  push_request.url = pushed_url;
  push_request.method = "GET";
  base::WeakPtr<SpdySession> session_with_pushed_stream;
  spdy::SpdyStreamId pushed_stream_id;
  spdy_session_pool_->push_promise_index()->ClaimPushedStream(
      key_, pushed_url, push_request, &session_with_pushed_stream,
      &pushed_stream_id);
  EXPECT_EQ(session_.get(), session_with_pushed_stream.get());
  EXPECT_EQ(2u, pushed_stream_id);

  // Verify that pushed stream is claimed.
  EXPECT_EQ(0u, num_unclaimed_pushed_streams());

  // GetPushedStream() should return an error if there does not exist a pushed
  // stream with ID |pushed_stream_id|.
  rv = session_->GetPushedStream(pushed_url, 4 /* pushed_stream_id */, IDLE,
                                 &pushed_stream);
  EXPECT_THAT(rv, IsError(ERR_SPDY_PUSHED_STREAM_NOT_AVAILABLE));

  // GetPushedStream() should return OK and return the pushed stream in
  // |pushed_stream| outparam if |pushed_stream_id| matches.
  rv = session_->GetPushedStream(pushed_url, 2 /* pushed_stream_id */, IDLE,
                                 &pushed_stream);
  EXPECT_THAT(rv, IsOk());
  ASSERT_TRUE(pushed_stream);
  test::StreamDelegateCloseOnHeaders delegate2(pushed_stream->GetWeakPtr());
  pushed_stream->SetDelegate(&delegate2);

  // Upon reading pushed headers, delegate closes the stream.
  data.Resume();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, num_active_streams());
  EXPECT_EQ(0u, num_created_streams());
  EXPECT_EQ(0u, num_pushed_streams());
  EXPECT_EQ(0u, num_active_pushed_streams());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(delegate1.StreamIsClosed());
  EXPECT_TRUE(delegate2.StreamIsClosed());

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

TEST_F(SpdySessionTest, RejectInvalidUnknownFrames) {
  MockRead reads[] = {
      MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
  };

  StaticSocketDataProvider data(reads, base::span<MockWrite>());
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  set_stream_hi_water_mark(5);
  // Low client (odd) ids are fine.
  EXPECT_TRUE(OnUnknownFrame(3, 0));
  // Client id exceeding watermark.
  EXPECT_FALSE(OnUnknownFrame(9, 0));

  set_last_accepted_push_stream_id(6);
  // Low server (even) ids are fine.
  EXPECT_TRUE(OnUnknownFrame(2, 0));
  // Server id exceeding last accepted id.
  EXPECT_FALSE(OnUnknownFrame(8, 0));
}

TEST_F(SpdySessionTest, EnableWebSocket) {
  spdy::SettingsMap settings_map;
  settings_map[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  spdy::SpdySerializedFrame settings(
      spdy_util_.ConstructSpdySettings(settings_map));
  MockRead reads[] = {CreateMockRead(settings, 0),
                      MockRead(ASYNC, ERR_IO_PENDING, 2),
                      MockRead(ASYNC, 0, 3)};

  spdy::SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck());
  MockWrite writes[] = {CreateMockWrite(ack, 1)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_FALSE(session_->support_websocket());

  // Read SETTINGS frame.
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(session_->support_websocket());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, DisableWebSocketDoesNothing) {
  spdy::SettingsMap settings_map;
  settings_map[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0;
  spdy::SpdySerializedFrame settings(
      spdy_util_.ConstructSpdySettings(settings_map));
  MockRead reads[] = {CreateMockRead(settings, 0),
                      MockRead(ASYNC, ERR_IO_PENDING, 2),
                      MockRead(ASYNC, 0, 3)};

  spdy::SpdySerializedFrame ack(spdy_util_.ConstructSpdySettingsAck());
  MockWrite writes[] = {CreateMockWrite(ack, 1)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_FALSE(session_->support_websocket());

  // Read SETTINGS frame.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(session_->support_websocket());

  // Read EOF.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, EnableWebSocketThenDisableIsProtocolError) {
  spdy::SettingsMap settings_map1;
  settings_map1[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 1;
  spdy::SpdySerializedFrame settings1(
      spdy_util_.ConstructSpdySettings(settings_map1));
  spdy::SettingsMap settings_map2;
  settings_map2[spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL] = 0;
  spdy::SpdySerializedFrame settings2(
      spdy_util_.ConstructSpdySettings(settings_map2));
  MockRead reads[] = {CreateMockRead(settings1, 0),
                      MockRead(ASYNC, ERR_IO_PENDING, 2),
                      CreateMockRead(settings2, 3)};

  spdy::SpdySerializedFrame ack1(spdy_util_.ConstructSpdySettingsAck());
  spdy::SpdySerializedFrame ack2(spdy_util_.ConstructSpdySettingsAck());
  spdy::SpdySerializedFrame goaway(spdy_util_.ConstructSpdyGoAway(
      0, spdy::ERROR_CODE_PROTOCOL_ERROR,
      "Invalid value for spdy::SETTINGS_ENABLE_CONNECT_PROTOCOL."));
  MockWrite writes[] = {CreateMockWrite(ack1, 1), CreateMockWrite(ack2, 4),
                        CreateMockWrite(goaway, 5)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  EXPECT_FALSE(session_->support_websocket());

  // Read first SETTINGS frame.
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(session_->support_websocket());

  // Read second SETTINGS frame.
  data.Resume();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
  EXPECT_FALSE(session_);
}

TEST_F(SpdySessionTest, GreaseFrameType) {
  const uint8_t type = 0x0b;
  const uint8_t flags = 0xcc;
  const std::string payload("foo");
  session_deps_.greased_http2_frame =
      base::Optional<net::SpdySessionPool::GreasedHttp2Frame>(
          {type, flags, payload});

  // Connection preface.
  spdy::SpdySerializedFrame preface(
      const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
      spdy::kHttp2ConnectionHeaderPrefixSize,
      /* owns_buffer = */ false);

  // Initial SETTINGS frame.
  spdy::SettingsMap expected_settings;
  expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
      kSpdyMaxConcurrentPushedStreams;
  spdy::SpdySerializedFrame settings_frame(
      spdy_util_.ConstructSpdySettings(expected_settings));

  spdy::SpdySerializedFrame combined_frame =
      CombineFrames({&preface, &settings_frame});

  // Greased frame sent on stream 0 after initial SETTINGS frame.
  const char kRawFrameData0[] = {
      0x00, 0x00, 0x03,        // length
      0x0b,                    // type
      0xcc,                    // flags
      0x00, 0x00, 0x00, 0x00,  // stream ID
      'f',  'o',  'o'          // payload
  };
  spdy::SpdySerializedFrame grease0(const_cast<char*>(kRawFrameData0),
                                    base::size(kRawFrameData0),
                                    /* owns_buffer = */ false);
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY));

  // Greased frame sent on stream 1 after request.
  const char kRawFrameData1[] = {
      0x00, 0x00, 0x03,        // length
      0x0b,                    // type
      0xcc,                    // flags
      0x00, 0x00, 0x00, 0x01,  // stream ID
      'f',  'o',  'o'          // payload
  };
  spdy::SpdySerializedFrame grease1(const_cast<char*>(kRawFrameData1),
                                    base::size(kRawFrameData1),
                                    /* owns_buffer = */ false);

  MockWrite writes[] = {CreateMockWrite(combined_frame, 0),
                        CreateMockWrite(grease0, 1), CreateMockWrite(req, 2),
                        CreateMockWrite(grease1, 3)};

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));

  MockRead reads[] = {CreateMockRead(resp, 4), CreateMockRead(body, 5),
                      MockRead(ASYNC, 0, 6)};

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);
  AddSSLSocketData();

  CreateNetworkSession();

  SpdySessionPoolPeer pool_peer(spdy_session_pool_);
  pool_peer.SetEnableSendingInitialData(true);

  CreateSpdySession();

  base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously(
      SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY,
      NetLogWithSource());
  test::StreamDelegateDoNothing delegate(stream);
  stream->SetDelegate(&delegate);

  stream->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl),
                             NO_MORE_DATA_TO_SEND);

  EXPECT_THAT(delegate.WaitForClose(), IsOk());

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(data.AllWriteDataConsumed());
  EXPECT_TRUE(data.AllReadDataConsumed());
}

enum ReadIfReadySupport {
  // ReadIfReady() field trial is enabled, and ReadIfReady() is implemented.
  READ_IF_READY_ENABLED_SUPPORTED,
  // ReadIfReady() field trial is enabled, but ReadIfReady() is unimplemented.
  READ_IF_READY_ENABLED_NOT_SUPPORTED,
  // ReadIfReady() field trial is disabled.
  READ_IF_READY_DISABLED,
};

class SpdySessionReadIfReadyTest
    : public SpdySessionTest,
      public testing::WithParamInterface<ReadIfReadySupport> {
 public:
  void SetUp() override {
    if (GetParam() == READ_IF_READY_DISABLED) {
      scoped_feature_list_.InitAndDisableFeature(
          Socket::kReadIfReadyExperiment);
    } else if (GetParam() == READ_IF_READY_ENABLED_SUPPORTED) {
      session_deps_.socket_factory->set_enable_read_if_ready(true);
    }
    SpdySessionTest::SetUp();
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

INSTANTIATE_TEST_CASE_P(/* no prefix */,
                        SpdySessionReadIfReadyTest,
                        testing::Values(READ_IF_READY_ENABLED_SUPPORTED,
                                        READ_IF_READY_ENABLED_NOT_SUPPORTED,
                                        READ_IF_READY_DISABLED));

// Tests basic functionality of ReadIfReady() when it is enabled or disabled.
TEST_P(SpdySessionReadIfReadyTest, ReadIfReady) {
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };

  spdy::SpdySerializedFrame resp(
      spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
  spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
  MockRead reads[] = {
      CreateMockRead(resp, 1), CreateMockRead(body, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };

  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream =
      CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, session_,
                                test_url_, HIGHEST, NetLogWithSource());
  ASSERT_TRUE(spdy_stream);
  EXPECT_EQ(0u, spdy_stream->stream_id());
  test::StreamDelegateDoNothing delegate(spdy_stream);
  spdy_stream->SetDelegate(&delegate);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
  spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(spdy_stream);
  EXPECT_EQ(1u, delegate.stream_id());
}

class SendInitialSettingsOnNewSpdySessionTest : public SpdySessionTest {
 protected:
  void RunInitialSettingsTest(const spdy::SettingsMap expected_settings) {
    MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING)};

    spdy::SpdySerializedFrame preface(
        const_cast<char*>(spdy::kHttp2ConnectionHeaderPrefix),
        spdy::kHttp2ConnectionHeaderPrefixSize,
        /* owns_buffer = */ false);
    spdy::SpdySerializedFrame settings_frame(
        spdy_util_.ConstructSpdySettings(expected_settings));

    spdy::SpdySerializedFrame combined_frame =
        CombineFrames({&preface, &settings_frame});
    MockWrite writes[] = {CreateMockWrite(combined_frame, 0)};

    StaticSocketDataProvider data(reads, writes);
    session_deps_.socket_factory->AddSocketDataProvider(&data);
    AddSSLSocketData();

    CreateNetworkSession();

    SpdySessionPoolPeer pool_peer(spdy_session_pool_);
    pool_peer.SetEnableSendingInitialData(true);

    CreateSpdySession();

    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(data.AllWriteDataConsumed());
  }
};

// Setting values when Params::http2_settings is empty.  Note that
// spdy::SETTINGS_INITIAL_WINDOW_SIZE is sent in production, because it is set
// to a non-default value, but it is not sent in tests, because the protocol
// default value is used in tests.
TEST_F(SendInitialSettingsOnNewSpdySessionTest, Empty) {
  spdy::SettingsMap expected_settings;
  expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
      kSpdyMaxConcurrentPushedStreams;
  RunInitialSettingsTest(expected_settings);
}

// When a setting is set to the protocol default value,
// no corresponding value is sent on the wire.
TEST_F(SendInitialSettingsOnNewSpdySessionTest, ProtocolDefault) {
  // Explicitly set protocol default values for the following settings.
  session_deps_.http2_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 4096;
  session_deps_.http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 1;
  session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
      64 * 1024 - 1;

  spdy::SettingsMap expected_settings;
  expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
      kSpdyMaxConcurrentPushedStreams;
  RunInitialSettingsTest(expected_settings);
}

// Values set in Params::http2_settings overwrite Chromium's default values.
TEST_F(SendInitialSettingsOnNewSpdySessionTest, OverwriteValues) {
  session_deps_.http2_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 16 * 1024;
  session_deps_.http2_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
  session_deps_.http2_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 42;
  session_deps_.http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 32 * 1024;
  session_deps_.http2_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
      101 * 1024;

  spdy::SettingsMap expected_settings;
  expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = 16 * 1024;
  expected_settings[spdy::SETTINGS_ENABLE_PUSH] = 0;
  expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] = 42;
  expected_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] = 32 * 1024;
  expected_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] = 101 * 1024;
  RunInitialSettingsTest(expected_settings);
}

// Unknown parameters should still be sent to the server.
TEST_F(SendInitialSettingsOnNewSpdySessionTest, UnknownSettings) {
  // The following parameters are not defined in the HTTP/2 specification.
  session_deps_.http2_settings[7] = 1234;
  session_deps_.http2_settings[25] = 5678;

  spdy::SettingsMap expected_settings;
  expected_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  expected_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
      kSpdyMaxConcurrentPushedStreams;
  expected_settings[7] = 1234;
  expected_settings[25] = 5678;
  RunInitialSettingsTest(expected_settings);
}

class AltSvcFrameTest : public SpdySessionTest {
 public:
  AltSvcFrameTest()
      : alternative_service_("quic",
                             "alternative.example.org",
                             443,
                             86400,
                             spdy::SpdyAltSvcWireFormat::VersionVector()) {}

  void AddSocketData(const spdy::SpdyAltSvcIR& altsvc_ir) {
    altsvc_frame_ = spdy_util_.SerializeFrame(altsvc_ir);
    reads_.push_back(CreateMockRead(altsvc_frame_, 0));
    reads_.push_back(MockRead(ASYNC, 0, 1));

    data_ =
        std::make_unique<SequencedSocketData>(reads_, base::span<MockWrite>());
    session_deps_.socket_factory->AddSocketDataProvider(data_.get());
  }

  void CreateSpdySession() {
    session_ =
        ::net::CreateSpdySession(http_session_.get(), key_, NetLogWithSource());
  }

  spdy::SpdyAltSvcWireFormat::AlternativeService alternative_service_;

 private:
  spdy::SpdySerializedFrame altsvc_frame_;
  std::vector<MockRead> reads_;
  std::unique_ptr<SequencedSocketData> data_;
};

TEST_F(AltSvcFrameTest, ProcessAltSvcFrame) {
  const char origin[] = "https://mail.example.org";
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
  altsvc_ir.add_altsvc(alternative_service_);
  altsvc_ir.set_origin(origin);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  AlternativeServiceInfoVector altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          session_origin);
  ASSERT_TRUE(altsvc_info_vector.empty());

  altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          url::SchemeHostPort(GURL(origin)));
  ASSERT_EQ(1u, altsvc_info_vector.size());
  AlternativeService alternative_service(kProtoQUIC, "alternative.example.org",
                                         443u);
  EXPECT_EQ(alternative_service, altsvc_info_vector[0].alternative_service());
}

// Regression test for https://crbug.com/736063.
TEST_F(AltSvcFrameTest, IgnoreQuicAltSvcWithUnsupportedVersion) {
  const char origin[] = "https://mail.example.org";
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
  spdy::SpdyAltSvcWireFormat::AlternativeService quic_alternative_service(
      "quic", "alternative.example.org", 443, 86400,
      spdy::SpdyAltSvcWireFormat::VersionVector());
  // TODO(zhongyi): spdy::SpdyAltSvcWireFormat::ParseHeaderFieldValue expects
  // positve versions while VersionVector allows nonnegative verisons. Fix the
  // parse function and change the hardcoded invalid version to
  // quic::QUIC_VERSION_UNSUPPORTED.
  quic_alternative_service.version.push_back(/* invalid QUIC version */ 1);
  altsvc_ir.add_altsvc(quic_alternative_service);
  altsvc_ir.set_origin(origin);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  AlternativeServiceInfoVector altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          session_origin);
  ASSERT_TRUE(altsvc_info_vector.empty());

  altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          url::SchemeHostPort(GURL(origin)));
  ASSERT_EQ(0u, altsvc_info_vector.size());
}

TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameForOriginNotCoveredByCert) {
  const char origin[] = "https://invalid.example.org";
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
  altsvc_ir.add_altsvc(alternative_service_);
  altsvc_ir.set_origin(origin);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());

  ASSERT_TRUE(
      spdy_session_pool_->http_server_properties()
          ->GetAlternativeServiceInfos(url::SchemeHostPort(GURL(origin)))
          .empty());
}

// An ALTSVC frame on stream 0 with empty origin MUST be ignored.
// (RFC 7838 Section 4)
TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameWithEmptyOriginOnStreamZero) {
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
  altsvc_ir.add_altsvc(alternative_service_);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());
}

// An ALTSVC frame on a stream other than stream 0 with non-empty origin MUST be
// ignored.  (RFC 7838 Section 4)
TEST_F(AltSvcFrameTest,
       DoNotProcessAltSvcFrameWithNonEmptyOriginOnNonZeroStream) {
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
  altsvc_ir.add_altsvc(alternative_service_);
  altsvc_ir.set_origin("https://mail.example.org");
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());
}

TEST_F(AltSvcFrameTest, ProcessAltSvcFrameOnActiveStream) {
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
  altsvc_ir.add_altsvc(alternative_service_);

  spdy::SpdySerializedFrame altsvc_frame(spdy_util_.SerializeFrame(altsvc_ir));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
  MockRead reads[] = {
      CreateMockRead(altsvc_frame, 1), CreateMockRead(rst, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };

  const char request_origin[] = "https://mail.example.org";
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(request_origin, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
      SPDY_REQUEST_RESPONSE_STREAM, session_, GURL(request_origin), MEDIUM,
      NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(request_origin));

  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());

  AlternativeServiceInfoVector altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          url::SchemeHostPort(GURL(request_origin)));
  ASSERT_EQ(1u, altsvc_info_vector.size());
  EXPECT_EQ(kProtoQUIC, altsvc_info_vector[0].alternative_service().protocol);
  EXPECT_EQ("alternative.example.org",
            altsvc_info_vector[0].alternative_service().host);
  EXPECT_EQ(443u, altsvc_info_vector[0].alternative_service().port);
}

TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnStreamWithInsecureOrigin) {
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
  altsvc_ir.add_altsvc(alternative_service_);

  spdy::SpdySerializedFrame altsvc_frame(spdy_util_.SerializeFrame(altsvc_ir));
  spdy::SpdySerializedFrame rst(
      spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_REFUSED_STREAM));
  MockRead reads[] = {
      CreateMockRead(altsvc_frame, 1), CreateMockRead(rst, 2),
      MockRead(ASYNC, 0, 3)  // EOF
  };

  const char request_origin[] = "http://mail.example.org";
  spdy::SpdySerializedFrame req(
      spdy_util_.ConstructSpdyGet(request_origin, 1, MEDIUM));
  MockWrite writes[] = {
      CreateMockWrite(req, 0),
  };
  SequencedSocketData data(reads, writes);
  session_deps_.socket_factory->AddSocketDataProvider(&data);

  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::WeakPtr<SpdyStream> spdy_stream1 = CreateStreamSynchronously(
      SPDY_REQUEST_RESPONSE_STREAM, session_, GURL(request_origin), MEDIUM,
      NetLogWithSource());
  test::StreamDelegateDoNothing delegate1(spdy_stream1);
  spdy_stream1->SetDelegate(&delegate1);

  spdy::SpdyHeaderBlock headers(
      spdy_util_.ConstructGetHeaderBlock(request_origin));

  spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND);

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());

  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(
                      url::SchemeHostPort(GURL(request_origin)))
                  .empty());
}

TEST_F(AltSvcFrameTest, DoNotProcessAltSvcFrameOnNonExistentStream) {
  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 1);
  altsvc_ir.add_altsvc(alternative_service_);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  ASSERT_TRUE(spdy_session_pool_->http_server_properties()
                  ->GetAlternativeServiceInfos(session_origin)
                  .empty());
}

// Regression test for https://crbug.com/810404.
TEST_F(AltSvcFrameTest, InvalidOrigin) {
  // This origin parses to an invalid GURL with https scheme.
  const std::string origin("https:?");
  const GURL origin_gurl(origin);
  EXPECT_FALSE(origin_gurl.is_valid());
  EXPECT_TRUE(origin_gurl.host().empty());
  EXPECT_TRUE(origin_gurl.SchemeIs(url::kHttpsScheme));

  spdy::SpdyAltSvcIR altsvc_ir(/* stream_id = */ 0);
  altsvc_ir.add_altsvc(alternative_service_);
  altsvc_ir.set_origin(origin);
  AddSocketData(altsvc_ir);
  AddSSLSocketData();

  CreateNetworkSession();
  CreateSpdySession();

  base::RunLoop().RunUntilIdle();

  const url::SchemeHostPort session_origin("https", test_url_.host(),
                                           test_url_.EffectiveIntPort());
  AlternativeServiceInfoVector altsvc_info_vector =
      spdy_session_pool_->http_server_properties()->GetAlternativeServiceInfos(
          session_origin);
  EXPECT_TRUE(altsvc_info_vector.empty());
}

TEST(MapFramerErrorToProtocolError, MapsValues) {
  CHECK_EQ(SPDY_ERROR_INVALID_CONTROL_FRAME,
           MapFramerErrorToProtocolError(
               http2::Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
  CHECK_EQ(SPDY_ERROR_INVALID_DATA_FRAME_FLAGS,
           MapFramerErrorToProtocolError(
               http2::Http2DecoderAdapter::SPDY_INVALID_DATA_FRAME_FLAGS));
  CHECK_EQ(SPDY_ERROR_GOAWAY_FRAME_CORRUPT,
           MapFramerErrorToProtocolError(
               http2::Http2DecoderAdapter::SPDY_GOAWAY_FRAME_CORRUPT));
  CHECK_EQ(SPDY_ERROR_UNEXPECTED_FRAME,
           MapFramerErrorToProtocolError(
               http2::Http2DecoderAdapter::SPDY_UNEXPECTED_FRAME));
}

TEST(MapFramerErrorToNetError, MapsValue) {
  CHECK_EQ(ERR_SPDY_PROTOCOL_ERROR,
           MapFramerErrorToNetError(
               http2::Http2DecoderAdapter::SPDY_INVALID_CONTROL_FRAME));
  CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
           MapFramerErrorToNetError(
               http2::Http2DecoderAdapter::SPDY_COMPRESS_FAILURE));
  CHECK_EQ(ERR_SPDY_COMPRESSION_ERROR,
           MapFramerErrorToNetError(
               http2::Http2DecoderAdapter::SPDY_DECOMPRESS_FAILURE));
  CHECK_EQ(ERR_SPDY_FRAME_SIZE_ERROR,
           MapFramerErrorToNetError(
               http2::Http2DecoderAdapter::SPDY_CONTROL_PAYLOAD_TOO_LARGE));
  CHECK_EQ(ERR_SPDY_FRAME_SIZE_ERROR,
           MapFramerErrorToNetError(
               http2::Http2DecoderAdapter::SPDY_OVERSIZED_PAYLOAD));
}

TEST(MapRstStreamStatusToProtocolError, MapsValues) {
  CHECK_EQ(STATUS_CODE_PROTOCOL_ERROR,
           MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_PROTOCOL_ERROR));
  CHECK_EQ(
      STATUS_CODE_FRAME_SIZE_ERROR,
      MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_FRAME_SIZE_ERROR));
  CHECK_EQ(
      STATUS_CODE_ENHANCE_YOUR_CALM,
      MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_ENHANCE_YOUR_CALM));
  CHECK_EQ(
      STATUS_CODE_INADEQUATE_SECURITY,
      MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_INADEQUATE_SECURITY));
  CHECK_EQ(
      STATUS_CODE_HTTP_1_1_REQUIRED,
      MapRstStreamStatusToProtocolError(spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
}

TEST(MapNetErrorToGoAwayStatus, MapsValue) {
  CHECK_EQ(spdy::ERROR_CODE_INADEQUATE_SECURITY,
           MapNetErrorToGoAwayStatus(ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY));
  CHECK_EQ(spdy::ERROR_CODE_FLOW_CONTROL_ERROR,
           MapNetErrorToGoAwayStatus(ERR_SPDY_FLOW_CONTROL_ERROR));
  CHECK_EQ(spdy::ERROR_CODE_PROTOCOL_ERROR,
           MapNetErrorToGoAwayStatus(ERR_SPDY_PROTOCOL_ERROR));
  CHECK_EQ(spdy::ERROR_CODE_COMPRESSION_ERROR,
           MapNetErrorToGoAwayStatus(ERR_SPDY_COMPRESSION_ERROR));
  CHECK_EQ(spdy::ERROR_CODE_FRAME_SIZE_ERROR,
           MapNetErrorToGoAwayStatus(ERR_SPDY_FRAME_SIZE_ERROR));
  CHECK_EQ(spdy::ERROR_CODE_PROTOCOL_ERROR,
           MapNetErrorToGoAwayStatus(ERR_UNEXPECTED));
}

namespace {

class TestSSLConfigService : public SSLConfigService {
 public:
  TestSSLConfigService() {}
  ~TestSSLConfigService() override = default;

  void GetSSLConfig(SSLConfig* config) override { *config = config_; }

  // Returns true if |hostname| is in domains_for_pooling_. This is a simpler
  // implementation than the production implementation in SSLConfigServiceMojo.
  bool CanShareConnectionWithClientCerts(
      const std::string& hostname) const override {
    for (const std::string& domain : domains_for_pooling_) {
      if (domain == hostname) {
        return true;
      }
    }
    return false;
  }

  void SetDomainsForPooling(const std::vector<std::string>& domains) {
    domains_for_pooling_ = domains;
  }

 private:
  SSLConfig config_;
  std::vector<std::string> domains_for_pooling_;
};

}  // namespace

TEST(CanPoolTest, CanPool) {
  // Load a cert that is valid for:
  //   www.example.org
  //   mail.example.org
  //   mail.example.com

  TransportSecurityState tss;
  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "www.example.org"));
  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.com"));
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.google.com"));
}

TEST(CanPoolTest, CanPoolExpectCT) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(
      TransportSecurityState::kDynamicExpectCTFeature);
  // Load a cert that is valid for:
  //   www.example.org
  //   mail.example.org
  //   mail.example.com

  TransportSecurityState tss;
  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert =
      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  ssl_info.unverified_cert = ssl_info.cert;
  ssl_info.ct_policy_compliance =
      ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;
  ssl_info.is_issued_by_known_root = true;

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "www.example.org"));

  const base::Time current_time(base::Time::Now());
  const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000);
  ssl_info.ct_policy_compliance =
      ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;

  // A different Expect-CT enabled host should not be allowed to pool.
  tss.AddExpectCT("mail.example.org", expiry, true, GURL());
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.org"));
  // A report-only Expect-CT configuration should not prevent pooling.
  tss.AddExpectCT("mail.example.org", expiry, false,
                  GURL("https://report.test"));
  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
  // If Expect-CT becomes enabled for the same host for which the connection was
  // already made, subsequent connections to that host should not be allowed to
  // pool.
  tss.AddExpectCT("www.example.org", expiry, true, GURL());
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "www.example.org"));
}

TEST(CanPoolTest, CanNotPoolWithCertErrors) {
  // Load a cert that is valid for:
  //   www.example.org
  //   mail.example.org
  //   mail.example.com

  TransportSecurityState tss;
  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");
  ssl_info.cert_status = CERT_STATUS_REVOKED;

  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanNotPoolWithClientCerts) {
  // Load a cert that is valid for:
  //   www.example.org
  //   mail.example.org
  //   mail.example.com

  TransportSecurityState tss;
  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");
  ssl_info.client_cert_sent = true;

  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanNotPoolAcrossETLDsWithChannelID) {
  // Load a cert that is valid for:
  //   www.example.org
  //   mail.example.org
  //   mail.example.com

  TransportSecurityState tss;
  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");
  ssl_info.channel_id_sent = true;

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "www.example.com"));
}

TEST(CanPoolTest, CanNotPoolWithBadPins) {
  uint8_t primary_pin = 1;
  uint8_t backup_pin = 2;
  uint8_t bad_pin = 3;
  TransportSecurityState tss;
  test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);

  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");
  ssl_info.is_issued_by_known_root = true;
  ssl_info.public_key_hashes.push_back(test::GetTestHashValue(bad_pin));

  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanNotPoolWithBadCTWhenCTRequired) {
  using testing::Return;
  using CTRequirementLevel =
      TransportSecurityState::RequireCTDelegate::CTRequirementLevel;

  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert =
      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  ssl_info.is_issued_by_known_root = true;
  ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
  ssl_info.ct_policy_compliance =
      ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;

  MockRequireCTDelegate require_ct_delegate;
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate,
              IsCTRequiredForHost("mail.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));

  TransportSecurityState tss;
  tss.SetRequireCTDelegate(&require_ct_delegate);

  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanPoolWithBadCTWhenCTNotRequired) {
  using testing::Return;
  using CTRequirementLevel =
      TransportSecurityState::RequireCTDelegate::CTRequirementLevel;

  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert =
      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  ssl_info.is_issued_by_known_root = true;
  ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
  ssl_info.ct_policy_compliance =
      ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS;

  MockRequireCTDelegate require_ct_delegate;
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate,
              IsCTRequiredForHost("mail.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));

  TransportSecurityState tss;
  tss.SetRequireCTDelegate(&require_ct_delegate);

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanPoolWithGoodCTWhenCTRequired) {
  using testing::Return;
  using CTRequirementLevel =
      TransportSecurityState::RequireCTDelegate::CTRequirementLevel;

  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert =
      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  ssl_info.is_issued_by_known_root = true;
  ssl_info.public_key_hashes.push_back(test::GetTestHashValue(1));
  ssl_info.ct_policy_compliance =
      ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS;

  MockRequireCTDelegate require_ct_delegate;
  EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost("www.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::NOT_REQUIRED));
  EXPECT_CALL(require_ct_delegate,
              IsCTRequiredForHost("mail.example.org", _, _))
      .WillRepeatedly(Return(CTRequirementLevel::REQUIRED));

  TransportSecurityState tss;
  tss.SetRequireCTDelegate(&require_ct_delegate);

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanPoolWithAcceptablePins) {
  uint8_t primary_pin = 1;
  uint8_t backup_pin = 2;
  TransportSecurityState tss;
  test::AddPin(&tss, "mail.example.org", primary_pin, backup_pin);

  TestSSLConfigService ssl_config_service;
  SSLInfo ssl_info;
  ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
                                     "spdy_pooling.pem");
  ssl_info.is_issued_by_known_root = true;
  ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin));

  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
}

TEST(CanPoolTest, CanPoolWithClientCertsAndPolicy) {
  TransportSecurityState tss;
  SSLInfo ssl_info;
  ssl_info.cert =
      ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
  ssl_info.client_cert_sent = true;

  // Configure ssl_config_service so that CanShareConnectionWithClientCerts
  // returns true for www.example.org and mail.example.org.
  TestSSLConfigService ssl_config_service;
  ssl_config_service.SetDomainsForPooling(
      {"www.example.org", "mail.example.org"});

  // Test that CanPool returns true when client certs are enabled and
  // CanShareConnectionWithClientCerts returns true for both hostnames, but not
  // just one hostname.
  EXPECT_TRUE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                   "www.example.org", "mail.example.org"));
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "www.example.org", "mail.example.com"));
  EXPECT_FALSE(SpdySession::CanPool(&tss, ssl_info, ssl_config_service,
                                    "mail.example.com", "www.example.org"));
}

TEST(RecordPushedStreamHistogramTest, VaryResponseHeader) {
  struct {
    size_t num_headers;
    const char* headers[2];
    int expected_bucket;
  } test_cases[] = {{0, {}, 0},
                    {1, {"foo", "bar"}, 0},
                    {1, {"vary", ""}, 1},
                    {1, {"vary", "*"}, 2},
                    {1, {"vary", "accept-encoding"}, 3},
                    {1, {"vary", "foo , accept-encoding ,bar"}, 4},
                    {1, {"vary", "\taccept-encoding, foo"}, 4},
                    {1, {"vary", "foo"}, 5},
                    {1, {"vary", "fooaccept-encoding"}, 5},
                    {1, {"vary", "foo, accept-encodingbar"}, 5}};

  for (size_t i = 0; i < arraysize(test_cases); ++i) {
    spdy::SpdyHeaderBlock headers;
    for (size_t j = 0; j < test_cases[i].num_headers; ++j) {
      headers[test_cases[i].headers[2 * j]] = test_cases[i].headers[2 * j + 1];
    }
    base::HistogramTester histograms;
    histograms.ExpectTotalCount("Net.PushedStreamVaryResponseHeader", 0);
    SpdySession::RecordPushedStreamVaryResponseHeaderHistogram(headers);
    histograms.ExpectTotalCount("Net.PushedStreamVaryResponseHeader", 1);
    histograms.ExpectBucketCount("Net.PushedStreamVaryResponseHeader",
                                 test_cases[i].expected_bucket, 1);
    // Adding an unrelated header field should not change how Vary is parsed.
    headers["foo"] = "bar";
    SpdySession::RecordPushedStreamVaryResponseHeaderHistogram(headers);
    histograms.ExpectTotalCount("Net.PushedStreamVaryResponseHeader", 2);
    histograms.ExpectBucketCount("Net.PushedStreamVaryResponseHeader",
                                 test_cases[i].expected_bucket, 2);
  }
}

}  // namespace net
