gfe-relnote: Decouple the QuicSession from the QuicStreamIdManager by introducing a QuicStreamIdManager::DelegateInterface which the session implements. Does not change behavior, merely adds a layer of abstraction which allows unit tests of QuicStreamIdManager to be simplified.

PiperOrigin-RevId: 270302454
Change-Id: I4a66803d4a2f1f640ef68ee6373af9b67423bac4
diff --git a/quic/core/quic_stream_id_manager_test.cc b/quic/core/quic_stream_id_manager_test.cc
index 7c1233b..748a10c 100644
--- a/quic/core/quic_stream_id_manager_test.cc
+++ b/quic/core/quic_stream_id_manager_test.cc
@@ -4,150 +4,68 @@
 #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().
+class MockDelegate : public QuicStreamIdManager::DelegateInterface {
  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 to an invalid frame type to detect cases where the frame type
-    // is not set subsequently.
-    save_frame_.type = static_cast<QuicFrameType>(-1);
-    Initialize();
-  }
-
-  TestQuicStream* CreateIncomingStream(QuicStreamId id) override {
-    TestQuicStream* stream = new TestQuicStream(
-        id, this,
-        DetermineStreamType(id, 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_; }
-
-  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_;
+  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));
 };
 
 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_ = std::make_unique<TestQuicSession>(connection_);
-    stream_id_manager_ =
-        IsBidi() ? QuicSessionPeer::v99_bidirectional_stream_id_manager(
-                       session_.get())
-                 : QuicSessionPeer::v99_unidirectional_stream_id_manager(
-                       session_.get());
-  }
+      : stream_id_manager_(&delegate_,
+                           IsUnidi(),
+                           perspective,
+                           QUIC_VERSION_99,
+                           0,
+                           kDefaultMaxStreamsPerConnection,
+                           kDefaultMaxStreamsPerConnection) {}
 
-  QuicTransportVersion transport_version() const {
-    return connection_->transport_version();
-  }
-
-  void CloseStream(QuicStreamId id) { session_->CloseStream(id); }
+  QuicTransportVersion transport_version() const { return QUIC_VERSION_99; }
 
   QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_CLIENT) +
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_CLIENT) +
            kV99StreamIdIncrement * n;
   }
 
   QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_CLIENT) +
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_CLIENT) +
            kV99StreamIdIncrement * n;
   }
 
   QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
-    return QuicUtils::GetFirstBidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_SERVER) +
+    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
+                                                    Perspective::IS_SERVER) +
            kV99StreamIdIncrement * n;
   }
 
   QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
-    return QuicUtils::GetFirstUnidirectionalStreamId(
-               connection_->transport_version(), Perspective::IS_SERVER) +
+    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
+                                                     Perspective::IS_SERVER) +
            kV99StreamIdIncrement * n;
   }
 
@@ -172,11 +90,8 @@
   bool IsUnidi() { return GetParam() ? false : true; }
   bool IsBidi() { return GetParam(); }
 
-  MockQuicConnectionHelper helper_;
-  MockAlarmFactory alarm_factory_;
-  StrictMock<MockQuicConnection>* connection_;
-  std::unique_ptr<TestQuicSession> session_;
-  QuicStreamIdManager* stream_id_manager_;
+  StrictMock<MockDelegate> delegate_;
+  QuicStreamIdManager stream_id_manager_;
 };
 
 // Following tests are either client-specific (they depend, in some way, on
@@ -200,29 +115,29 @@
   // These fields are inited via the QuicSession constructor to default
   // values defined as a constant.
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->outgoing_max_streams());
+            stream_id_manager_.outgoing_max_streams());
 
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->incoming_actual_max_streams());
+            stream_id_manager_.incoming_actual_max_streams());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->incoming_advertised_max_streams());
+            stream_id_manager_.incoming_advertised_max_streams());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->incoming_initial_max_open_streams());
+            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 / kMaxStreamsWindowDivisor,
-            stream_id_manager_->max_streams_window());
+            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(QuicStreamIdManagerTestClient, CheckMaxStreamsWindow1) {
-  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());
+  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());
   // If streamid_count/2==0 (integer math) force it to 1.
