// Copyright (c) 2018 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/third_party/quiche/src/quic/core/quic_stream_id_manager.h"

#include <cstdint>
#include <set>
#include <utility>

#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_session.h"
#include "net/third_party/quiche/src/quic/core/quic_stream.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_map_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test_mem_slice_vector.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"

using testing::_;
using testing::Invoke;
using testing::Return;
using testing::StrictMock;

namespace quic {
namespace test {
namespace {

class TestQuicStream : public QuicStream {
  // TestQuicStream exists simply as a place to hang OnDataAvailable().
 public:
  TestQuicStream(QuicStreamId id, QuicSession* session, StreamType type)
      : QuicStream(id, session, /*is_static=*/false, type) {}

  void OnDataAvailable() override {}
};

class TestQuicSession : public MockQuicSession {
 public:
  TestQuicSession(QuicConnection* connection)
      : MockQuicSession(connection, /*create_mock_crypto_stream=*/true) {
    Initialize();
  }

  TestQuicStream* CreateIncomingStream(QuicStreamId id) override {
    TestQuicStream* stream = new TestQuicStream(
        id, this,
        DetermineStreamType(id, connection()->transport_version(),
                            perspective(),
                            /*is_incoming=*/true, BIDIRECTIONAL));
    ActivateStream(QuicWrapUnique(stream));
    return stream;
  }

  bool SaveFrame(const QuicFrame& frame) {
    save_frame_ = frame;
    DeleteFrame(&const_cast<QuicFrame&>(frame));
    return true;
  }

  const QuicFrame& save_frame() { return save_frame_; }

  bool ClearControlFrame(const QuicFrame& frame) {
    DeleteFrame(&const_cast<QuicFrame&>(frame));
    return true;
  }

  TestQuicStream* CreateOutgoingBidirectionalStream() {
    if (!CanOpenNextOutgoingBidirectionalStream()) {
      return nullptr;
    }
    QuicStreamId id = GetNextOutgoingBidirectionalStreamId();
    TestQuicStream* stream = new TestQuicStream(id, this, BIDIRECTIONAL);
    ActivateStream(QuicWrapUnique(stream));
    return stream;
  }

  TestQuicStream* CreateOutgoingUnidirectionalStream() {
    if (!CanOpenNextOutgoingUnidirectionalStream()) {
      return nullptr;
    }
    QuicStreamId id = GetNextOutgoingUnidirectionalStreamId();
    TestQuicStream* stream = new TestQuicStream(id, this, WRITE_UNIDIRECTIONAL);
    ActivateStream(QuicWrapUnique(stream));
    return stream;
  }

 private:
  QuicFrame save_frame_;
};

class QuicStreamIdManagerTestBase : public QuicTestWithParam<bool> {
 protected:
  explicit QuicStreamIdManagerTestBase(Perspective perspective)
      : connection_(new StrictMock<MockQuicConnection>(
            &helper_,
            &alarm_factory_,
            perspective,
            ParsedQuicVersionVector(
                {{PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_99}}))) {
    connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
    session_ = QuicMakeUnique<TestQuicSession>(connection_);
    stream_id_manager_ =
        GetParam() ? QuicSessionPeer::v99_bidirectional_stream_id_manager(
                         session_.get())
                   : QuicSessionPeer::v99_unidirectional_stream_id_manager(
                         session_.get());
  }

  QuicTransportVersion transport_version() const {
    return connection_->transport_version();
  }

  void CloseStream(QuicStreamId id) { session_->CloseStream(id); }

  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
    return QuicUtils::GetFirstBidirectionalStreamId(
               connection_->transport_version(), Perspective::IS_CLIENT) +
           kV99StreamIdIncrement * n;
  }

  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
    return QuicUtils::GetFirstUnidirectionalStreamId(
               connection_->transport_version(), Perspective::IS_CLIENT) +
           kV99StreamIdIncrement * n;
  }

  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
    return QuicUtils::GetFirstBidirectionalStreamId(
               connection_->transport_version(), Perspective::IS_SERVER) +
           kV99StreamIdIncrement * n;
  }

  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
    return QuicUtils::GetFirstUnidirectionalStreamId(
               connection_->transport_version(), Perspective::IS_SERVER) +
           kV99StreamIdIncrement * n;
  }

  MockQuicConnectionHelper helper_;
  MockAlarmFactory alarm_factory_;
  StrictMock<MockQuicConnection>* connection_;
  std::unique_ptr<TestQuicSession> session_;
  QuicStreamIdManager* stream_id_manager_;
};

