// 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 <string>
#include <utility>

#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_stream_id_manager_peer.h"

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

namespace quic {
namespace test {
namespace {

class MockDelegate : public QuicStreamIdManager::DelegateInterface {
 public:
  MOCK_METHOD1(OnCanCreateNewOutgoingStream, void(bool unidirectional));
  MOCK_METHOD2(OnError,
               void(QuicErrorCode error_code, std::string error_details));
  MOCK_METHOD2(SendMaxStreams,
               void(QuicStreamCount stream_count, bool unidirectional));
  MOCK_METHOD2(SendStreamsBlocked,
               void(QuicStreamCount stream_count, bool unidirectional));
};

struct TestParams {
  TestParams(Perspective perspective, bool is_unidirectional)
      : perspective(perspective), is_unidirectional(is_unidirectional) {}

  Perspective perspective;
  bool is_unidirectional;
};

// Used by ::testing::PrintToStringParamName().
std::string PrintToString(const TestParams& p) {
  return QuicStrCat(
      (p.perspective == Perspective::IS_CLIENT ? "Client" : "Server"),
      (p.is_unidirectional ? "Unidirectional" : "Bidirectional"));
}

std::vector<TestParams> GetTestParams() {
  std::vector<TestParams> params;
  for (Perspective perspective :
       {Perspective::IS_CLIENT, Perspective::IS_SERVER}) {
    for (bool is_unidirectional : {true, false}) {
      params.push_back(TestParams(perspective, is_unidirectional));
    }
  }
  return params;
}

class QuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
 protected:
  QuicStreamIdManagerTest()
      : stream_id_manager_(&delegate_,
                           IsUnidirectional(),
                           perspective(),
                           transport_version(),
                           0,
                           kDefaultMaxStreamsPerConnection,
                           kDefaultMaxStreamsPerConnection) {
    DCHECK(VersionHasIetfQuicFrames(transport_version()));
  }

  QuicTransportVersion transport_version() const { return QUIC_VERSION_99; }

  // Returns the stream ID for the Nth incoming stream (created by the peer)
  // of the corresponding directionality of this manager.
  QuicStreamId GetNthIncomingStreamId(int n) {
    return kV99StreamIdIncrement * n +
           (IsUnidirectional()
                ? QuicUtils::GetFirstUnidirectionalStreamId(
                      transport_version(),
                      QuicUtils::InvertPerspective(perspective()))
                : QuicUtils::GetFirstBidirectionalStreamId(
                      transport_version(),
                      QuicUtils::InvertPerspective(perspective())));
  }

  bool IsUnidirectional() { return GetParam().is_unidirectional; }
  Perspective perspective() { return GetParam().perspective; }

  StrictMock<MockDelegate> delegate_;
  QuicStreamIdManager stream_id_manager_;
};

INSTANTIATE_TEST_SUITE_P(Tests,
                         QuicStreamIdManagerTest,
                         ::testing::ValuesIn(GetTestParams()),
                         ::testing::PrintToStringParamName());

TEST_P(QuicStreamIdManagerTest, Initialization) {
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_.outgoing_max_streams());

  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_.incoming_advertised_max_streams());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            stream_id_manager_.incoming_initial_max_open_streams());

  // The window for advertising updates to the MAX STREAM ID is half the number
  // of streams allowed.
  EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
            stream_id_manager_.max_streams_window());
}

// 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(QuicStreamIdManagerTest, CheckMaxStreamsWindowForSingleStream) {
  stream_id_manager_.SetMaxOpenIncomingStreams(1);
  EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
  EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(1u, stream_id_manager_.max_streams_window());
}

TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesOverMaxFailsOutgoing) {
  QuicStreamCount implementation_max =
      QuicUtils::GetMaxStreamCount(IsUnidirectional(), perspective());
  // Ensure that the limit is less than the implementation maximum.
  EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);

  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(implementation_max + 1);
  // Should be pegged at the max.
  EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
}

