blob: ccc743632ec47885dc7722590a94e4af4880be58 [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_progressive_decoder.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_decoder_test_utils.h"
#include "net/third_party/quiche/src/quic/core/qpack/qpack_test_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
using ::testing::Eq;
using ::testing::Return;
using ::testing::StrictMock;
namespace quic {
namespace test {
namespace {
const uint64_t kMaximumDynamicTableCapacityForTesting = 1024 * 1024;
const QuicStreamId kStreamId = 0;
// Header Acknowledgement decoder stream instruction with stream_id = 0.
const char* const kHeaderAcknowledgement = "\x80";
class MockEnforcer
: public QpackProgressiveDecoder::BlockedStreamLimitEnforcer {
public:
~MockEnforcer() override = default;
MOCK_METHOD(bool, OnStreamBlocked, (QuicStreamId stream_id));
MOCK_METHOD(void, OnStreamUnblocked, (QuicStreamId stream_id));
};
class QpackProgressiveDecoderTest : public QuicTest {
protected:
QpackProgressiveDecoderTest()
: progressive_decoder_(kStreamId,
&enforcer_,
&header_table_,
&decoder_stream_sender_,
&headers_handler_) {
decoder_stream_sender_.set_qpack_stream_sender_delegate(
&decoder_stream_sender_delegate_);
header_table_.SetMaximumDynamicTableCapacity(
kMaximumDynamicTableCapacityForTesting);
}
~QpackProgressiveDecoderTest() override = default;
QpackProgressiveDecoder progressive_decoder_;
StrictMock<MockEnforcer> enforcer_;
QpackHeaderTable header_table_;
QpackDecoderStreamSender decoder_stream_sender_;
StrictMock<MockQpackStreamSenderDelegate> decoder_stream_sender_delegate_;
StrictMock<MockHeadersHandler> headers_handler_;
};
TEST_F(QpackProgressiveDecoderTest, Literal) {
EXPECT_CALL(headers_handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
progressive_decoder_.Decode(QuicTextUtils::HexDecode("000023666f6f03626172"));
EXPECT_CALL(headers_handler_, OnDecodingCompleted());
progressive_decoder_.EndHeaderBlock();
}
TEST_F(QpackProgressiveDecoderTest, DynamicTableSynchronous) {
EXPECT_TRUE(header_table_.InsertEntry("foo", "bar"));
EXPECT_CALL(headers_handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
progressive_decoder_.Decode(QuicTextUtils::HexDecode(
"0200" // Required Insert Count 1 and Delta Base 0.
"80")); // Dynamic table entry with relative index 0,
// absolute index 0.
EXPECT_CALL(headers_handler_, OnDecodingCompleted());
EXPECT_CALL(decoder_stream_sender_delegate_,
WriteStreamData(Eq(kHeaderAcknowledgement)));
progressive_decoder_.EndHeaderBlock();
}
TEST_F(QpackProgressiveDecoderTest, DynamicTableBlocked) {
EXPECT_CALL(enforcer_, OnStreamBlocked(kStreamId)).WillOnce(Return(true));
progressive_decoder_.Decode(QuicTextUtils::HexDecode(
"0200" // Required Insert Count 1 and Delta Base 0.
"80")); // Dynamic table entry with relative index 0,
// absolute index 0.
progressive_decoder_.EndHeaderBlock();
EXPECT_CALL(enforcer_, OnStreamUnblocked(kStreamId));
EXPECT_CALL(headers_handler_, OnHeaderDecoded(Eq("foo"), Eq("bar")));
EXPECT_CALL(headers_handler_, OnDecodingCompleted());
EXPECT_CALL(decoder_stream_sender_delegate_,
WriteStreamData(Eq(kHeaderAcknowledgement)));
EXPECT_TRUE(header_table_.InsertEntry("foo", "bar"));
}
TEST_F(QpackProgressiveDecoderTest, TooManyBlockedStreams) {
EXPECT_CALL(enforcer_, OnStreamBlocked(kStreamId)).WillOnce(Return(false));
EXPECT_CALL(
headers_handler_,
OnDecodingErrorDetected("Limit on number of blocked streams exceeded."));
// Required Insert Count 1.
progressive_decoder_.Decode(QuicTextUtils::HexDecode("0200"));
}
} // namespace
} // namespace test
} // namespace quic