// Following tests are either client-specific (they depend, in some way, on
// client-specific attributes, such as the initial stream ID) or are
// server/client independent (arbitrarily all such tests have been placed here).

class QuicStreamIdManagerTestClient : public QuicStreamIdManagerTestBase {
 protected:
  QuicStreamIdManagerTestClient()
      : QuicStreamIdManagerTestBase(Perspective::IS_CLIENT) {}
};

INSTANTIATE_TEST_SUITE_P(Tests, QuicStreamIdManagerTestClient, testing::Bool());

// Check that the parameters used by the stream ID manager are properly
// initialized.
TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerClientInitialization) {
  // These fields are inited via the QuicSession constructor to default
  // values defined as a constant.
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_->max_allowed_incoming_streams());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_->max_allowed_outgoing_streams());

  // The window for advertising updates to the MAX STREAM ID is half the number
  // of streams allowed.
  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamIdWindowDivisor,
            stream_id_manager_->max_stream_id_window());

  // This test runs as a client, so it initiates (that is to say, outgoing)
  // even-numbered stream IDs. Also, our implementation starts allocating
  // stream IDs at 0 (for clients) 1 (for servers) -- before taking statically
  // allocated streams into account. The -1 in the calculation is
  // because the value being tested is the maximum allowed stream ID, not the
  // first unallowed stream id.
  const QuicStreamId kExpectedMaxOutgoingStreamId =
      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
                  : session_->next_outgoing_unidirectional_stream_id()) +
      ((kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement);
  EXPECT_EQ(kExpectedMaxOutgoingStreamId,
            stream_id_manager_->max_allowed_outgoing_stream_id());

  // Same for IDs of incoming streams...
  const QuicStreamId kExpectedMaxIncomingStreamId =
      stream_id_manager_->first_incoming_dynamic_stream_id() +
      (kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement;
  EXPECT_EQ(kExpectedMaxIncomingStreamId,
            stream_id_manager_->actual_max_allowed_incoming_stream_id());
  EXPECT_EQ(kExpectedMaxIncomingStreamId,
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
}

// This test checks that the initialization for the maximum allowed outgoing
// stream id is correct.
TEST_P(QuicStreamIdManagerTestClient, CheckMaxAllowedOutgoing) {
  const size_t kNumOutgoingStreams = 124;
  stream_id_manager_->SetMaxOpenOutgoingStreams(kNumOutgoingStreams);
  EXPECT_EQ(kNumOutgoingStreams,
            stream_id_manager_->max_allowed_outgoing_streams());

  // Check that the maximum available stream is properly set.
  size_t expected_max_outgoing_id =
      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
                  : session_->next_outgoing_unidirectional_stream_id()) +
      ((kNumOutgoingStreams - 1) * kV99StreamIdIncrement);
  EXPECT_EQ(expected_max_outgoing_id,
            stream_id_manager_->max_allowed_outgoing_stream_id());
}

// This test checks that the initialization for the maximum allowed incoming
// stream id is correct.
TEST_P(QuicStreamIdManagerTestClient, CheckMaxAllowedIncoming) {
  const size_t kStreamCount = 245;
  stream_id_manager_->SetMaxOpenIncomingStreams(kStreamCount);
  EXPECT_EQ(kStreamCount, stream_id_manager_->max_allowed_incoming_streams());
  // Check that the window is 1/2 (integer math) of the stream count.
  EXPECT_EQ(kStreamCount / 2, stream_id_manager_->max_stream_id_window());

  // Actual- and advertised- maxima start out equal.
  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());

  // Check that the maximum stream ID is properly calculated.
  EXPECT_EQ(stream_id_manager_->first_incoming_dynamic_stream_id() +
                ((kStreamCount - 1) * kV99StreamIdIncrement),
            stream_id_manager_->actual_max_allowed_incoming_stream_id());
}