-  EXPECT_EQ(1u, stream_id_manager_->max_streams_window());
+  EXPECT_EQ(1u, stream_id_manager_.max_streams_window());
 }
 
 // Now check that setting to a value larger than the maximum fails.
@@ -232,12 +147,13 @@
       QuicUtils::GetMaxStreamCount(!GetParam(), /* GetParam==true for bidi */
                                    Perspective::IS_CLIENT);
   // Ensure that the limit is less than the implementation maximum.
-  EXPECT_LT(stream_id_manager_->outgoing_max_streams(), implementation_max);
+  EXPECT_LT(stream_id_manager_.outgoing_max_streams(), implementation_max);
 
   // Try to go over.
-  stream_id_manager_->SetMaxOpenOutgoingStreams(implementation_max + 1);
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  stream_id_manager_.SetMaxOpenOutgoingStreams(implementation_max + 1);
   // Should be pegged at the max.
-  EXPECT_EQ(implementation_max, stream_id_manager_->outgoing_max_streams());
+  EXPECT_EQ(implementation_max, stream_id_manager_.outgoing_max_streams());
 }
 
 // Now do the same for the incoming streams
@@ -245,79 +161,70 @@
   QuicStreamCount implementation_max =
       QuicUtils::GetMaxStreamCount(!GetParam(), /* GetParam==true for bidi */
                                    Perspective::IS_CLIENT);
-  stream_id_manager_->SetMaxOpenIncomingStreams(implementation_max - 1u);
+  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max - 1u);
   EXPECT_EQ(implementation_max - 1u,
-            stream_id_manager_->incoming_initial_max_open_streams());
+            stream_id_manager_.incoming_initial_max_open_streams());
   EXPECT_EQ(implementation_max - 1u,
-            stream_id_manager_->incoming_actual_max_streams());
+            stream_id_manager_.incoming_actual_max_streams());
   EXPECT_EQ((implementation_max - 1u) / 2u,
-            stream_id_manager_->max_streams_window());
+            stream_id_manager_.max_streams_window());
 
-  stream_id_manager_->SetMaxOpenIncomingStreams(implementation_max);
+  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max);
   EXPECT_EQ(implementation_max,
-            stream_id_manager_->incoming_initial_max_open_streams());
+            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());
+            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());
+  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);
+  stream_id_manager_.SetMaxOpenIncomingStreams(implementation_max + 1);
   EXPECT_EQ(implementation_max,
-            stream_id_manager_->incoming_initial_max_open_streams());
+            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());
+            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(QuicStreamIdManagerTestClient, ProcessStreamsBlockedOk) {
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
+  // 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() - 1;
-  QuicStreamsBlockedFrame frame(0, stream_count, /*unidirectional=*/false);
-
-  // Simulate being configured so that the MAX_STREAMS is transmitted.
-  session_->OnConfigNegotiated();
-
-  session_->OnStreamsBlockedFrame(frame);
-
-  // We should see a MAX_STREAMS frame.
-  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
-
-  // and it should advertise the current max-allowed value.
-  EXPECT_EQ(stream_id_manager_->incoming_initial_max_open_streams(),
-            session_->save_frame().max_streams_frame.stream_count);
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count - 1, IsUnidi());
+  EXPECT_CALL(delegate_, SendMaxStreams(stream_count, IsUnidi()));
+  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(QuicStreamIdManagerTestClient, ProcessStreamsBlockedNoOp) {
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
   QuicStreamCount stream_count =
-      stream_id_manager_->incoming_initial_max_open_streams();
-  QuicStreamsBlockedFrame frame(0, stream_count, /*unidirectional=*/false);
-  session_->OnStreamsBlockedFrame(frame);
+      stream_id_manager_.incoming_initial_max_open_streams();
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidi());
+  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(QuicStreamIdManagerTestClient, ProcessStreamsBlockedTooBig) {
-  EXPECT_CALL(*connection_, CloseConnection(QUIC_STREAMS_BLOCKED_ERROR, _, _));
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  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, /*unidirectional=*/false);
-  session_->OnStreamsBlockedFrame(frame);
+      stream_id_manager_.incoming_initial_max_open_streams() + 1;
+  QuicStreamsBlockedFrame frame(0, stream_count, IsUnidi());
+  stream_id_manager_.OnStreamsBlockedFrame(frame);
 }
 
 // Same basic tests as above, but calls
