blob: a7cba733ee254c647591c78b5f783a709ec2de9d [file] [log] [blame]
// Copyright (c) 2019 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/qpack/qpack_blocking_manager.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
namespace quic {
namespace test {
namespace {
class QpackBlockingManagerTest : public QuicTest {
protected:
QpackBlockingManagerTest() = default;
~QpackBlockingManagerTest() override = default;
QpackBlockingManager manager_;
};
TEST_F(QpackBlockingManagerTest, Empty) {
EXPECT_EQ(0u, manager_.blocked_stream_count());
EXPECT_EQ(0u, manager_.known_received_count());
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
}
TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
manager_.OnInsertCountIncrement(2);
// Stream 0 is not blocked, because it only references entries that are
// already acknowledged by an Insert Count Increment instruction.
manager_.OnHeaderBlockSent(0, {1, 0});
EXPECT_EQ(0u, manager_.blocked_stream_count());
}
TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
manager_.OnHeaderBlockSent(0, {1, 0});
EXPECT_EQ(1u, manager_.blocked_stream_count());
manager_.OnInsertCountIncrement(2);
EXPECT_EQ(0u, manager_.blocked_stream_count());
}
TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
manager_.OnHeaderBlockSent(0, {2, 1, 1});
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(0u, manager_.blocked_stream_count());
// Stream 1 is not blocked, because it only references entries that are
// already acknowledged by a Header Acknowledgement instruction.
manager_.OnHeaderBlockSent(1, {2, 2});
EXPECT_EQ(0u, manager_.blocked_stream_count());
}
TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
manager_.OnHeaderBlockSent(0, {2, 1, 1});
manager_.OnHeaderBlockSent(1, {2, 2});
EXPECT_EQ(2u, manager_.blocked_stream_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(0u, manager_.blocked_stream_count());
}
TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
EXPECT_EQ(0u, manager_.known_received_count());
// Sending a header block does not change Known Received Count.
manager_.OnHeaderBlockSent(0, {0});
EXPECT_EQ(0u, manager_.known_received_count());
manager_.OnHeaderBlockSent(1, {1});
EXPECT_EQ(0u, manager_.known_received_count());
// Header Acknowledgement might increase Known Received Count.
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(1u, manager_.known_received_count());
manager_.OnHeaderBlockSent(2, {5});
EXPECT_EQ(1u, manager_.known_received_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
EXPECT_EQ(2u, manager_.known_received_count());
// Insert Count Increment increases Known Received Count.
manager_.OnInsertCountIncrement(2);
EXPECT_EQ(4u, manager_.known_received_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
EXPECT_EQ(6u, manager_.known_received_count());
// Stream Cancellation does not change Known Received Count.
manager_.OnStreamCancellation(0);
EXPECT_EQ(6u, manager_.known_received_count());
// Header Acknowledgement of a block with smaller Required Insert Count does
// not increase Known Received Count.
manager_.OnHeaderBlockSent(0, {3});
EXPECT_EQ(6u, manager_.known_received_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(6u, manager_.known_received_count());
// Header Acknowledgement of a block with equal Required Insert Count does not
// increase Known Received Count.
manager_.OnHeaderBlockSent(1, {5});
EXPECT_EQ(6u, manager_.known_received_count());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
EXPECT_EQ(6u, manager_.known_received_count());
}
TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(0, {0});
EXPECT_EQ(0u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(1, {2});
EXPECT_EQ(0u, manager_.smallest_blocking_index());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(2u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(1, {1});
EXPECT_EQ(1u, manager_.smallest_blocking_index());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
EXPECT_EQ(1u, manager_.smallest_blocking_index());
// Insert Count Increment does not change smallest blocking index.
manager_.OnInsertCountIncrement(2);
EXPECT_EQ(1u, manager_.smallest_blocking_index());
manager_.OnStreamCancellation(1);
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
}
TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
EXPECT_EQ(0u, manager_.known_received_count());
EXPECT_EQ(0u, manager_.blocked_stream_count());
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(0, {2, 1, 1});
EXPECT_EQ(0u, manager_.known_received_count());
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(1u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(0, {1, 0});
EXPECT_EQ(0u, manager_.known_received_count());
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(0u, manager_.smallest_blocking_index());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(3u, manager_.known_received_count());
EXPECT_EQ(0u, manager_.blocked_stream_count());
EXPECT_EQ(0u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(0, {3});
EXPECT_EQ(3u, manager_.known_received_count());
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(0u, manager_.smallest_blocking_index());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(3u, manager_.known_received_count());
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(3u, manager_.smallest_blocking_index());
EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
EXPECT_EQ(4u, manager_.known_received_count());
EXPECT_EQ(0u, manager_.blocked_stream_count());
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
}
TEST_F(QpackBlockingManagerTest, CancelStream) {
manager_.OnHeaderBlockSent(0, {3});
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(3u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(0, {2});
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(2u, manager_.smallest_blocking_index());
manager_.OnHeaderBlockSent(1, {4});
EXPECT_EQ(2u, manager_.blocked_stream_count());
EXPECT_EQ(2u, manager_.smallest_blocking_index());
manager_.OnStreamCancellation(0);
EXPECT_EQ(1u, manager_.blocked_stream_count());
EXPECT_EQ(4u, manager_.smallest_blocking_index());
manager_.OnStreamCancellation(1);
EXPECT_EQ(0u, manager_.blocked_stream_count());
EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
manager_.smallest_blocking_index());
}
} // namespace
} // namespace test
} // namespace quic