// This test checks that the stream advertisement window is set to 1
// if the number of stream ids is 1. This is a special case in the code.
TEST_P(QuicStreamIdManagerTestClient, CheckMaxStreamIdWindow1) {
  stream_id_manager_->SetMaxOpenIncomingStreams(1);
  EXPECT_EQ(1u, stream_id_manager_->max_allowed_incoming_streams());
  // If streamid_count/2==0 (integer math) force it to 1.
  EXPECT_EQ(1u, stream_id_manager_->max_stream_id_window());
}

// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is less than the
// stream ID most recently advertised in a MAX_STREAM_ID frame. This should
// cause a MAX_STREAM_ID frame with the most recently advertised stream id to be
// sent.
TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedOk) {
  EXPECT_CALL(*connection_, SendControlFrame(_))
      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
  QuicStreamId stream_id =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id() -
      kV99StreamIdIncrement;
  QuicStreamIdBlockedFrame frame(0, stream_id);
  session_->OnStreamIdBlockedFrame(frame);

  // We should see a MAX_STREAM_ID frame.
  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);

  // and it should advertise the current max-allowed value.
  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
            session_->save_frame().max_stream_id_frame.max_stream_id);
}

// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is equal to
// stream ID most recently advertised in a MAX_STREAM_ID frame. No
// MAX_STREAM_ID should be generated.
TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedNoOp) {
  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
  QuicStreamId stream_id =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
  QuicStreamIdBlockedFrame frame(0, stream_id);
  session_->OnStreamIdBlockedFrame(frame);
}

// Check the case of the stream ID in a STREAM_ID_BLOCKED frame is greater than
// the stream ID most recently advertised in a MAX_STREAM_ID frame. Expect a
// connection close with an error.
TEST_P(QuicStreamIdManagerTestClient, ProcessStreamIdBlockedTooBig) {
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
  QuicStreamId stream_id =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id() +
      kV99StreamIdIncrement;
  QuicStreamIdBlockedFrame frame(0, stream_id);
  session_->OnStreamIdBlockedFrame(frame);
}

// Same basic tests as above, but calls
// QuicStreamIdManager::MaybeIncreaseLargestPeerStreamId directly, avoiding the
// call chain. The intent is that if there is a problem, the following tests
// will point to either the stream ID manager or the call chain. They also
// provide specific, small scale, tests of a public QuicStreamIdManager method.
// First test make sure that streams with ids below the limit are accepted.
TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidBelowLimit) {
  QuicStreamId stream_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id() -
      kV99StreamIdIncrement;
  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
}

// Accept a stream with an ID that equals the limit.
TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidAtLimit) {
  QuicStreamId stream_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id();
  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
}

// Close the connection if the id exceeds the limit.
TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdInValidAboveLimit) {
  QuicStreamId stream_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
      kV99StreamIdIncrement;
  QuicString error_details =
      GetParam() ? "Stream id 401 above 397" : "Stream id 403 above 399";
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
  EXPECT_FALSE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
}

// Test that a client will reject a MAX_STREAM_ID that specifies a
// server-initiated stream ID.
TEST_P(QuicStreamIdManagerTestClient, RejectServerMaxStreamId) {
  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();

  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
  // current MAX.
  id += (kV99StreamIdIncrement * 2);

  // Make it an odd (server-initiated) ID.
  id |= 0x1;
  EXPECT_FALSE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));

  // Make the frame and process it; should result in the connection being
  // closed.
  QuicMaxStreamIdFrame frame(0, id);
  EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAM_ID_ERROR, _, _));
  session_->OnMaxStreamIdFrame(frame);
}

// Test that a client will reject a STREAM_ID_BLOCKED that specifies a
// client-initiated stream ID. STREAM_ID_BLOCKED from a server should specify an
// odd (server-initiated_ ID). Generate one with an odd ID and check that the
// connection is closed.
TEST_P(QuicStreamIdManagerTestClient, RejectServerStreamIdBlocked) {
  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();

  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
  // current MAX.
  id += (kV99StreamIdIncrement * 2);
  // Make sure it's odd, like a client-initiated ID.
  id &= ~0x01;
  EXPECT_TRUE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));

  // Generate and process the frame; connection should be closed.
  QuicStreamIdBlockedFrame frame(0, id);
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
  session_->OnStreamIdBlockedFrame(frame);
}