@@ -328,33 +235,31 @@
 // First test make sure that streams with ids below the limit are accepted.
 TEST_P(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidBelowLimit) {
   QuicStreamId stream_id =
-      StreamCountToId(stream_id_manager_->incoming_actual_max_streams() - 1,
+      StreamCountToId(stream_id_manager_.incoming_actual_max_streams() - 1,
                       Perspective::IS_CLIENT);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
+  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(QuicStreamIdManagerTestClient, IsIncomingStreamIdValidAtLimit) {
-  QuicStreamId stream_id =
-      StreamCountToId(stream_id_manager_->incoming_actual_max_streams(),
-                      Perspective::IS_CLIENT);
-  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
+  QuicStreamId stream_id = StreamCountToId(
+      stream_id_manager_.incoming_actual_max_streams(), Perspective::IS_CLIENT);
+  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(QuicStreamIdManagerTestClient, IsIncomingStreamIdInValidAboveLimit) {
   QuicStreamId stream_id = StreamCountToId(
-      stream_id_manager_->incoming_actual_max_streams() + 1,
+      stream_id_manager_.incoming_actual_max_streams() + 1,
       Perspective::IS_SERVER);  // This node is a client, incoming
                                 // stream ids must be server-originated.
   std::string error_details =
       GetParam() ? "Stream id 401 would exceed stream count limit 100"
                  : "Stream id 403 would exceed stream count limit 100";
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
-  EXPECT_FALSE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
+  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, error_details));
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
 }
 
 // Test functionality for reception of a MAX_STREAMS frame. This code is
@@ -365,7 +270,7 @@
       // 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();
+      stream_id_manager_.outgoing_max_streams();
 
   QuicMaxStreamsFrame frame;
 
@@ -376,27 +281,29 @@
   frame.stream_count = initial_stream_count - 1;
 
   frame.unidirectional = IsUnidi();
-  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  EXPECT_TRUE(stream_id_manager_.OnMaxStreamsFrame(frame));
   EXPECT_EQ(initial_stream_count - 1u,
-            stream_id_manager_->outgoing_max_streams());
+            stream_id_manager_.outgoing_max_streams());
 
   QuicStreamCount save_outgoing_max_streams =
-      stream_id_manager_->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 = IsUnidi();
-  EXPECT_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  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());
+            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_TRUE(stream_id_manager_->OnMaxStreamsFrame(frame));
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  EXPECT_TRUE(stream_id_manager_.OnMaxStreamsFrame(frame));
 
   EXPECT_EQ(initial_stream_count + 1u,
-            stream_id_manager_->outgoing_max_streams());
+            stream_id_manager_.outgoing_max_streams());
 }
 
 // Test functionality for reception of a STREAMS_BLOCKED frame.