// Now do the same for the incoming streams
TEST_P(QuicStreamIdManagerTest, CheckMaxStreamsBadValuesIncoming) {
  QuicStreamCount implementation_max =
      QuicUtils::GetMaxStreamCount(IsUnidirectional(), perspective());
  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max - 1u);
  EXPECT_EQ(implementation_max - 1u,
            stream_id_manager_.incoming_initial_max_open_streams());
  EXPECT_EQ(implementation_max - 1u,
            stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ((implementation_max - 1u) / 2u,
            stream_id_manager_.max_streams_window());

  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max);
  EXPECT_EQ(implementation_max,
            stream_id_manager_.incoming_initial_max_open_streams());
  EXPECT_EQ(implementation_max,
            stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(implementation_max / 2, stream_id_manager_.max_streams_window());

  // Reset to 1 so that we can detect the change.
  stream_id_manager_.SetMaxOpenIncomingStreams(1u);
  EXPECT_EQ(1u, stream_id_manager_.incoming_initial_max_open_streams());
  EXPECT_EQ(1u, stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(1u, stream_id_manager_.max_streams_window());
  // Now try to exceed the max, without wrapping.
  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max + 1);
  EXPECT_EQ(implementation_max,
            stream_id_manager_.incoming_initial_max_open_streams());
  EXPECT_EQ(implementation_max,
            stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(implementation_max / 2u, stream_id_manager_.max_streams_window());
}

// Check the case of the stream count in a STREAMS_BLOCKED frame is less than
// the count most recently advertised in a MAX_STREAMS frame. This should cause
// a MAX_STREAMS frame with the most recently advertised count to be sent.
TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedOk) {
  // Set the config negotiated so that the MAX_STREAMS is transmitted.
  stream_id_manager_.OnConfigNegotiated();

  QuicStreamCount stream_count =
      stream_id_manager_.incoming_initial_max_open_streams();
  QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidirectional());
  EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidirectional()));
  stream_id_manager_.OnStreamsBlockedFrame(frame);
}

// Check the case of the stream count in a STREAMS_BLOCKED frame is equal to the
// count most recently advertised in a MAX_STREAMS frame. No MAX_STREAMS
// should be generated.
TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedNoOp) {
  QuicStreamCount stream_count =
      stream_id_manager_.incoming_initial_max_open_streams();
  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
}

// Check the case of the stream count in a STREAMS_BLOCKED frame is greater than
// the count most recently advertised in a MAX_STREAMS frame. Expect a
// connection close with an error.
TEST_P(QuicStreamIdManagerTest, ProcessStreamsBlockedTooBig) {
  EXPECT_CALL(delegate_, OnError(QUIC_STREAMS_BLOCKED_ERROR, _));
  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
  QuicStreamCount stream_count =
      stream_id_manager_.incoming_initial_max_open_streams() + 1;
  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidirectional());
  stream_id_manager_.OnStreamsBlockedFrame(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(QuicStreamIdManagerTest, IsIncomingStreamIdValidBelowLimit) {
  QuicStreamId stream_id = GetNthIncomingStreamId(
      stream_id_manager_.incoming_actual_max_streams() - 2);
  EXPECT_CALL(delegate_, OnError(_, _)).Times(0);
  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
}

// Accept a stream with an ID that equals the limit.
TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdValidAtLimit) {
  QuicStreamId stream_id = GetNthIncomingStreamId(
      stream_id_manager_.incoming_actual_max_streams() - 1);
  EXPECT_CALL(delegate_, OnError(_, _)).Times(0);
  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
}

// Close the connection if the id exceeds the limit.
TEST_P(QuicStreamIdManagerTest, IsIncomingStreamIdInValidAboveLimit) {
  QuicStreamId stream_id =
      GetNthIncomingStreamId(stream_id_manager_.incoming_actual_max_streams());
  std::string error_details = QuicStrCat(
      "Stream id ", stream_id, " would exceed stream count limit 100");
  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, error_details));
  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
}