// Test functionality for reception of a MAX STREAM ID frame. This code is
// client/server-agnostic.
TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerClientOnMaxStreamIdFrame) {
  // Get the current maximum allowed outgoing stream ID.
  QuicStreamId initial_stream_id =
      stream_id_manager_->max_allowed_outgoing_stream_id();
  QuicMaxStreamIdFrame frame;

  // If the stream ID in the frame is < the current maximum then
  // the frame should be ignored.
  frame.max_stream_id = initial_stream_id - kV99StreamIdIncrement;
  EXPECT_TRUE(stream_id_manager_->OnMaxStreamIdFrame(frame));
  EXPECT_EQ(initial_stream_id,
            stream_id_manager_->max_allowed_outgoing_stream_id());

  // A stream ID greater than the current limit should increase the limit.
  frame.max_stream_id = initial_stream_id + kV99StreamIdIncrement;
  EXPECT_TRUE(stream_id_manager_->OnMaxStreamIdFrame(frame));
  EXPECT_EQ(initial_stream_id + kV99StreamIdIncrement,
            stream_id_manager_->max_allowed_outgoing_stream_id());
}

// Test functionality for reception of a STREAM ID BLOCKED frame.
// This code is client/server-agnostic.
TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerOnStreamIdBlockedFrame) {
  // Get the current maximum allowed incoming stream ID.
  QuicStreamId advertised_stream_id =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
  QuicStreamIdBlockedFrame frame;

  // If the peer is saying it's blocked on the stream ID that
  // we've advertised, it's a noop since the peer has the correct information.
  frame.stream_id = advertised_stream_id;
  EXPECT_TRUE(stream_id_manager_->OnStreamIdBlockedFrame(frame));

  // If the peer is saying it's blocked on a stream ID that is larger
  // than what we've advertised, the connection should get closed.
  frame.stream_id = advertised_stream_id + kV99StreamIdIncrement;
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
  EXPECT_FALSE(stream_id_manager_->OnStreamIdBlockedFrame(frame));

  // If the peer is saying it's blocked on a stream ID that is less than
  // what we've advertised, we send a MAX STREAM ID frame and update
  // the advertised value.
  // First, need to bump up the actual max so there is room for the MAX
  // STREAM_ID frame to send a larger ID.
  QuicStreamId actual_stream_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id();
  stream_id_manager_->OnStreamClosed(
      stream_id_manager_->first_incoming_dynamic_stream_id());
  EXPECT_EQ(actual_stream_id + kV99StreamIdIncrement,
            stream_id_manager_->actual_max_allowed_incoming_stream_id());
  EXPECT_GT(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());

  // Now simulate receiving a STTREAM_ID_BLOCKED frame...
  // Changing the actual maximum, above, forces a MAX STREAM ID frame to be
  // sent, so the logic for that (SendMaxStreamIdFrame(), etc) is tested.
  frame.stream_id = advertised_stream_id;
  EXPECT_CALL(*connection_, SendControlFrame(_))
      .Times(1)
      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
  EXPECT_TRUE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
  EXPECT_EQ(stream_id_manager_->advertised_max_allowed_incoming_stream_id(),
            session_->save_frame().max_stream_id_frame.max_stream_id);

  // Ensure a client initiated stream ID is rejected.
  frame.stream_id = GetParam() ? GetNthClientInitiatedBidirectionalId(1)
                               : GetNthClientInitiatedUnidirectionalId(1);
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
  EXPECT_FALSE(stream_id_manager_->OnStreamIdBlockedFrame(frame));
}