@@ -404,9 +311,10 @@
 TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerOnStreamsBlockedFrame) {
   // Get the current maximum allowed incoming stream count.
   QuicStreamCount advertised_stream_count =
-      stream_id_manager_->incoming_advertised_max_streams();
-  // Simulate receiving a config to allow frame transmission
-  session_->OnConfigNegotiated();
+      stream_id_manager_.incoming_advertised_max_streams();
+
+  // Set the config negotiated to allow frame transmission.
+  stream_id_manager_.OnConfigNegotiated();
 
   QuicStreamsBlockedFrame frame;
 
@@ -415,14 +323,14 @@
   // 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(*connection_, SendControlFrame(_)).Times(0);
-  EXPECT_TRUE(stream_id_manager_->OnStreamsBlockedFrame(frame));
+  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(*connection_, CloseConnection(QUIC_STREAMS_BLOCKED_ERROR, _, _));
-  EXPECT_FALSE(stream_id_manager_->OnStreamsBlockedFrame(frame));
+  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
@@ -430,16 +338,16 @@
   // 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();
+      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_));
+  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);
+            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
@@ -450,19 +358,14 @@
   // MAX_STREAMS sent earler.
   frame.stream_count = advertised_stream_count;
 
-  EXPECT_CALL(*connection_, SendControlFrame(_))
-      .Times(1)
-      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
+  EXPECT_CALL(delegate_,
+              SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+                             IsUnidi()));
 
-  EXPECT_TRUE(stream_id_manager_->OnStreamsBlockedFrame(frame));
+  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());
-  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
-  EXPECT_EQ(stream_id_manager_->incoming_advertised_max_streams(),
-            session_->save_frame().max_streams_frame.stream_count);
-  // Make sure that this is the only MAX_STREAMS
-  EXPECT_EQ(1u, GetControlFrameId(session_->save_frame()));
+  EXPECT_EQ(stream_id_manager_.incoming_actual_max_streams(),
+            stream_id_manager_.incoming_advertised_max_streams());
 }
 
 // Test GetNextOutgoingStream. This is client/server agnostic.
@@ -471,41 +374,34 @@
   // opening...
   size_t number_of_streams = kDefaultMaxStreamsPerConnection;
 
-  // Set up config to allow the default stream limit and then
-  // simulate receiving a config to allow frame transmission
-  QuicConfigPeer::SetReceivedMaxIncomingUnidirectionalStreams(
-      session_->config(), kDefaultMaxStreamsPerConnection);
-  QuicConfigPeer::SetReceivedMaxIncomingBidirectionalStreams(
-      session_->config(), kDefaultMaxStreamsPerConnection);
-  session_->OnConfigNegotiated();
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  stream_id_manager_.SetMaxOpenOutgoingStreams(100);
+
+  stream_id_manager_.OnConfigNegotiated();
 
   QuicStreamId stream_id =
-      IsUnidi() ? session_->next_outgoing_unidirectional_stream_id()
-                : session_->next_outgoing_bidirectional_stream_id();
+      IsUnidi() ? QuicUtils::GetFirstUnidirectionalStreamId(
+                      QUIC_VERSION_99, stream_id_manager_.perspective())
+                : QuicUtils::GetFirstBidirectionalStreamId(
+                      QUIC_VERSION_99, stream_id_manager_.perspective());
 
-  EXPECT_EQ(number_of_streams, stream_id_manager_->outgoing_max_streams());
+  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());
+    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(*connection_, SendControlFrame(_))
-      .Times(1)
-      .WillRepeatedly(Invoke(session_.get(), &TestQuicSession::SaveFrame));
-  EXPECT_FALSE(stream_id_manager_->CanOpenNextOutgoingStream());
-  EXPECT_EQ(STREAMS_BLOCKED_FRAME, session_->save_frame().type);
-  // If bidi, Crypto stream default created  at start up, it is one
-  // more stream to account for since initialization is "number of
-  // request/responses" & crypto is added in to that, not streams.
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            session_->save_frame().max_streams_frame.stream_count);
+  EXPECT_CALL(delegate_,
+              SendStreamsBlocked(kDefaultMaxStreamsPerConnection, IsUnidi()));
+  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(),
+      stream_id_manager_.GetNextOutgoingStreamId(),
       "Attempt to allocate a new outgoing stream that would exceed the limit");
 }
 