TEST_P(QuicStreamIdManagerTest, OnMaxStreamsFrame) {
  // Get the current maximum allowed outgoing stream count.
  QuicStreamCount initial_stream_count =
      // need to know the number of request/response streams.
      // This is the total number of outgoing streams (which includes both
      // req/resp and statics).
      stream_id_manager_.outgoing_max_streams();

  QuicMaxStreamsFrame frame;

  // Even though the stream count in the frame is < the initial maximum,
  // it shouldn't be ignored since the initial max was set via
  // the constructor (an educated guess) but the MAX STREAMS frame
  // is authoritative.
  frame.stream_count = initial_stream_count - 1;

  frame.unidirectional = IsUnidirectional();
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  EXPECT_TRUE(stream_id_manager_.OnMaxStreamsFrame(frame));
  EXPECT_EQ(initial_stream_count - 1u,
            stream_id_manager_.outgoing_max_streams());

  QuicStreamCount save_outgoing_max_streams =
      stream_id_manager_.outgoing_max_streams();
  // Now that there has been one MAX STREAMS frame, we should not
  // accept a MAX_STREAMS that reduces the limit...
  frame.stream_count = initial_stream_count - 2;
  frame.unidirectional = IsUnidirectional();
  EXPECT_TRUE(stream_id_manager_.OnMaxStreamsFrame(frame));
  // should not change from previous setting.
  EXPECT_EQ(save_outgoing_max_streams,
            stream_id_manager_.outgoing_max_streams());

  // A stream count greater than the current limit should increase the limit.
  frame.stream_count = initial_stream_count + 1;
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  EXPECT_TRUE(stream_id_manager_.OnMaxStreamsFrame(frame));

  EXPECT_EQ(initial_stream_count + 1u,
            stream_id_manager_.outgoing_max_streams());
}

TEST_P(QuicStreamIdManagerTest, OnStreamsBlockedFrame) {
  // Get the current maximum allowed incoming stream count.
  QuicStreamCount advertised_stream_count =
      stream_id_manager_.incoming_advertised_max_streams();

  // Set the config negotiated to allow frame transmission.
  stream_id_manager_.OnConfigNegotiated();

  QuicStreamsBlockedFrame frame;

  frame.unidirectional = IsUnidirectional();

  // If the peer is saying it's blocked on the stream count that
  // we've advertised, it's a noop since the peer has the correct information.
  frame.stream_count = advertised_stream_count;
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame));

  // If the peer is saying it's blocked on a stream count that is larger
  // than what we've advertised, the connection should get closed.
  frame.stream_count = advertised_stream_count + 1;
  EXPECT_CALL(delegate_, OnError(QUIC_STREAMS_BLOCKED_ERROR, _));
  EXPECT_FALSE(stream_id_manager_.OnStreamsBlockedFrame(frame));

  // If the peer is saying it's blocked on a count that is less than
  // our actual count, we send a MAX_STREAMS frame and update
  // the advertised value.
  // First, need to bump up the actual max so there is room for the MAX
  // STREAMS frame to send a larger ID.
  QuicStreamCount actual_stream_count =
      stream_id_manager_.incoming_actual_max_streams();

  // Closing a stream will result in the ability to initiate one more
  // stream
  stream_id_manager_.OnStreamClosed(
      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_));
  EXPECT_EQ(actual_stream_count + 1u,
            stream_id_manager_.incoming_actual_max_streams());
  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
            stream_id_manager_.incoming_advertised_max_streams() + 1u);

  // Now simulate receiving a STREAMS_BLOCKED frame...
  // Changing the actual maximum, above, forces a MAX_STREAMS frame to be
  // sent, so the logic for that (SendMaxStreamsFrame(), etc) is tested.

  // The STREAMS_BLOCKED frame contains the previous advertised count,
  // not the one that the peer would have received as a result of the
  // MAX_STREAMS sent earler.
  frame.stream_count = advertised_stream_count;

  EXPECT_CALL(delegate_,
              SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
                             IsUnidirectional()));

  EXPECT_TRUE(stream_id_manager_.OnStreamsBlockedFrame(frame));
  // Check that the saved frame is correct.
  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
            stream_id_manager_.incoming_advertised_max_streams());
}

TEST_P(QuicStreamIdManagerTest, GetNextOutgoingStream) {
  // Number of streams we can open and the first one we should get when
  // opening...
  size_t number_of_streams = kDefaultMaxStreamsPerConnection;

  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(100);

  stream_id_manager_.OnConfigNegotiated();

  QuicStreamId stream_id =
      IsUnidirectional()
          ? QuicUtils::GetFirstUnidirectionalStreamId(
                transport_version(), stream_id_manager_.perspective())
          : QuicUtils::GetFirstBidirectionalStreamId(
                transport_version(), stream_id_manager_.perspective());

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

  // If we try to check that the next outgoing stream id is available it should
  // A) fail and B) generate a STREAMS_BLOCKED frame.
  EXPECT_CALL(delegate_, SendStreamsBlocked(kDefaultMaxStreamsPerConnection,
                                            IsUnidirectional()));
  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());

  // 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 to allocate a new outgoing stream that would exceed the limit");
}