// Test GetNextOutgoingStream. This is client/server agnostic.
TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerGetNextOutgoingFrame) {
  // Number of streams we can open and the first one we should get when
  // opening...
  int number_of_streams = kDefaultMaxStreamsPerConnection;
  QuicStreamId stream_id =
      GetParam() ? session_->next_outgoing_bidirectional_stream_id()
                 : session_->next_outgoing_unidirectional_stream_id();

  while (number_of_streams) {
    EXPECT_TRUE(stream_id_manager_->CanOpenNextOutgoingStream());
    EXPECT_EQ(stream_id, stream_id_manager_->GetNextOutgoingStreamId());
    stream_id += kV99StreamIdIncrement;
    number_of_streams--;
  }
  EXPECT_EQ(stream_id - kV99StreamIdIncrement,
            stream_id_manager_->max_allowed_outgoing_stream_id());

  // If we try to check that the next outgoing stream id is available it should
  // A) fail and B) generate a STREAM_ID_BLOCKED frame.
  EXPECT_CALL(*connection_, SendControlFrame(_))
      .Times(1)
      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
  EXPECT_FALSE(stream_id_manager_->CanOpenNextOutgoingStream());
  EXPECT_EQ(STREAM_ID_BLOCKED_FRAME, session_->save_frame().type);
  EXPECT_EQ(stream_id_manager_->max_allowed_outgoing_stream_id(),
            session_->save_frame().max_stream_id_frame.max_stream_id);
  // If we try to get the next id (above the limit), it should cause a quic-bug.
  EXPECT_QUIC_BUG(
      stream_id_manager_->GetNextOutgoingStreamId(),
      "Attempt allocate a new outgoing stream ID would exceed the limit");
}

// Ensure that MaybeIncreaseLargestPeerStreamId works properly. This is
// server/client agnostic.
TEST_P(QuicStreamIdManagerTestClient,
       StreamIdManagerServerMaybeIncreaseLargestPeerStreamId) {
  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
      stream_id_manager_->actual_max_allowed_incoming_stream_id()));
  QuicStreamId server_initiated_stream_id =
      GetParam() ? GetNthServerInitiatedBidirectionalId(0)
                 : GetNthServerInitiatedUnidirectionalId(0);
  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
      server_initiated_stream_id));
  // A bad stream ID results in a closed connection.
  EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_STREAM_ID, _, _));
  EXPECT_FALSE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
      kV99StreamIdIncrement));
}

// Test the MAX STREAM ID Window functionality.
// Free up Stream ID space. Do not expect to see a MAX_STREAM_ID
// until |window| stream ids are available.
TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerServerMaxStreamId) {
  // Test that a MAX_STREAM_ID frame is generated when the peer has less than
  // |max_stream_id_window_| streams left that it can initiate.

  // First, open, and then close, max_stream_id_window_ streams.  This will
  // max_stream_id_window_ streams available for the peer -- no MAX_STREAM_ID
  // should be sent. The -1 is because the check in
  // QuicStreamIdManager::MaybeSendMaxStreamIdFrame sends a MAX_STREAM_ID if the
  // number of available streams at the peer is <= |max_stream_id_window_|
  int stream_count = stream_id_manager_->max_stream_id_window() - 1;

  QuicStreamId advertised_max =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id();
  QuicStreamId expected_actual_max_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id();

  // Should not get a control-frame transmission since the peer should have
  // "plenty" of stream IDs to use.
  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
  // This test runs as a client, so the first stream to release is 2, a
  // server-initiated stream.
  QuicStreamId stream_id = GetParam()
                               ? GetNthServerInitiatedBidirectionalId(0)
                               : GetNthServerInitiatedUnidirectionalId(0);
  size_t old_available_incoming_streams =
      stream_id_manager_->available_incoming_streams();

  while (stream_count) {
    EXPECT_TRUE(
        stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));

    old_available_incoming_streams--;
    EXPECT_EQ(old_available_incoming_streams,
              stream_id_manager_->available_incoming_streams());

    stream_count--;
    stream_id += kV99StreamIdIncrement;
  }

  // Now close them, still should get no MAX_STREAM_ID
  stream_count = stream_id_manager_->max_stream_id_window();
  stream_id = GetParam() ? GetNthServerInitiatedBidirectionalId(0)
                         : GetNthServerInitiatedUnidirectionalId(0);
  while (stream_count) {
    stream_id_manager_->OnStreamClosed(stream_id);
    stream_count--;
    stream_id += kV99StreamIdIncrement;
    expected_actual_max_id += kV99StreamIdIncrement;
    EXPECT_EQ(expected_actual_max_id,
              stream_id_manager_->actual_max_allowed_incoming_stream_id());
    // Advertised maximum should remain the same.
    EXPECT_EQ(advertised_max,
              stream_id_manager_->advertised_max_allowed_incoming_stream_id());
  }

  // This should not change.
  EXPECT_EQ(old_available_incoming_streams,
            stream_id_manager_->available_incoming_streams());

  // Now whenever we close a stream we should get a MAX_STREAM_ID frame.
  // Above code closed all the open streams, so we have to open/close
  EXPECT_CALL(*connection_, SendControlFrame(_))
      .Times(1)
      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
  stream_id_manager_->OnStreamClosed(stream_id);
  stream_id += kV99StreamIdIncrement;

  // Check that the MAX STREAM ID was sent and has the correct values.
  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
  EXPECT_EQ(stream_id_manager_->advertised_max_allowed_incoming_stream_id(),
            session_->save_frame().max_stream_id_frame.max_stream_id);
}