@@ -513,27 +409,26 @@
 // server/client agnostic.
 TEST_P(QuicStreamIdManagerTestClient,
        StreamIdManagerServerMaybeIncreaseLargestPeerStreamId) {
-  QuicStreamId max_stream_id =
-      StreamCountToId(stream_id_manager_->incoming_actual_max_streams(),
-                      Perspective::IS_SERVER);
+  QuicStreamId max_stream_id = StreamCountToId(
+      stream_id_manager_.incoming_actual_max_streams(), Perspective::IS_SERVER);
   EXPECT_TRUE(
-      stream_id_manager_->MaybeIncreaseLargestPeerStreamId(max_stream_id));
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(max_stream_id));
 
   QuicStreamId server_initiated_stream_id =
       StreamCountToId(1u,  // get 1st id
                       Perspective::IS_SERVER);
-  EXPECT_TRUE(stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
+  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(
+  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, _));
+  EXPECT_FALSE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
       max_stream_id + kV99StreamIdIncrement));
 }
 
 // Test the MAX STREAMS Window functionality.
 TEST_P(QuicStreamIdManagerTestClient, StreamIdManagerServerMaxStreams) {
-  // Simulate completed config to allow frame transmission
-  session_->OnConfigNegotiated();
+  // 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.
@@ -543,96 +438,89 @@
   // 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;
+  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(*connection_, SendControlFrame(_)).Times(0);
+  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 = IsBidi() ? GetNthServerInitiatedBidirectionalId(0)
                                     : GetNthServerInitiatedUnidirectionalId(0);
   size_t old_available_incoming_streams =
-      stream_id_manager_->available_incoming_streams();
+      stream_id_manager_.available_incoming_streams();
   while (stream_count) {
-    EXPECT_TRUE(
-        stream_id_manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
+    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_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_count = stream_id_manager_.max_streams_window();
   stream_id = IsBidi() ? GetNthServerInitiatedBidirectionalId(0)
                        : GetNthServerInitiatedUnidirectionalId(0);
   QuicStreamCount expected_actual_max =
-      stream_id_manager_->incoming_actual_max_streams();
+      stream_id_manager_.incoming_actual_max_streams();
   QuicStreamCount expected_advertised_max_streams =
-      stream_id_manager_->incoming_advertised_max_streams();
+      stream_id_manager_.incoming_advertised_max_streams();
   while (stream_count) {
-    stream_id_manager_->OnStreamClosed(stream_id);
+    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());
+              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());
+              stream_id_manager_.incoming_advertised_max_streams());
   }
 
   // This should not change.
   EXPECT_EQ(old_available_incoming_streams,
-            stream_id_manager_->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(*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 STREAMS was sent and has the correct values.
-  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
-  EXPECT_EQ(stream_id_manager_->incoming_advertised_max_streams(),
-            session_->save_frame().max_streams_frame.stream_count);
+  //  EXPECT_CALL(delegate_,
+  //  SendMaxStreams(stream_id_manager_.incoming_actual_max_streams(),
+  //  IsUnidi()));
+  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidi()));
+  EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(stream_id));
+  stream_id_manager_.OnStreamClosed(stream_id);
 }
 
 // Check that edge conditions of the stream count in a STREAMS_BLOCKED frame
 // are. properly handled.
 TEST_P(QuicStreamIdManagerTestClient, StreamsBlockedEdgeConditions) {
-  // Simulate completed config to allow frame transmission
-  session_->OnConfigNegotiated();
+  // Set the config negotiated to allow frame transmission.
+  stream_id_manager_.OnConfigNegotiated();
 
   QuicStreamsBlockedFrame frame;
   frame.unidirectional = IsUnidi();
 
   // Check that receipt of a STREAMS BLOCKED with stream-count = 0 does nothing
   // when max_allowed_incoming_streams is 0.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-  stream_id_manager_->SetMaxOpenIncomingStreams(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);
+  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(*connection_, SendControlFrame(_))
-      .Times(1)
-      .WillOnce(Invoke(session_.get(), &TestQuicSession::SaveFrame));
-  stream_id_manager_->SetMaxOpenIncomingStreams(123);
+  EXPECT_CALL(delegate_, SendMaxStreams(123u, IsUnidi()));
+  EXPECT_CALL(delegate_, SendStreamsBlocked(_, _)).Times(0);
+  stream_id_manager_.SetMaxOpenIncomingStreams(123);
   frame.stream_count = 0;
-  stream_id_manager_->OnStreamsBlockedFrame(frame);
-  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
-  EXPECT_EQ(123u, session_->save_frame().max_streams_frame.stream_count);
+  stream_id_manager_.OnStreamsBlockedFrame(frame);
 }
 
 TEST_P(QuicStreamIdManagerTestClient, HoldMaxStreamsFrame) {
@@ -640,21 +528,18 @@
     return;
   }
 
