// 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 <string>
#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_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;
  std::string 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;
  std::string 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;

  std::string 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