TEST_P(QuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
  QuicStreamId max_stream_id = GetNthIncomingStreamId(
      stream_id_manager_.incoming_actual_max_streams() - 1);
  EXPECT_TRUE(
      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id));

  QuicStreamId first_stream_id = GetNthIncomingStreamId(0);
  EXPECT_TRUE(
      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(first_stream_id));
  // A bad stream ID results in a closed connection.
  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, _));
  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
      max_stream_id + kV99StreamIdIncrement));
}

TEST_P(QuicStreamIdManagerTest, MaxStreamsWindow) {
  // Set the config negotiated to allow frame transmission.
  stream_id_manager_.OnConfigNegotiated();

  // Test that a MAX_STREAMS frame is generated when the peer has less than
  // |max_streams_window_| streams left that it can initiate.

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

  // Should not get a control-frame transmission since the peer should have
  // "plenty" of stream IDs to use.
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);

  // Get the first incoming stream ID to try and allocate.
  QuicStreamId stream_id = GetNthIncomingStreamId(0);
  size_t old_available_incoming_streams =
      stream_id_manager_.available_incoming_streams();
  while (stream_count) {
    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));

    // This node should think that the peer believes it has one fewer
    // stream it can create.
    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_STREAMS
  stream_count = stream_id_manager_.max_streams_window();
  stream_id = GetNthIncomingStreamId(0);
  QuicStreamCount expected_actual_max =
      stream_id_manager_.incoming_actual_max_streams();
  QuicStreamCount expected_advertised_max_streams =
      stream_id_manager_.incoming_advertised_max_streams();
  while (stream_count) {
    stream_id_manager_.OnStreamClosed(stream_id);
    stream_count--;
    stream_id += kV99StreamIdIncrement;
    expected_actual_max++;
    EXPECT_EQ(expected_actual_max,
              stream_id_manager_.incoming_actual_max_streams());
    // Advertised maximum should remain the same.
    EXPECT_EQ(expected_advertised_max_streams,
              stream_id_manager_.incoming_advertised_max_streams());
  }

  // 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_STREAMS frame.
  // Above code closed all the open streams, so we have to open/close
  //  EXPECT_CALL(delegate_,
  //  SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
  //  IsUnidirectional()));
  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));
  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
  stream_id_manager_.OnStreamClosed(stream_id);
}

TEST_P(QuicStreamIdManagerTest, StreamsBlockedEdgeConditions) {
  // Set the config negotiated to allow frame transmission.
  stream_id_manager_.OnConfigNegotiated();

  QuicStreamsBlockedFrame frame;
  frame.unidirectional = IsUnidirectional();

  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
  // when max_allowed_incoming_streams is 0.
  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
  stream_id_manager_.SetMaxOpenIncomingStreams(0);
  frame.stream_count = 0;
  stream_id_manager_.OnStreamsBlockedFrame(frame);

  // Check that receipt of a STREAMS BLOCKED with stream-count = 0 invokes a
  // MAX STREAMS, count = 123, when the MaxOpen... is set to 123.
  EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidirectional()));
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
  stream_id_manager_.SetMaxOpenIncomingStreams(123);
  frame.stream_count = 0;
  stream_id_manager_.OnStreamsBlockedFrame(frame);
}

TEST_P(QuicStreamIdManagerTest, HoldMaxStreamsFrame) {
  // The config has not been negotiated so the MAX_STREAMS frame will not be
  // sent.
  EXPECT_CALL(delegate_, SendMaxStreams(_, _)).Times(0);

  QuicStreamsBlockedFrame frame(1u, 0u, IsUnidirectional());
  // Should cause change in pending_max_streams.
  stream_id_manager_.OnStreamsBlockedFrame(frame);

  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidirectional()));

  // MAX_STREAMS will be sent now that the config has been negotiated.
  stream_id_manager_.OnConfigNegotiated();
}

