summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc')
-rw-r--r--chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc160
1 files changed, 160 insertions, 0 deletions
diff --git a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
index 21397ed8571..30f578e9378 100644
--- a/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
+++ b/chromium/net/third_party/quiche/src/quic/core/qpack/qpack_encoder_test.cc
@@ -18,12 +18,19 @@
using ::testing::_;
using ::testing::Eq;
+using ::testing::Return;
using ::testing::StrictMock;
namespace quic {
namespace test {
namespace {
+// A number larger than kMaxBytesBufferedByStream in
+// qpack_encoder_stream_sender.cc. Returning this value from NumBytesBuffered()
+// will instruct QpackEncoder not to generate any instructions for the encoder
+// stream.
+constexpr uint64_t kTooManyBytesBuffered = 1024 * 1024;
+
class QpackEncoderTest : public QuicTest {
protected:
QpackEncoderTest()
@@ -47,6 +54,8 @@ class QpackEncoderTest : public QuicTest {
};
TEST_F(QpackEncoderTest, Empty) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
std::string output = Encode(header_list);
@@ -54,6 +63,8 @@ TEST_F(QpackEncoderTest, Empty) {
}
TEST_F(QpackEncoderTest, EmptyName) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list[""] = "foo";
std::string output = Encode(header_list);
@@ -62,6 +73,8 @@ TEST_F(QpackEncoderTest, EmptyName) {
}
TEST_F(QpackEncoderTest, EmptyValue) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "";
std::string output = Encode(header_list);
@@ -70,6 +83,8 @@ TEST_F(QpackEncoderTest, EmptyValue) {
}
TEST_F(QpackEncoderTest, EmptyNameAndValue) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list[""] = "";
std::string output = Encode(header_list);
@@ -78,6 +93,8 @@ TEST_F(QpackEncoderTest, EmptyNameAndValue) {
}
TEST_F(QpackEncoderTest, Simple) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "bar";
std::string output = Encode(header_list);
@@ -86,6 +103,8 @@ TEST_F(QpackEncoderTest, Simple) {
}
TEST_F(QpackEncoderTest, Multiple) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = "bar";
// 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
@@ -108,6 +127,8 @@ TEST_F(QpackEncoderTest, Multiple) {
}
TEST_F(QpackEncoderTest, StaticTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
{
spdy::Http2HeaderBlock header_list;
header_list[":method"] = "GET";
@@ -149,6 +170,8 @@ TEST_F(QpackEncoderTest, DecoderStreamError) {
}
TEST_F(QpackEncoderTest, SplitAlongNullCharacter) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list;
header_list["foo"] = absl::string_view("bar\0bar\0baz", 11);
std::string output = Encode(header_list);
@@ -217,6 +240,8 @@ TEST_F(QpackEncoderTest, InvalidHeaderAcknowledgement) {
}
TEST_F(QpackEncoderTest, DynamicTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(4096);
encoder_.SetDynamicTableCapacity(4096);
@@ -252,6 +277,8 @@ TEST_F(QpackEncoderTest, DynamicTable) {
// There is no room in the dynamic table after inserting the first entry.
TEST_F(QpackEncoderTest, SmallDynamicTable) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
encoder_.SetDynamicTableCapacity(QpackEntry::Size("foo", "bar"));
@@ -288,6 +315,8 @@ TEST_F(QpackEncoderTest, SmallDynamicTable) {
}
TEST_F(QpackEncoderTest, BlockedStream) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
encoder_.SetMaximumBlockedStreams(1);
encoder_.SetMaximumDynamicTableCapacity(4096);
encoder_.SetDynamicTableCapacity(4096);
@@ -395,6 +424,8 @@ TEST_F(QpackEncoderTest, BlockedStream) {
}
TEST_F(QpackEncoderTest, Draining) {
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
spdy::Http2HeaderBlock header_list1;
header_list1["one"] = "foo";
header_list1["two"] = "foo";
@@ -467,6 +498,135 @@ TEST_F(QpackEncoderTest, DynamicTableCapacityLessThanMaximum) {
EXPECT_EQ(30u, header_table->dynamic_table_capacity());
}
+TEST_F(QpackEncoderTest, EncoderStreamWritesDisallowedThenAllowed) {
+ if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
+ return;
+ }
+
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(kTooManyBytesBuffered));
+ encoder_.SetMaximumBlockedStreams(1);
+ encoder_.SetMaximumDynamicTableCapacity(4096);
+ encoder_.SetDynamicTableCapacity(4096);
+
+ spdy::Http2HeaderBlock header_list1;
+ header_list1["foo"] = "bar";
+ header_list1.AppendValueOrAddHeader("foo", "baz");
+ header_list1["cookie"] = "baz"; // name matches static entry
+
+ // Encoder is not allowed to write on the encoder stream.
+ // No Set Dynamic Table Capacity or Insert instructions are sent.
+ // Headers are encoded as string literals.
+ EXPECT_EQ(absl::HexStringToBytes("0000" // prefix
+ "2a94e7" // literal name "foo"
+ "03626172" // with literal value "bar"
+ "2a94e7" // literal name "foo"
+ "0362617a" // with literal value "baz"
+ "55" // name of static entry 5
+ "0362617a"), // with literal value "baz"
+ Encode(header_list1));
+
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+
+ // If number of bytes buffered by encoder stream goes under the threshold,
+ // then QpackEncoder will resume emitting encoder stream instructions.
+ ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
+
+ spdy::Http2HeaderBlock header_list2;
+ header_list2["foo"] = "bar";
+ header_list2.AppendValueOrAddHeader("foo",
+ "baz"); // name matches dynamic entry
+ header_list2["cookie"] = "baz"; // name matches static entry
+
+ // Set Dynamic Table Capacity instruction.
+ std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+ // Insert three entries into the dynamic table.
+ std::string insert_entries = absl::HexStringToBytes(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172" // value "bar"
+ "80" // insert with name reference, dynamic index 0
+ "0362617a" // value "baz"
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
+ EXPECT_CALL(encoder_stream_sender_delegate_,
+ WriteStreamData(Eq(
+ absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+ EXPECT_EQ(absl::HexStringToBytes(
+ "0400" // prefix
+ "828180"), // dynamic entries with relative index 0, 1, and 2
+ Encode(header_list2));
+
+ EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+}
+
+TEST_F(QpackEncoderTest, EncoderStreamWritesAllowedThenDisallowed) {
+ if (!GetQuicReloadableFlag(quic_limit_encoder_stream_buffering)) {
+ return;
+ }
+
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(0));
+ encoder_.SetMaximumBlockedStreams(1);
+ encoder_.SetMaximumDynamicTableCapacity(4096);
+ encoder_.SetDynamicTableCapacity(4096);
+
+ spdy::Http2HeaderBlock header_list1;
+ header_list1["foo"] = "bar";
+ header_list1.AppendValueOrAddHeader("foo",
+ "baz"); // name matches dynamic entry
+ header_list1["cookie"] = "baz"; // name matches static entry
+
+ // Set Dynamic Table Capacity instruction.
+ std::string set_dyanamic_table_capacity = absl::HexStringToBytes("3fe11f");
+ // Insert three entries into the dynamic table.
+ std::string insert_entries = absl::HexStringToBytes(
+ "62" // insert without name reference
+ "94e7" // Huffman-encoded name "foo"
+ "03626172" // value "bar"
+ "80" // insert with name reference, dynamic index 0
+ "0362617a" // value "baz"
+ "c5" // insert with name reference, static index 5
+ "0362617a"); // value "baz"
+ EXPECT_CALL(encoder_stream_sender_delegate_,
+ WriteStreamData(Eq(
+ absl::StrCat(set_dyanamic_table_capacity, insert_entries))));
+
+ EXPECT_EQ(absl::HexStringToBytes(
+ "0400" // prefix
+ "828180"), // dynamic entries with relative index 0, 1, and 2
+ Encode(header_list1));
+
+ EXPECT_EQ(insert_entries.size(), encoder_stream_sent_byte_count_);
+
+ // If number of bytes buffered by encoder stream goes over the threshold,
+ // then QpackEncoder will stop emitting encoder stream instructions.
+ ::testing::Mock::VerifyAndClearExpectations(&encoder_stream_sender_delegate_);
+ EXPECT_CALL(encoder_stream_sender_delegate_, NumBytesBuffered())
+ .WillRepeatedly(Return(kTooManyBytesBuffered));
+
+ spdy::Http2HeaderBlock header_list2;
+ header_list2["foo"] = "bar"; // matches previously inserted dynamic entry
+ header_list2["bar"] = "baz";
+ header_list2["cookie"] = "baz"; // name matches static entry
+
+ // Encoder is not allowed to write on the encoder stream.
+ // No Set Dynamic Table Capacity or Insert instructions are sent.
+ // Headers are encoded as string literals.
+ EXPECT_EQ(
+ absl::HexStringToBytes("0400" // prefix
+ "82" // dynamic entry with relative index 0
+ "23626172" // literal name "bar"
+ "0362617a" // with literal value "baz"
+ "80"), // dynamic entry with relative index 2
+ Encode(header_list2));
+
+ EXPECT_EQ(0u, encoder_stream_sent_byte_count_);
+}
+
} // namespace
} // namespace test
} // namespace quic