-  // The session has not been configured so frame transmission will not be
-  // allowed.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  // 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, QuicStreamIdManagerPeer::get_unidirectional(stream_id_manager_));
+  QuicStreamsBlockedFrame frame(1u, 0u, IsUnidi());
   // Should cause change in pending_max_streams.
-  stream_id_manager_->OnStreamsBlockedFrame(frame);
-  // Will do OnConfig. We should see a control frame pop out now.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
+  stream_id_manager_.OnStreamsBlockedFrame(frame);
 
-  // Now allow frame transmission -- which happens when the QuicSession
-  // receives the configuration and calls
-  // QuicStreamIdManager::OnConfigNegotiated()
-  session_->OnConfigNegotiated();
+  EXPECT_CALL(delegate_, SendMaxStreams(_, IsUnidi()));
+
+  // MAX_STREAMS will be sent now that the config has been negotiated.
+  stream_id_manager_.OnConfigNegotiated();
 }
 
 // Following tests all are server-specific. They depend, in some way, on
@@ -673,25 +558,21 @@
 
   // set outgoing limit to 0, will cause the CanOpenNext... to fail
   // leading to a STREAMS_BLOCKED.
-  QuicStreamIdManagerPeer::set_outgoing_max_streams(stream_id_manager_, 0);
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  stream_id_manager_.SetMaxOpenOutgoingStreams(0);
 
-  // We should not see a STREAMS-BLOCKED frame because we're not configured..
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(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
+  // false and have forced a STREAMS_BLOCKED to be queued up, with the
   // blocked stream id == 0.
-  EXPECT_FALSE(stream_id_manager_->CanOpenNextOutgoingStream());
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
 
-  // Simulate receipt of the configuration; This case does not update the
-  // outgoing stream limit, so the on-config should result in a streams-blocked
-  // being sent.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(1);
-  QuicConfigPeer::SetReceivedMaxIncomingUnidirectionalStreams(
-      session_->config(), 0);
-  QuicConfigPeer::SetReceivedMaxIncomingBidirectionalStreams(session_->config(),
-                                                             0);
-  session_->OnConfigNegotiated();
+  // Since the steam limit has not been increased when the config was negotiated
+  // a STREAMS_BLOCKED frame should be sent.
+  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidi()));
+  stream_id_manager_.OnConfigNegotiated();
 }
 
 TEST_P(QuicStreamIdManagerTestClient, HoldStreamsBlockedFrameNoXmit) {
@@ -700,28 +581,22 @@
   }
   // Set outgoing limit to 0, will cause the CanOpenNext... to fail
   // leading to a STREAMS_BLOCKED.
-  QuicStreamIdManagerPeer::set_outgoing_max_streams(stream_id_manager_, 0);
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  stream_id_manager_.SetMaxOpenOutgoingStreams(0);
 
