diff --git a/quic/api/QuicTransportBase.cpp b/quic/api/QuicTransportBase.cpp index 5678863bd..a72c12fc7 100644 --- a/quic/api/QuicTransportBase.cpp +++ b/quic/api/QuicTransportBase.cpp @@ -2127,6 +2127,17 @@ void QuicTransportBase::writeSocketData() { setIdleTimer(); conn_->receivedNewPacketBeforeWrite = false; } + // Check if we are app-limited after finish this round of sending + auto currentSendBufLen = conn_->flowControlState.sumCurStreamBufferLen; + auto lossBufferEmpty = !conn_->streamManager->hasLoss() && + conn_->cryptoState->initialStream.lossBuffer.empty() && + conn_->cryptoState->handshakeStream.lossBuffer.empty() && + conn_->cryptoState->oneRttStream.lossBuffer.empty(); + if (conn_->congestionController && + currentSendBufLen < conn_->udpSendPacketLen && lossBufferEmpty && + conn_->congestionController->getWritableBytes()) { + conn_->congestionController->setAppLimited(); + } } } // Writing data could write out an ack which could cause us to cancel diff --git a/quic/api/QuicTransportFunctions.cpp b/quic/api/QuicTransportFunctions.cpp index f9412ca10..26d6eb12c 100644 --- a/quic/api/QuicTransportFunctions.cpp +++ b/quic/api/QuicTransportFunctions.cpp @@ -366,7 +366,8 @@ void updateConnection( packetNum, (uint64_t)encodedSize, (int)isHandshake, - (int)pureAck); + (int)pureAck, + pkt.isAppLimited); conn.lossState.largestSent = std::max(conn.lossState.largestSent, packetNum); if (conn.congestionController && !pureAck) { conn.congestionController->onPacketSent(pkt); diff --git a/quic/api/test/QuicTransportBaseTest.cpp b/quic/api/test/QuicTransportBaseTest.cpp index 7eac924a6..1011dbcb4 100644 --- a/quic/api/test/QuicTransportBaseTest.cpp +++ b/quic/api/test/QuicTransportBaseTest.cpp @@ -1467,26 +1467,26 @@ INSTANTIATE_TEST_CASE_P( QuicTransportImplTestUniBidi, Values(true, false)); -TEST_P(QuicTransportImplTestUniBidi, AppLimitedTest) { +TEST_P(QuicTransportImplTestUniBidi, AppIdleTest) { auto& conn = transport->getConnectionState(); auto mockCongestionController = std::make_unique(); auto rawCongestionController = mockCongestionController.get(); conn.congestionController = std::move(mockCongestionController); - EXPECT_CALL(*rawCongestionController, setAppLimited(false, _)).Times(0); + EXPECT_CALL(*rawCongestionController, setAppIdle(false, _)).Times(0); auto stream = createStream(transport, GetParam()); - EXPECT_CALL(*rawCongestionController, setAppLimited(true, _)); + EXPECT_CALL(*rawCongestionController, setAppIdle(true, _)); transport->closeStream(stream); } -TEST_P(QuicTransportImplTestUniBidi, AppLimitedTestControlStreams) { +TEST_P(QuicTransportImplTestUniBidi, AppIdleTestControlStreams) { auto& conn = transport->getConnectionState(); auto mockCongestionController = std::make_unique(); auto rawCongestionController = mockCongestionController.get(); conn.congestionController = std::move(mockCongestionController); - EXPECT_CALL(*rawCongestionController, setAppLimited(false, _)).Times(0); + EXPECT_CALL(*rawCongestionController, setAppIdle(false, _)).Times(0); auto stream = createStream(transport, GetParam()); ASSERT_TRUE(stream); @@ -1497,25 +1497,25 @@ TEST_P(QuicTransportImplTestUniBidi, AppLimitedTestControlStreams) { ASSERT_TRUE(ctrlStream2); transport->setControlStream(ctrlStream2); - EXPECT_CALL(*rawCongestionController, setAppLimited(true, _)); + EXPECT_CALL(*rawCongestionController, setAppIdle(true, _)); transport->closeStream(stream); } -TEST_P(QuicTransportImplTestUniBidi, AppLimitedTestOnlyControlStreams) { +TEST_P(QuicTransportImplTestUniBidi, AppIdleTestOnlyControlStreams) { auto& conn = transport->getConnectionState(); auto mockCongestionController = std::make_unique(); auto rawCongestionController = mockCongestionController.get(); conn.congestionController = std::move(mockCongestionController); auto ctrlStream1 = createStream(transport, GetParam()); - EXPECT_CALL(*rawCongestionController, setAppLimited(true, _)).Times(1); + EXPECT_CALL(*rawCongestionController, setAppIdle(true, _)).Times(1); transport->setControlStream(ctrlStream1); - EXPECT_CALL(*rawCongestionController, setAppLimited(false, _)).Times(1); + EXPECT_CALL(*rawCongestionController, setAppIdle(false, _)).Times(1); auto ctrlStream2 = createStream(transport, GetParam()); - EXPECT_CALL(*rawCongestionController, setAppLimited(true, _)).Times(1); + EXPECT_CALL(*rawCongestionController, setAppIdle(true, _)).Times(1); transport->setControlStream(ctrlStream2); - EXPECT_CALL(*rawCongestionController, setAppLimited(_, _)).Times(0); + EXPECT_CALL(*rawCongestionController, setAppIdle(_, _)).Times(0); transport->closeStream(ctrlStream1); transport->closeStream(ctrlStream2); } diff --git a/quic/api/test/QuicTransportTest.cpp b/quic/api/test/QuicTransportTest.cpp index 1c74ab155..8d8003b27 100644 --- a/quic/api/test/QuicTransportTest.cpp +++ b/quic/api/test/QuicTransportTest.cpp @@ -358,8 +358,96 @@ TEST_F(QuicTransportTest, WriteDataWithProbing) { loopForWrites(); // Pending numProbePackets is cleared: EXPECT_EQ(0, conn.pendingEvents.numProbePackets); - // both write and onPacketSent will inquire getWritableBytes - EXPECT_EQ(onPacketSentCounter + socketWriteCounter, getWritableBytesCounter); + transport_->close(folly::none); +} + +TEST_F(QuicTransportTest, NotAppLimitedWithLoss) { + auto& conn = transport_->getConnectionState(); + // Replace with MockConnectionCallback: + auto mockCongestionController = std::make_unique(); + auto rawCongestionController = mockCongestionController.get(); + conn.congestionController = std::move(mockCongestionController); + EXPECT_CALL(*rawCongestionController, getWritableBytes()) + .WillRepeatedly(Return(5000)); + + auto stream = transport_->createBidirectionalStream().value(); + auto lossStream = transport_->createBidirectionalStream().value(); + conn.streamManager->addLoss(lossStream); + conn.streamManager->getStream(lossStream) + ->lossBuffer.emplace_back( + IOBuf::copyBuffer("Mountains may depart"), 0, false); + transport_->writeChain( + stream, + IOBuf::copyBuffer("An elephant sitting still"), + false, + false, + nullptr); + EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + loopForWrites(); + transport_->close(folly::none); +} + +TEST_F(QuicTransportTest, NotAppLimitedWithNoWritableBytes) { + auto& conn = transport_->getConnectionState(); + // Replace with MockConnectionCallback: + auto mockCongestionController = std::make_unique(); + auto rawCongestionController = mockCongestionController.get(); + conn.congestionController = std::move(mockCongestionController); + EXPECT_CALL(*rawCongestionController, getWritableBytes()) + .WillRepeatedly(Invoke([&]() { + if (conn.outstandingPackets.empty()) { + return 5000; + } + return 0; + })); + + auto stream = transport_->createBidirectionalStream().value(); + transport_->writeChain( + stream, + IOBuf::copyBuffer("An elephant sitting still"), + false, + false, + nullptr); + EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + loopForWrites(); + transport_->close(folly::none); +} + +TEST_F(QuicTransportTest, NotAppLimitedWithLargeBuffer) { + auto& conn = transport_->getConnectionState(); + // Replace with MockConnectionCallback: + auto mockCongestionController = std::make_unique(); + auto rawCongestionController = mockCongestionController.get(); + conn.congestionController = std::move(mockCongestionController); + EXPECT_CALL(*rawCongestionController, getWritableBytes()) + .WillRepeatedly(Return(5000)); + + auto stream = transport_->createBidirectionalStream().value(); + auto buf = buildRandomInputData(100 * 2000); + transport_->writeChain(stream, buf->clone(), false, false, nullptr); + EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(0); + loopForWrites(); + transport_->close(folly::none); +} + +TEST_F(QuicTransportTest, AppLimited) { + auto& conn = transport_->getConnectionState(); + // Replace with MockConnectionCallback: + auto mockCongestionController = std::make_unique(); + auto rawCongestionController = mockCongestionController.get(); + conn.congestionController = std::move(mockCongestionController); + EXPECT_CALL(*rawCongestionController, getWritableBytes()) + .WillRepeatedly(Return(5000)); + + auto stream = transport_->createBidirectionalStream().value(); + transport_->writeChain( + stream, + IOBuf::copyBuffer("An elephant sitting still"), + false, + false, + nullptr); + EXPECT_CALL(*rawCongestionController, setAppLimited()).Times(1); + loopForWrites(); transport_->close(folly::none); } diff --git a/quic/congestion_control/Copa.cpp b/quic/congestion_control/Copa.cpp index 7bd82e57e..e57980c1a 100644 --- a/quic/congestion_control/Copa.cpp +++ b/quic/congestion_control/Copa.cpp @@ -308,7 +308,10 @@ std::chrono::microseconds Copa::getPacingInterval() const noexcept { void Copa::setMinimalPacingInterval(std::chrono::microseconds) noexcept {} -void Copa::setAppLimited(bool, TimePoint) noexcept { /* unsupported */ +void Copa::setAppIdle(bool, TimePoint) noexcept { /* unsupported */ +} + +void Copa::setAppLimited() { /* unsupported */ } bool Copa::isAppLimited() const noexcept { diff --git a/quic/congestion_control/Copa.h b/quic/congestion_control/Copa.h index 9af3ae100..7fe8cca88 100644 --- a/quic/congestion_control/Copa.h +++ b/quic/congestion_control/Copa.h @@ -43,7 +43,8 @@ class Copa : public CongestionController { uint64_t getBytesInFlight() const noexcept; void setConnectionEmulation(uint8_t) noexcept override; - void setAppLimited(bool, TimePoint) noexcept override; + void setAppIdle(bool, TimePoint) noexcept override; + void setAppLimited() override; // pacing related functions, not implemented for copa bool canBePaced() const noexcept override; diff --git a/quic/congestion_control/NewReno.cpp b/quic/congestion_control/NewReno.cpp index 1d1d121df..46dda94ef 100644 --- a/quic/congestion_control/NewReno.cpp +++ b/quic/congestion_control/NewReno.cpp @@ -158,7 +158,10 @@ std::chrono::microseconds NewReno::getPacingInterval() const noexcept { void NewReno::setMinimalPacingInterval(std::chrono::microseconds) noexcept {} -void NewReno::setAppLimited(bool, TimePoint) noexcept { /* unsupported */ +void NewReno::setAppIdle(bool, TimePoint) noexcept { /* unsupported */ +} + +void NewReno::setAppLimited() { /* unsupported */ } bool NewReno::isAppLimited() const noexcept { diff --git a/quic/congestion_control/NewReno.h b/quic/congestion_control/NewReno.h index 94b0ac8dc..deb1a7599 100644 --- a/quic/congestion_control/NewReno.h +++ b/quic/congestion_control/NewReno.h @@ -27,7 +27,9 @@ class NewReno : public CongestionController { uint64_t getCongestionWindow() const noexcept override; void setConnectionEmulation(uint8_t) noexcept override; bool canBePaced() const noexcept override; - void setAppLimited(bool, TimePoint) noexcept override; + void setAppIdle(bool, TimePoint) noexcept override; + void setAppLimited() override; + CongestionControlType type() const noexcept override; bool inSlowStart() const noexcept; diff --git a/quic/congestion_control/QuicCubic.cpp b/quic/congestion_control/QuicCubic.cpp index 605bd7593..a9ee26c7a 100644 --- a/quic/congestion_control/QuicCubic.cpp +++ b/quic/congestion_control/QuicCubic.cpp @@ -154,11 +154,11 @@ bool Cubic::canBePaced() const noexcept { return pacingEnabled; } -void Cubic::setAppLimited(bool limited, TimePoint eventTime) noexcept { +void Cubic::setAppIdle(bool idle, TimePoint eventTime) noexcept { QUIC_TRACE( - cubic_applimited, + cubic_appidle, conn_, - limited, + idle, std::chrono::duration_cast( eventTime.time_since_epoch()) .count(), @@ -167,22 +167,32 @@ void Cubic::setAppLimited(bool limited, TimePoint eventTime) noexcept { steadyState_.lastReductionTime->time_since_epoch()) .count() : -1); - bool currentAppLimited = isAppLimited(); - if (!currentAppLimited && limited) { + bool currentAppIdle = isAppIdle(); + if (!currentAppIdle && idle) { quiescenceStart_ = eventTime; } - if (!limited && currentAppLimited && *quiescenceStart_ <= eventTime && + if (!idle && currentAppIdle && *quiescenceStart_ <= eventTime && steadyState_.lastReductionTime) { *steadyState_.lastReductionTime += std::chrono::duration_cast( eventTime - *quiescenceStart_); } - if (!limited) { + if (!idle) { quiescenceStart_ = folly::none; } } +void Cubic::setAppLimited() { + // we use app-idle for Cubic +} + bool Cubic::isAppLimited() const noexcept { + // Or maybe always false. This doesn't really matter for Cubic. Channeling + // isAppIdle() makes testing easier. + return isAppIdle(); +} + +bool Cubic::isAppIdle() const noexcept { return quiescenceStart_.hasValue(); } diff --git a/quic/congestion_control/QuicCubic.h b/quic/congestion_control/QuicCubic.h index 5fc95926b..5b00dd2ed 100644 --- a/quic/congestion_control/QuicCubic.h +++ b/quic/congestion_control/QuicCubic.h @@ -97,7 +97,8 @@ class Cubic : public CongestionController { uint64_t getCongestionWindow() const noexcept override; bool canBePaced() const noexcept override; void setConnectionEmulation(uint8_t) noexcept override; - void setAppLimited(bool limited, TimePoint eventTime) noexcept override; + void setAppIdle(bool idle, TimePoint eventTime) noexcept override; + void setAppLimited() override; bool isAppLimited() const noexcept override; @@ -116,6 +117,7 @@ class Cubic : public CongestionController { CubicStates state_{CubicStates::Hystart}; private: + bool isAppIdle() const noexcept; void onPacketAcked(const AckEvent& ack); void onPacketAckedInHystart(const AckEvent& ack); void onPacketAckedInSteady(const AckEvent& ack); diff --git a/quic/congestion_control/test/CubicTest.cpp b/quic/congestion_control/test/CubicTest.cpp index 3f7822f22..1c9e84b27 100644 --- a/quic/congestion_control/test/CubicTest.cpp +++ b/quic/congestion_control/test/CubicTest.cpp @@ -124,7 +124,7 @@ TEST_F(CubicTest, CwndIncreaseAfterReduction) { EXPECT_EQ(CubicStates::Steady, cubic.state()); } -TEST_F(CubicTest, AppLimited) { +TEST_F(CubicTest, AppIdle) { QuicConnectionStateBase conn(QuicNodeType::Client); conn.udpSendPacketLen = 1500; TestingCubic cubic(conn); @@ -150,7 +150,7 @@ TEST_F(CubicTest, AppLimited) { EXPECT_GT(cubic.getCongestionWindow(), cwnd); cwnd = cubic.getCongestionWindow(); - cubic.setAppLimited(true, reductionTime + 1100ms); + cubic.setAppIdle(true, reductionTime + 1100ms); EXPECT_TRUE(cubic.isAppLimited()); auto packet2 = makeTestingWritePacket(2, 1000, 3000); cubic.onPacketSent(packet2); @@ -159,7 +159,7 @@ TEST_F(CubicTest, AppLimited) { EXPECT_EQ(cubic.getCongestionWindow(), cwnd); // 1 seconds of quiescence - cubic.setAppLimited(false, reductionTime + 2100ms); + cubic.setAppIdle(false, reductionTime + 2100ms); EXPECT_FALSE(cubic.isAppLimited()); auto packet3 = makeTestingWritePacket(3, 1000, 4000); cubic.onPacketSent(packet3); diff --git a/quic/state/QuicStreamManager.cpp b/quic/state/QuicStreamManager.cpp index 2756c955c..f90ecf76d 100644 --- a/quic/state/QuicStreamManager.cpp +++ b/quic/state/QuicStreamManager.cpp @@ -153,7 +153,7 @@ QuicStreamManager::getOrCreateOpenedLocalStream(StreamId streamId) { QuicStreamState* QuicStreamManager::getStream(StreamId streamId) { if (isRemoteStream(nodeType_, streamId)) { auto stream = getOrCreatePeerStream(streamId); - updateAppLimitedState(); + updateAppIdleState(); return stream; } auto it = streams_.find(streamId); @@ -169,7 +169,7 @@ QuicStreamState* QuicStreamManager::getStream(StreamId streamId) { "Trying to get unopened local stream", TransportErrorCode::STREAM_STATE_ERROR); } - updateAppLimitedState(); + updateAppIdleState(); return stream; } @@ -298,7 +298,7 @@ QuicStreamManager::createStream(StreamId streamId) { std::forward_as_tuple(streamId), std::forward_as_tuple(streamId, conn_)); QUIC_STATS(conn_.infoCallback, onNewQuicStream); - updateAppLimitedState(); + updateAppIdleState(); return &it.first->second; } @@ -342,7 +342,7 @@ void QuicStreamManager::removeClosedStream(StreamId streamId) { openLocalStreams_.erase(streamItr); } } - updateAppLimitedState(); + updateAppIdleState(); } void QuicStreamManager::updateLossStreams(QuicStreamState& stream) { @@ -403,18 +403,18 @@ void QuicStreamManager::updatePeekableStreams(QuicStreamState& stream) { } } -void QuicStreamManager::updateAppLimitedState() { +void QuicStreamManager::updateAppIdleState() { bool currentNonCtrlStreams = hasNonCtrlStreams(); - if (isAppLimited_ && !currentNonCtrlStreams) { + if (isAppIdle_ && !currentNonCtrlStreams) { // We were app limited, and we continue to be app limited. return; - } else if (!isAppLimited_ && currentNonCtrlStreams) { + } else if (!isAppIdle_ && currentNonCtrlStreams) { // We were not app limited, and we continue to be not app limited. return; } - isAppLimited_ = !currentNonCtrlStreams; + isAppIdle_ = !currentNonCtrlStreams; if (conn_.congestionController) { - conn_.congestionController->setAppLimited(isAppLimited_, Clock::now()); + conn_.congestionController->setAppIdle(isAppIdle_, Clock::now()); } } @@ -423,10 +423,10 @@ void QuicStreamManager::setStreamAsControl(QuicStreamState& stream) { stream.isControl = true; numControlStreams_++; } - updateAppLimitedState(); + updateAppIdleState(); } -bool QuicStreamManager::isAppLimited() const { - return isAppLimited_; +bool QuicStreamManager::isAppIdle() const { + return isAppIdle_; } } // namespace quic diff --git a/quic/state/QuicStreamManager.h b/quic/state/QuicStreamManager.h index 8842bbe65..3ad506417 100644 --- a/quic/state/QuicStreamManager.h +++ b/quic/state/QuicStreamManager.h @@ -563,16 +563,16 @@ class QuicStreamManager { dataRejectedStreams_.clear(); } - bool isAppLimited() const; + bool isAppIdle() const; private: - // Updates the congestion controller app limited state, after a change in the + // Updates the congestion controller app-idle state, after a change in the // number of streams. - // App limited state is set to true if there was at least one non-control + // App-idle state is set to true if there was at least one non-control // before the update and there are none after. It is set to false if instead // there were no non-control streams before and there is at least one at the // time of calling - void updateAppLimitedState(); + void updateAppIdleState(); QuicStreamState* FOLLY_NULLABLE getOrCreateOpenedLocalStream(StreamId streamId); @@ -666,8 +666,8 @@ class QuicStreamManager { // Data structure to keep track of stream that have detected lost data std::vector lossStreams_; - // Record whether or not we are app limited. - bool isAppLimited_{false}; + // Record whether or not we are app-idle. + bool isAppIdle_{false}; }; } // namespace quic diff --git a/quic/state/StateData.h b/quic/state/StateData.h index 67647f3d7..79bdc4de1 100644 --- a/quic/state/StateData.h +++ b/quic/state/StateData.h @@ -218,15 +218,21 @@ struct CongestionController { * example, we probably don't want to pace a connection in Recovery. */ virtual bool canBePaced() const = 0; + /** + * Notify congestion controller that the connection has become idle or active + * in the sense that there are active non-control streams. + * idle: true if the connection has become app-idle, false if the + * connection has become not app-idle. + * eventTime: the time point when the app-idle state changed. + */ + virtual void setAppIdle(bool idle, TimePoint eventTime) = 0; + /** * Notify congestion controller that the connection has become app-limited or * not app-limited. * - * limited: true if the connection has become app-limited, false if the - * connection has become not app-limited. - * eventTime: the time point when the app-limited state changed. */ - virtual void setAppLimited(bool limited, TimePoint eventTime) = 0; + virtual void setAppLimited() = 0; virtual CongestionControlType type() const = 0; /** @@ -246,8 +252,7 @@ struct CongestionController { /** * Whether the congestion controller thinks it's currently in app-limited - * state. For some congestion controllers, e.g. BBR, the app-limited state may - * not be the same as the app. + * state. */ virtual bool isAppLimited() const = 0; }; diff --git a/quic/state/test/Mocks.h b/quic/state/test/Mocks.h index 425a071e0..ae908737a 100644 --- a/quic/state/test/Mocks.h +++ b/quic/state/test/Mocks.h @@ -37,7 +37,8 @@ class MockCongestionController : public CongestionController { , setMinimalPacingInterval, void(std::chrono::microseconds)); - GMOCK_METHOD2_(, , , setAppLimited, void(bool, TimePoint)); + GMOCK_METHOD2_(, , , setAppIdle, void(bool, TimePoint)); + MOCK_METHOD0(setAppLimited, void()); MOCK_CONST_METHOD0(isAppLimited, bool()); }; } // namespace test diff --git a/quic/state/test/QuicStreamManagerTest.cpp b/quic/state/test/QuicStreamManagerTest.cpp index 08012d839..f6732d248 100644 --- a/quic/state/test/QuicStreamManagerTest.cpp +++ b/quic/state/test/QuicStreamManagerTest.cpp @@ -44,140 +44,140 @@ class QuicStreamManagerTest : public Test { MockCongestionController* mockController; }; -TEST_F(QuicStreamManagerTest, TestAppLimitedCreateBidiStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleCreateBidiStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); // The app limiited state did not change. - EXPECT_CALL(*mockController, setAppLimited(false, _)).Times(0); + EXPECT_CALL(*mockController, setAppIdle(false, _)).Times(0); auto stream = manager.createNextBidirectionalStream(); StreamId id = stream.value()->id; - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); // Force transition to closed state stream.value()->send.state = StreamSendStates::Closed(); stream.value()->recv.state = StreamReceiveStates::Closed(); manager.removeClosedStream(stream.value()->id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); EXPECT_EQ(manager.getStream(id), nullptr); } -TEST_F(QuicStreamManagerTest, TestAppLimitedCreateUnidiStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleCreateUnidiStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); - EXPECT_CALL(*mockController, setAppLimited(false, _)).Times(0); + EXPECT_FALSE(manager.isAppIdle()); + EXPECT_CALL(*mockController, setAppIdle(false, _)).Times(0); auto stream = manager.createNextUnidirectionalStream(); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); // Force transition to closed state - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); stream.value()->send.state = StreamSendStates::Closed(); stream.value()->recv.state = StreamReceiveStates::Closed(); manager.removeClosedStream(stream.value()->id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); } -TEST_F(QuicStreamManagerTest, TestAppLimitedExistingLocalStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleExistingLocalStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); - EXPECT_CALL(*mockController, setAppLimited(false, _)).Times(0); + EXPECT_FALSE(manager.isAppIdle()); + EXPECT_CALL(*mockController, setAppIdle(false, _)).Times(0); auto stream = manager.createNextUnidirectionalStream(); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); manager.setStreamAsControl(*stream.value()); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); manager.getStream(stream.value()->id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); } -TEST_F(QuicStreamManagerTest, TestAppLimitedStreamAsControl) { +TEST_F(QuicStreamManagerTest, TestAppIdleStreamAsControl) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); auto stream = manager.createNextUnidirectionalStream(); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); manager.setStreamAsControl(*stream.value()); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(false, _)); + EXPECT_CALL(*mockController, setAppIdle(false, _)); manager.createNextUnidirectionalStream(); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); } -TEST_F(QuicStreamManagerTest, TestAppLimitedCreatePeerStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleCreatePeerStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); StreamId id = 0; auto stream = manager.getStream(id); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); manager.setStreamAsControl(*stream); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(false, _)); + EXPECT_CALL(*mockController, setAppIdle(false, _)); StreamId id2 = 4; manager.getStream(id2); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); } -TEST_F(QuicStreamManagerTest, TestAppLimitedExistingPeerStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleExistingPeerStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); - EXPECT_CALL(*mockController, setAppLimited(false, _)).Times(0); + EXPECT_FALSE(manager.isAppIdle()); + EXPECT_CALL(*mockController, setAppIdle(false, _)).Times(0); StreamId id = 0; auto stream = manager.getStream(id); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); manager.setStreamAsControl(*stream); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); manager.getStream(id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); } -TEST_F(QuicStreamManagerTest, TestAppLimitedClosePeerStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleClosePeerStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); StreamId id = 0; auto stream = manager.getStream(id); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); // Force transition to closed state stream->send.state = StreamSendStates::Closed(); stream->recv.state = StreamReceiveStates::Closed(); manager.removeClosedStream(stream->id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); EXPECT_EQ(manager.getStream(id), nullptr); } -TEST_F(QuicStreamManagerTest, TestAppLimitedCloseControlStream) { +TEST_F(QuicStreamManagerTest, TestAppIdleCloseControlStream) { auto& manager = *conn.streamManager; - EXPECT_FALSE(manager.isAppLimited()); - EXPECT_CALL(*mockController, setAppLimited(false, _)).Times(0); + EXPECT_FALSE(manager.isAppIdle()); + EXPECT_CALL(*mockController, setAppIdle(false, _)).Times(0); StreamId id = 0; auto stream = manager.getStream(id); - EXPECT_FALSE(manager.isAppLimited()); + EXPECT_FALSE(manager.isAppIdle()); - EXPECT_CALL(*mockController, setAppLimited(true, _)); + EXPECT_CALL(*mockController, setAppIdle(true, _)); manager.setStreamAsControl(*stream); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); // Force transition to closed state stream->send.state = StreamSendStates::Closed(); stream->recv.state = StreamReceiveStates::Closed(); manager.removeClosedStream(stream->id); - EXPECT_TRUE(manager.isAppLimited()); + EXPECT_TRUE(manager.isAppIdle()); } } // namespace test } // namespace quic