// Test that registering static stream IDs causes the stream ID limit to rise
// accordingly. This is server/client agnostic.
TEST_P(QuicStreamIdManagerTestClient, TestStaticStreamAdjustment) {
  QuicStreamId first_dynamic =
      stream_id_manager_->first_incoming_dynamic_stream_id();
  QuicStreamId expected_max_incoming =
      stream_id_manager_->actual_max_allowed_incoming_stream_id();

  // First test will register the first dynamic stream id as being for a static
  // stream.  This takes one stream ID out of the low-end of the dynamic range
  // so therefore the high end should go up by 1 ID.
  expected_max_incoming += kV99StreamIdIncrement;
  stream_id_manager_->RegisterStaticStream(first_dynamic);
  EXPECT_EQ(expected_max_incoming,
            stream_id_manager_->actual_max_allowed_incoming_stream_id());

  // Now be extreme, increase static by 100 stream ids.  A discontinuous
  // jump is not allowed; make sure.
  first_dynamic += kV99StreamIdIncrement * 100;
  expected_max_incoming += kV99StreamIdIncrement * 100;
  QuicString bug_detail =
      GetParam() ? "allocate 5 got 401" : "allocate 7 got 403";
  EXPECT_QUIC_BUG(
      stream_id_manager_->RegisterStaticStream(first_dynamic),
      "Error in incoming static stream allocation, expected to " + bug_detail);
}

// Following tests all are server-specific. They depend, in some way, on
// server-specific attributes, such as the initial stream ID.

class QuicStreamIdManagerTestServer : public QuicStreamIdManagerTestBase {
 protected:
  QuicStreamIdManagerTestServer()
      : QuicStreamIdManagerTestBase(Perspective::IS_SERVER) {}
};

INSTANTIATE_TEST_SUITE_P(Tests, QuicStreamIdManagerTestServer, testing::Bool());

// This test checks that the initialization for the maximum allowed outgoing
// stream id is correct.
TEST_P(QuicStreamIdManagerTestServer, CheckMaxAllowedOutgoing) {
  const size_t kIncomingStreamCount = 123;
  stream_id_manager_->SetMaxOpenOutgoingStreams(kIncomingStreamCount);
  EXPECT_EQ(kIncomingStreamCount,
            stream_id_manager_->max_allowed_outgoing_streams());

  // Check that the max outgoing stream id is properly calculated
  EXPECT_EQ(stream_id_manager_->GetNextOutgoingStreamId() +
                ((kIncomingStreamCount - 1) * kV99StreamIdIncrement),
            stream_id_manager_->max_allowed_outgoing_stream_id());
}

// This test checks that the initialization for the maximum allowed incoming
// stream id is correct.
TEST_P(QuicStreamIdManagerTestServer, CheckMaxAllowedIncoming) {
  const size_t kIncomingStreamCount = 245;
  stream_id_manager_->SetMaxOpenIncomingStreams(kIncomingStreamCount);
  EXPECT_EQ(kIncomingStreamCount,
            stream_id_manager_->max_allowed_incoming_streams());

  // Check that the window is 1/2 (integer math) of the stream count.
  EXPECT_EQ((kIncomingStreamCount / 2),
            stream_id_manager_->max_stream_id_window());

  // Actual- and advertised- maxima start out equal.
  EXPECT_EQ(stream_id_manager_->actual_max_allowed_incoming_stream_id(),
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());

  // First stream ID the client should use should be 3, this means that the max
  // stream id is 491 -- ((number of stream ids-1) * 2) + first available id.
  EXPECT_EQ(stream_id_manager_->first_incoming_dynamic_stream_id() +
                ((kIncomingStreamCount - 1) * kV99StreamIdIncrement),
            stream_id_manager_->actual_max_allowed_incoming_stream_id());
}