-  // We should not see a STREAMS-BLOCKED frame because we're not configured..
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
+  // We should not see a STREAMS_BLOCKED frame because we're not configured..
+  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidi())).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
+  // false and have forced a STREAMS_BLOCKED to be queued up, with the
   // blocked stream id == 0.
-  EXPECT_FALSE(stream_id_manager_->CanOpenNextOutgoingStream());
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
 
-  // Since the config gives some streams to create, we should not see
-  // a STREAMS-BLOCKED frame.
-  EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
-
-  // Do the configuration.  The stream limits are increased, allowing this
-  // node to create more streams, so we should not see the pending
-  // STREAMS-BLOCKED frame get transmitted.
-  QuicConfigPeer::SetReceivedMaxIncomingUnidirectionalStreams(
-      session_->config(), 10);
-  QuicConfigPeer::SetReceivedMaxIncomingBidirectionalStreams(session_->config(),
-                                                             10);
-  session_->OnConfigNegotiated();
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  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();
 }
 
 INSTANTIATE_TEST_SUITE_P(Tests,
@@ -733,86 +608,64 @@
 // stream id is correct.
 TEST_P(QuicStreamIdManagerTestServer, CheckMaxAllowedOutgoing) {
   const size_t kIncomingStreamCount = 123;
-  stream_id_manager_->SetMaxOpenOutgoingStreams(kIncomingStreamCount);
-  EXPECT_EQ(kIncomingStreamCount, stream_id_manager_->outgoing_max_streams());
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  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(QuicStreamIdManagerTestServer, MaxStreamsSlidingWindow) {
-  // 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();
+  stream_id_manager_.OnConfigNegotiated();
+
   QuicStreamCount first_advert =
-      stream_id_manager_->incoming_advertised_max_streams();
+      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());
+  int i = static_cast<int>(stream_id_manager_.max_streams_window());
   QuicStreamId id =
-      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(stream_id_manager_);
+      QuicStreamIdManagerPeer::GetFirstIncomingStreamId(&stream_id_manager_);
+  EXPECT_CALL(
+      delegate_,
+      SendMaxStreams(first_advert + stream_id_manager_.max_streams_window(),
+                     IsUnidi()));
   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_STREAMS to be sent.
-    stream->set_fin_received(true);
-    EXPECT_EQ(id, stream->id());
-    if (IsBidi()) {
-      // Only send reset for incoming bidirectional streams.
-      EXPECT_CALL(*session_, SendRstStream(_, _, _));
-    }
-    CloseStream(stream->id());
+    EXPECT_TRUE(stream_id_manager_.MaybeIncreaseLargestPeerStreamId(id));
+    stream_id_manager_.OnStreamClosed(id);
     i--;
     id += kV99StreamIdIncrement;
   }
-  EXPECT_EQ(MAX_STREAMS_FRAME, session_->save_frame().type);
-  QuicStreamCount second_advert =
-      session_->save_frame().max_streams_frame.stream_count;
-  EXPECT_EQ(first_advert + stream_id_manager_->max_streams_window(),
-            second_advert);
 }
 
 // Tast that an attempt to create an outgoing stream does not exceed the limit
 // and that it generates an appropriate STREAMS_BLOCKED frame.
 TEST_P(QuicStreamIdManagerTestServer, NewStreamDoesNotExceedLimit) {
-  // Configure with some number of streams, and allow frame transmission
-  QuicConfigPeer::SetReceivedMaxIncomingUnidirectionalStreams(
-      session_->config(), 100);
-  QuicConfigPeer::SetReceivedMaxIncomingBidirectionalStreams(session_->config(),
-                                                             100);
-  session_->OnConfigNegotiated();
+  EXPECT_CALL(delegate_, OnCanCreateNewOutgoingStream(IsUnidi()));
+  stream_id_manager_.SetMaxOpenOutgoingStreams(100);
+  stream_id_manager_.OnConfigNegotiated();
 
-  size_t stream_count = stream_id_manager_->outgoing_max_streams();
+  size_t stream_count = stream_id_manager_.outgoing_max_streams();
   EXPECT_NE(0u, stream_count);
-  TestQuicStream* stream;
+
   while (stream_count) {
-    stream = IsBidi() ? session_->CreateOutgoingBidirectionalStream()
-                      : session_->CreateOutgoingUnidirectionalStream();
-    EXPECT_NE(stream, nullptr);
+    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());
+  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(*connection_, SendControlFrame(_));
-  stream = IsBidi() ? session_->CreateOutgoingBidirectionalStream()
-                    : session_->CreateOutgoingUnidirectionalStream();
-  EXPECT_EQ(nullptr, stream);
+  EXPECT_CALL(delegate_, SendStreamsBlocked(_, IsUnidi()));
+  EXPECT_FALSE(stream_id_manager_.CanOpenNextOutgoingStream());
 }
 
 // Check that the parameters used by the stream ID manager are properly
