mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-08 09:42:06 +03:00
Cancel delivery callbacks on skip
Summary: For the sender, upon egress or ingress skip we must check registered delivery callbacks and invoke `onCancel()` for each offset below the skipped offset. Reviewed By: mjoras Differential Revision: D15113113 fbshipit-source-id: 221badce8e92abde48e8ab2c8f3c1da9e506f54e
This commit is contained in:
committed by
Facebook Github Bot
parent
bea47aa54e
commit
6b49f4e42a
@@ -1097,6 +1097,62 @@ TEST_F(QuicTransportImplTest, DeliveryCallbackUnsetOne) {
|
||||
transport->close(folly::none);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, DeliveryCallbackOnSendDataExpire) {
|
||||
InSequence enforceOrder;
|
||||
|
||||
transport->transportConn->partialReliabilityEnabled = true;
|
||||
|
||||
auto stream1 = transport->createBidirectionalStream().value();
|
||||
auto stream2 = transport->createBidirectionalStream().value();
|
||||
MockDeliveryCallback dcb1;
|
||||
MockDeliveryCallback dcb2;
|
||||
|
||||
transport->registerDeliveryCallback(stream1, 10, &dcb1);
|
||||
transport->registerDeliveryCallback(stream2, 20, &dcb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _));
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _)).Times(0);
|
||||
|
||||
auto res = transport->sendDataExpired(stream1, 11);
|
||||
EXPECT_EQ(res.hasError(), false);
|
||||
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _));
|
||||
|
||||
transport->close(folly::none);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, DeliveryCallbackOnSendDataExpireCallbacksLeft) {
|
||||
InSequence enforceOrder;
|
||||
|
||||
transport->transportConn->partialReliabilityEnabled = true;
|
||||
|
||||
auto stream1 = transport->createBidirectionalStream().value();
|
||||
auto stream2 = transport->createBidirectionalStream().value();
|
||||
MockDeliveryCallback dcb1;
|
||||
MockDeliveryCallback dcb2;
|
||||
|
||||
transport->registerDeliveryCallback(stream1, 10, &dcb1);
|
||||
transport->registerDeliveryCallback(stream1, 20, &dcb1);
|
||||
transport->registerDeliveryCallback(stream2, 20, &dcb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _));
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _)).Times(0);
|
||||
|
||||
auto res = transport->sendDataExpired(stream1, 11);
|
||||
EXPECT_EQ(res.hasError(), false);
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _));
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _)).Times(1);
|
||||
|
||||
transport->close(folly::none);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, RegisterDeliveryCallbackLowerThanExpected) {
|
||||
auto stream = transport->createBidirectionalStream().value();
|
||||
MockDeliveryCallback dcb1;
|
||||
@@ -2166,6 +2222,98 @@ TEST_F(QuicTransportImplTest, DataRejecteddCallbackDataAvailable) {
|
||||
transport.reset();
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, DataRejecteddCallbackWithDeliveryCallbacks) {
|
||||
InSequence enforceOrder;
|
||||
|
||||
transport->transportConn->partialReliabilityEnabled = true;
|
||||
|
||||
auto stream1 = transport->createBidirectionalStream().value();
|
||||
auto stream2 = transport->createBidirectionalStream().value();
|
||||
|
||||
MockDeliveryCallback dcb1;
|
||||
MockDeliveryCallback dcb2;
|
||||
MockDataRejectedCallback dataRejectedCb1;
|
||||
MockDataRejectedCallback dataRejectedCb2;
|
||||
|
||||
transport->registerDeliveryCallback(stream1, 10, &dcb1);
|
||||
transport->registerDeliveryCallback(stream2, 20, &dcb2);
|
||||
|
||||
transport->setDataRejectedCallback(stream1, &dataRejectedCb1);
|
||||
transport->setDataRejectedCallback(stream2, &dataRejectedCb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(stream1, 10)).Times(1);
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dataRejectedCb1, onDataRejected(stream1, 15));
|
||||
transport->addMinStreamDataFrameToStream(
|
||||
MinStreamDataFrame(stream1, kDefaultStreamWindowSize, 15));
|
||||
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
Mock::VerifyAndClearExpectations(&dataRejectedCb1);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dcb2, onCanceled(stream2, 20)).Times(1);
|
||||
EXPECT_CALL(dataRejectedCb2, onDataRejected(stream2, 23));
|
||||
transport->addMinStreamDataFrameToStream(
|
||||
MinStreamDataFrame(stream2, kDefaultStreamWindowSize, 23));
|
||||
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
Mock::VerifyAndClearExpectations(&dataRejectedCb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _)).Times(0);
|
||||
transport->close(folly::none);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
QuicTransportImplTest,
|
||||
DataRejecteddCallbackWithDeliveryCallbacksSomeLeft) {
|
||||
InSequence enforceOrder;
|
||||
|
||||
transport->transportConn->partialReliabilityEnabled = true;
|
||||
|
||||
auto stream1 = transport->createBidirectionalStream().value();
|
||||
auto stream2 = transport->createBidirectionalStream().value();
|
||||
|
||||
MockDeliveryCallback dcb1;
|
||||
MockDeliveryCallback dcb2;
|
||||
MockDataRejectedCallback dataRejectedCb1;
|
||||
MockDataRejectedCallback dataRejectedCb2;
|
||||
|
||||
transport->registerDeliveryCallback(stream1, 10, &dcb1);
|
||||
transport->registerDeliveryCallback(stream1, 25, &dcb1);
|
||||
transport->registerDeliveryCallback(stream2, 20, &dcb2);
|
||||
transport->registerDeliveryCallback(stream2, 29, &dcb2);
|
||||
|
||||
transport->setDataRejectedCallback(stream1, &dataRejectedCb1);
|
||||
transport->setDataRejectedCallback(stream2, &dataRejectedCb2);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(stream1, 10)).Times(1);
|
||||
EXPECT_CALL(dcb2, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dataRejectedCb1, onDataRejected(stream1, 15));
|
||||
transport->addMinStreamDataFrameToStream(
|
||||
MinStreamDataFrame(stream1, kDefaultStreamWindowSize, 15));
|
||||
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
Mock::VerifyAndClearExpectations(&dataRejectedCb1);
|
||||
|
||||
EXPECT_CALL(dcb1, onCanceled(_, _)).Times(0);
|
||||
EXPECT_CALL(dcb2, onCanceled(stream2, 20)).Times(1);
|
||||
EXPECT_CALL(dataRejectedCb2, onDataRejected(stream2, 23));
|
||||
transport->addMinStreamDataFrameToStream(
|
||||
MinStreamDataFrame(stream2, kDefaultStreamWindowSize, 23));
|
||||
|
||||
Mock::VerifyAndClearExpectations(&dcb1);
|
||||
Mock::VerifyAndClearExpectations(&dcb2);
|
||||
Mock::VerifyAndClearExpectations(&dataRejectedCb2);
|
||||
|
||||
EXPECT_CALL(dcb2, onCanceled(stream2, 29)).Times(1);
|
||||
EXPECT_CALL(dcb1, onCanceled(stream1, 25)).Times(1);
|
||||
transport->close(folly::none);
|
||||
}
|
||||
|
||||
TEST_F(QuicTransportImplTest, DataRejectedCallbackChangeCallback) {
|
||||
transport->transportConn->partialReliabilityEnabled = true;
|
||||
|
||||
|
Reference in New Issue
Block a user