TEST_P(QuicStreamIdManagerTest, HoldStreamsBlockedFrameXmit) {
  // set outgoing limit to 0, will cause the CanOpenNext... to fail
  // leading to a STREAMS_BLOCKED.
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(0);

  // We should not see a STREAMS_BLOCKED frame because we're not configured..
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);

  // Since the stream limit is 0 and no sreams can be created this should return
  // false and have forced a STREAMS_BLOCKED to be queued up, with the
  // blocked stream id == 0.
  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());

  // Since the steam limit has not been increased when the config was negotiated
  // a STREAMS_BLOCKED frame should be sent.
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidirectional()));
  stream_id_manager_.OnConfigNegotiated();
}

TEST_P(QuicStreamIdManagerTest, HoldStreamsBlockedFrameNoXmit) {
  // Set outgoing limit to 0, will cause the CanOpenNext... to fail
  // leading to a STREAMS_BLOCKED.
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(0);

  // We should not see a STREAMS_BLOCKED frame because we're not configured..
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidirectional())).Times(0);

  // Since the stream limit is 0 and no sreams can be created this should return
  // false and have forced a STREAMS_BLOCKED to be queued up, with the
  // blocked stream id == 0.
  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());

  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(10);
  // Since the stream limit has been increase which allows streams to be created
  // no STREAMS_BLOCKED should be send.
  stream_id_manager_.OnConfigNegotiated();
}

TEST_P(QuicStreamIdManagerTest, CheckMaxAllowedOutgoingInitialization) {
  const size_t kIncomingStreamCount = 123;
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(kIncomingStreamCount);
  EXPECT_EQ(kIncomingStreamCount, stream_id_manager_.outgoing_max_streams());
}

// Test that a MAX_STREAMS 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(QuicStreamIdManagerTest, MaxStreamsSlidingWindow) {
  // Simulate config being negotiated, causing the limits all to be initialized.
  stream_id_manager_.OnConfigNegotiated();

  QuicStreamCount first_advert =
      stream_id_manager_.incoming_advertised_max_streams();

  // Open/close enough streams to shrink the window without causing a MAX
  // STREAMS to be generated. The window will open (and a MAX STREAMS generated)
  // when max_streams_window() stream IDs have been made available. The loop
  // will make that many stream IDs available, so the last CloseStream should

  // cause a MAX STREAMS frame to be generated.
  int i = static_cast<int>(stream_id_manager_.max_streams_window());
  QuicStreamId id =
      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
  EXPECT_CALL(
      delegate_,
      SendMaxStreams(first_advert + stream_id_manager_.max_streams_window(),
                     IsUnidirectional()));
  while (i) {
    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id));
    stream_id_manager_.OnStreamClosed(id);
    i--;
    id += kV99StreamIdIncrement;
  }
}

TEST_P(QuicStreamIdManagerTest, NewStreamDoesNotExceedLimit) {
  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidirectional()));
  stream_id_manager_.SetMaxOpenOutgoingStreams(100);
  stream_id_manager_.OnConfigNegotiated();

  size_t stream_count = stream_id_manager_.outgoing_max_streams();
  EXPECT_NE(0u, stream_count);

  while (stream_count) {
    EXPECT_TRUE(stream_id_manager_.CanOpenNextOutgoingStream());
    stream_id_manager_.GetNextOutgoingStreamId();
    stream_count--;
  }

  EXPECT_EQ(stream_id_manager_.outgoing_stream_count(),
            stream_id_manager_.outgoing_max_streams());
  // Create another, it should fail. Should also send a STREAMS_BLOCKED
  // control frame.
  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidirectional()));
  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
}

TEST_P(QuicStreamIdManagerTest, AvailableStreams) {
  stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthIncomingStreamId(3));

  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(1)));
  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(2)));
  EXPECT_FALSE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(3)));
  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(GetNthIncomingStreamId(4)));
}

// 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(QuicStreamIdManagerTest, ExtremeMaybeIncreaseLargestPeerStreamId) {
  QuicStreamId too_big_stream_id = GetNthIncomingStreamId(
      stream_id_manager_.incoming_actual_max_streams() + 20);
  std::string error_details = QuicStrCat(
      "Stream id ", too_big_stream_id, " would exceed stream count limit 100");

  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, error_details));
  EXPECT_FALSE(
      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(too_big_stream_id));
}

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