// Test that a MAX_STREAM_ID frame is generated when half the stream ids become
// available. This has a useful side effect of testing that when streams are
// closed, the number of available stream ids increases.
TEST_P(QuicStreamIdManagerTestServer, MaxStreamIdSlidingWindow) {
  // Ignore OnStreamReset calls.
  EXPECT_CALL(*connection_, OnStreamReset(_, _)).WillRepeatedly(Return());
  // Capture control frames for analysis.
  EXPECT_CALL(*connection_, SendControlFrame(_))
      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
  // Simulate config being negotiated, causing the limits all to be initialized.
  session_->OnConfigNegotiated();
  QuicStreamId first_advert =
      stream_id_manager_->advertised_max_allowed_incoming_stream_id();

  // Open/close enough streams to shrink the window without causing a MAX STREAM
  // ID to be generated. The window will open (and a MAX STREAM ID generated)
  // when max_stream_id_window() stream IDs have been made available. The loop
  // will make that many stream IDs available, so the last CloseStream should
  // cause a MAX STREAM ID frame to be generated.
  int i = static_cast<int>(stream_id_manager_->max_stream_id_window());
  QuicStreamId id = stream_id_manager_->first_incoming_dynamic_stream_id();
  while (i) {
    QuicStream* stream = session_->GetOrCreateStream(id);
    EXPECT_NE(nullptr, stream);
    // have to set the stream's fin-received flag to true so that it
    // does not go into the has-not-received-byte-offset state, leading
    // to the stream being added to the locally_closed_streams_highest_offset_
    // map, and therefore not counting as truly being closed. The test requires
    // that the stream truly close, so that new streams become available,
    // causing the MAX_STREAM_ID to be sent.
    stream->set_fin_received(true);
    EXPECT_EQ(id, stream->id());
    if (GetParam()) {
      // Only send reset for incoming bidirectional streams.
      EXPECT_CALL(*session_, SendRstStream(_, _, _));
    }
    CloseStream(stream->id());
    i--;
    id += kV99StreamIdIncrement;
  }
  EXPECT_EQ(MAX_STREAM_ID_FRAME, session_->save_frame().type);
  QuicStreamId second_advert =
      session_->save_frame().max_stream_id_frame.max_stream_id;
  EXPECT_EQ(first_advert + (stream_id_manager_->max_stream_id_window() *
                            kV99StreamIdIncrement),
            second_advert);
}

// Tast that an attempt to create an outgoing stream does not exceed the limit
// and that it generates an appropriate STREAM_ID_BLOCKED frame.
TEST_P(QuicStreamIdManagerTestServer, NewStreamDoesNotExceedLimit) {
  size_t stream_count = stream_id_manager_->max_allowed_outgoing_streams();
  EXPECT_NE(0u, stream_count);
  TestQuicStream* stream;
  while (stream_count) {
    stream = GetParam() ? session_->CreateOutgoingBidirectionalStream()
                        : session_->CreateOutgoingUnidirectionalStream();
    EXPECT_NE(stream, nullptr);
    stream_count--;
  }
  // Quis Custodiet Ipsos Custodes.
  EXPECT_EQ(stream->id(), stream_id_manager_->max_allowed_outgoing_stream_id());
  // Create another, it should fail. Should also send a STREAM_ID_BLOCKED
  // control frame.
  EXPECT_CALL(*connection_, SendControlFrame(_));
  stream = GetParam() ? session_->CreateOutgoingBidirectionalStream()
                      : session_->CreateOutgoingUnidirectionalStream();
  EXPECT_EQ(nullptr, stream);
}

// Test that a server will reject a MAX_STREAM_ID that specifies a
// client-initiated stream ID.
TEST_P(QuicStreamIdManagerTestServer, RejectClientMaxStreamId) {
  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();

  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
  // current MAX.
  id += (kV99StreamIdIncrement * 2);

  // Turn it into a client-initiated ID (even).
  id &= ~0x1;
  EXPECT_TRUE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));

  // Generate a MAX_STREAM_ID frame and process it; the connection should close.
  QuicMaxStreamIdFrame frame(0, id);
  EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAM_ID_ERROR, _, _));
  session_->OnMaxStreamIdFrame(frame);
}

