Track unacknowledged references on the encoder stream in QpackBlockingManager.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 263116461
Change-Id: I928d3b06dfbc8de7ad8995b739f49c65856237b2
diff --git a/quic/core/qpack/qpack_blocking_manager_test.cc b/quic/core/qpack/qpack_blocking_manager_test.cc
index a7cba73..6f78d87 100644
--- a/quic/core/qpack/qpack_blocking_manager_test.cc
+++ b/quic/core/qpack/qpack_blocking_manager_test.cc
@@ -206,6 +206,88 @@
manager_.smallest_blocking_index());
}
+TEST_F(QpackBlockingManagerTest,
+ ReferenceOnEncoderStreamUnblockedByInsertCountIncrement) {
+ EXPECT_EQ(0u, manager_.known_received_count());
+ EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+ manager_.smallest_blocking_index());
+
+ // Entry 1 refers to entry 0.
+ manager_.OnReferenceSentOnEncoderStream(1, 0);
+ // Entry 2 also refers to entry 0.
+ manager_.OnReferenceSentOnEncoderStream(2, 0);
+
+ EXPECT_EQ(0u, manager_.known_received_count());
+ EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+ // Acknowledging entry 1 still leaves one unacknowledged reference to entry 0.
+ manager_.OnInsertCountIncrement(2);
+
+ EXPECT_EQ(2u, manager_.known_received_count());
+ EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+ // Entry 3 also refers to entry 2.
+ manager_.OnReferenceSentOnEncoderStream(3, 2);
+
+ EXPECT_EQ(2u, manager_.known_received_count());
+ EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+ // Acknowledging entry 2 removes last reference to entry 0.
+ manager_.OnInsertCountIncrement(1);
+
+ EXPECT_EQ(3u, manager_.known_received_count());
+ EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+ // Acknowledging entry 4 (and implicitly 3) removes reference to entry 2.
+ manager_.OnInsertCountIncrement(2);
+
+ EXPECT_EQ(5u, manager_.known_received_count());
+ EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+ manager_.smallest_blocking_index());
+}
+
+TEST_F(QpackBlockingManagerTest,
+ ReferenceOnEncoderStreamUnblockedByHeaderAcknowledgement) {
+ EXPECT_EQ(0u, manager_.known_received_count());
+ EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+ manager_.smallest_blocking_index());
+
+ // Entry 1 refers to entry 0.
+ manager_.OnReferenceSentOnEncoderStream(1, 0);
+ // Entry 2 also refers to entry 0.
+ manager_.OnReferenceSentOnEncoderStream(2, 0);
+
+ EXPECT_EQ(0u, manager_.known_received_count());
+ EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+ // Acknowledging a header block with entries up to 1 still leave one
+ // unacknowledged reference to entry 0.
+ manager_.OnHeaderBlockSent(/* stream_id = */ 0, {0, 1});
+ manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
+
+ EXPECT_EQ(2u, manager_.known_received_count());
+ EXPECT_EQ(0u, manager_.smallest_blocking_index());
+
+ // Entry 3 also refers to entry 2.
+ manager_.OnReferenceSentOnEncoderStream(3, 2);
+
+ // Acknowledging a header block with entries up to 2 removes last reference to
+ // entry 0.
+ manager_.OnHeaderBlockSent(/* stream_id = */ 0, {2, 0, 2});
+ manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
+
+ EXPECT_EQ(3u, manager_.known_received_count());
+ EXPECT_EQ(2u, manager_.smallest_blocking_index());
+
+ // Acknowledging entry 4 (and implicitly 3) removes reference to entry 2.
+ manager_.OnHeaderBlockSent(/* stream_id = */ 0, {1, 4, 2, 0});
+ manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
+
+ EXPECT_EQ(5u, manager_.known_received_count());
+ EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
+ manager_.smallest_blocking_index());
+}
+
} // namespace
} // namespace test
} // namespace quic