@@ -821,27 +674,27 @@
   // These fields are inited via the QuicSession constructor to default
   // values defined as a constant.
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->incoming_initial_max_open_streams());
+            stream_id_manager_.incoming_initial_max_open_streams());
 
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->incoming_actual_max_streams());
+            stream_id_manager_.incoming_actual_max_streams());
   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            stream_id_manager_->outgoing_max_streams());
+            stream_id_manager_.outgoing_max_streams());
 
   // The window for advertising updates to the MAX STREAM ID is half the number
   // of stream allowed.
   EXPECT_EQ(kDefaultMaxStreamsPerConnection / kMaxStreamsWindowDivisor,
-            stream_id_manager_->max_streams_window());
+            stream_id_manager_.max_streams_window());
 }
 
 TEST_P(QuicStreamIdManagerTestServer, AvailableStreams) {
-  stream_id_manager_->MaybeIncreaseLargestPeerStreamId(
+  stream_id_manager_.MaybeIncreaseLargestPeerStreamId(
       IsBidi() ? GetNthClientInitiatedBidirectionalId(3)
                : GetNthClientInitiatedUnidirectionalId(3));
-  EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(
       IsBidi() ? GetNthClientInitiatedBidirectionalId(1)
                : GetNthClientInitiatedUnidirectionalId(1)));
-  EXPECT_TRUE(stream_id_manager_->IsAvailableStream(
+  EXPECT_TRUE(stream_id_manager_.IsAvailableStream(
       IsBidi() ? GetNthClientInitiatedBidirectionalId(2)
                : GetNthClientInitiatedUnidirectionalId(2)));
 }
@@ -851,7 +704,7 @@
 // This is a regression for Chromium bugs 909987 and 910040
 TEST_P(QuicStreamIdManagerTestServer, ExtremeMaybeIncreaseLargestPeerStreamId) {
   QuicStreamId too_big_stream_id = StreamCountToId(
-      stream_id_manager_->incoming_actual_max_streams() + 20,
+      stream_id_manager_.incoming_actual_max_streams() + 20,
       Perspective::IS_CLIENT);  // This node is a server, incoming stream
                                 // ids must be client-originated.
   std::string error_details;
@@ -865,10 +718,9 @@
     error_details = "Stream id 478 would exceed stream count limit 100";
   }
 
-  EXPECT_CALL(*connection_,
-              CloseConnection(QUIC_INVALID_STREAM_ID, error_details, _));
+  EXPECT_CALL(delegate_, OnError(QUIC_INVALID_STREAM_ID, error_details));
   EXPECT_FALSE(
-      stream_id_manager_->MaybeIncreaseLargestPeerStreamId(too_big_stream_id));
+      stream_id_manager_.MaybeIncreaseLargestPeerStreamId(too_big_stream_id));
 }
 
 }  // namespace