// Test that a server will reject a STREAM_ID_BLOCKED that specifies a
// server-initiated stream ID. STREAM_ID_BLOCKED from a client should specify an
// even (client-initiated_ ID) generate one with an odd ID and check that the
// connection is closed.
TEST_P(QuicStreamIdManagerTestServer, RejectClientStreamIdBlocked) {
  QuicStreamId id = stream_id_manager_->max_allowed_outgoing_stream_id();

  // Ensure that the ID that will be in the MAX_STREAM_ID is larger than the
  // current MAX.
  id += (kV99StreamIdIncrement * 2);

  // Make the ID odd, so it looks like the client is trying to specify a
  // server-initiated ID.
  id |= 0x1;
  EXPECT_FALSE(QuicUtils::IsClientInitiatedStreamId(QUIC_VERSION_99, id));

  // Generate a STREAM_ID_BLOCKED frame and process it; the connection should
  // close.
  QuicStreamIdBlockedFrame frame(0, id);
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_STREAM_ID_BLOCKED_ERROR, _, _));
  session_->OnStreamIdBlockedFrame(frame);
}

// Check that the parameters used by the stream ID manager are properly
// initialized
TEST_P(QuicStreamIdManagerTestServer, StreamIdManagerServerInitialization) {
  // These fields are inited via the QuicSession constructor to default
  // values defined as a constant.
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_->max_allowed_incoming_streams());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_->max_allowed_outgoing_streams());

  // The window for advertising updates to the MAX STREAM ID is half the number
  // of stream allowed.
  EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamIdWindowDivisor,
            stream_id_manager_->max_stream_id_window());

  // This test runs as a server, so it initiates (that is to say, outgoing)
  // even-numbered stream IDs. The -1 in the calculation is because the value
  // being tested is the maximum allowed stream ID, not the first unallowed
  // stream id.
  const QuicStreamId kExpectedMaxOutgoingStreamId =
      (GetParam() ? session_->next_outgoing_bidirectional_stream_id()
                  : session_->next_outgoing_unidirectional_stream_id()) +
      ((kDefaultMaxStreamsPerConnection - 1) * kV99StreamIdIncrement);
  EXPECT_EQ(kExpectedMaxOutgoingStreamId,
            stream_id_manager_->max_allowed_outgoing_stream_id());

  // Same for IDs of incoming streams... But they are client initiated, so are
  // even.
  const QuicStreamId kExpectedMaxIncomingStreamId =
      GetParam() ? GetNthClientInitiatedBidirectionalId(
                       kDefaultMaxStreamsPerConnection - 1)
                 : GetNthClientInitiatedUnidirectionalId(
                       kDefaultMaxStreamsPerConnection - 1);
  EXPECT_EQ(kExpectedMaxIncomingStreamId,
            stream_id_manager_->actual_max_allowed_incoming_stream_id());
  EXPECT_EQ(kExpectedMaxIncomingStreamId,
            stream_id_manager_->advertised_max_allowed_incoming_stream_id());
}

TEST_P(QuicStreamIdManagerTestServer, AvailableStreams) {
  stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
      GetParam() ? GetNthClientInitiatedBidirectionalId(3)
                 : GetNthClientInitiatedUnidirectionalId(3));
  EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
      GetParam() ? GetNthClientInitiatedBidirectionalId(1)
                 : GetNthClientInitiatedUnidirectionalId(1)));
  EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
      GetParam() ? GetNthClientInitiatedBidirectionalId(2)
                 : GetNthClientInitiatedUnidirectionalId(2)));
}

// Tests that if MaybeIncreaseLargestPeerStreamId is given an extremely
// large stream ID (larger than the limit) it is rejected.
// This is a regression for Chromium bugs 909987 and 910040
TEST_P(QuicStreamIdManagerTestServer, ExtremeMaybeIncreaseLargestPeerStreamId) {
  QuicStreamId too_big_stream_id =
      stream_id_manager_->actual_max_allowed_incoming_stream_id() +
      kV99StreamIdIncrement * 20;

  QuicString error_details =
      GetParam() ? "Stream id 480 above 400" : "Stream id 478 above 398";
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));

  EXPECT_FALSE(
      stream_id_manager_->MaybeIncreaseLargestPeerStreamId(too_big_stream_id));
}

}  // namespace
}  // namespace test
}  // namespace quic
