Also test http2::HuffmanEncodeFast() in spdy::HpackEncoderTest.
spdy::HpackHuffmanTable::EncodeString() will be deprecated and replaced by
http2::HuffmanEncodeFast(). With this change, HpackEncoderTest generates data
using both and compares that against HpackEncoder which currently uses
spdy::HpackHuffmanTable::EncodeString() but will alternatively be using
http2::HuffmanEncodeFast() controlled by a flag, to provide extended test
coverage.
PiperOrigin-RevId: 335869311
Change-Id: If50b36933c0aec87a66279b54cf70c9452933c90
diff --git a/spdy/core/hpack/hpack_encoder_test.cc b/spdy/core/hpack/hpack_encoder_test.cc
index 8e9a2d6..62c7887 100644
--- a/spdy/core/hpack/hpack_encoder_test.cc
+++ b/spdy/core/hpack/hpack_encoder_test.cc
@@ -5,8 +5,9 @@
#include "net/third_party/quiche/src/spdy/core/hpack/hpack_encoder.h"
#include <cstdint>
-#include <map>
+#include <utility>
+#include "net/third_party/quiche/src/http2/hpack/huffman/hpack_huffman_encoder.h"
#include "net/third_party/quiche/src/http2/test_tools/http2_random.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
#include "net/third_party/quiche/src/spdy/core/hpack/hpack_huffman_table.h"
@@ -125,14 +126,17 @@
kRepresentations,
};
-class HpackEncoderTestBase : public QuicheTest {
+class HpackEncoderTest
+ : public QuicheTestWithParam<std::tuple<EncodeStrategy, bool>> {
protected:
typedef test::HpackEncoderPeer::Representations Representations;
- HpackEncoderTestBase()
+ HpackEncoderTest()
: peer_(&encoder_),
static_(peer_.table()->GetByIndex(1)),
- headers_storage_(1024 /* block size */) {}
+ headers_storage_(1024 /* block size */),
+ strategy_(std::get<0>(GetParam())),
+ use_fast_huffman_encoder_(std::get<1>(GetParam())) {}
void SetUp() override {
// Populate dynamic entries into the table fixture. For simplicity each
@@ -187,13 +191,19 @@
}
void ExpectString(HpackOutputStream* stream, quiche::QuicheStringPiece str) {
const HpackHuffmanTable& huffman_table = ObtainHpackHuffmanTable();
- size_t encoded_size = peer_.compression_enabled()
- ? huffman_table.EncodedSize(str)
- : str.size();
+ size_t encoded_size =
+ peer_.compression_enabled()
+ ? (use_fast_huffman_encoder_ ? http2::HuffmanSize(str)
+ : huffman_table.EncodedSize(str))
+ : str.size();
if (encoded_size < str.size()) {
expected_.AppendPrefix(kStringLiteralHuffmanEncoded);
expected_.AppendUint32(encoded_size);
- huffman_table.EncodeString(str, stream);
+ if (use_fast_huffman_encoder_) {
+ http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString());
+ } else {
+ huffman_table.EncodeString(str, stream);
+ }
} else {
expected_.AppendPrefix(kStringLiteralIdentityEncoded);
expected_.AppendUint32(str.size());
@@ -255,10 +265,18 @@
headers_observed_;
HpackOutputStream expected_;
- EncodeStrategy strategy_ = kDefault;
+ const EncodeStrategy strategy_;
+ const bool use_fast_huffman_encoder_;
};
-TEST_F(HpackEncoderTestBase, EncodeRepresentations) {
+using HpackEncoderTestWithDefaultStrategy = HpackEncoderTest;
+
+INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
+ HpackEncoderTestWithDefaultStrategy,
+ ::testing::Combine(::testing::Values(kDefault),
+ ::testing::Bool()));
+
+TEST_P(HpackEncoderTestWithDefaultStrategy, EncodeRepresentations) {
encoder_.SetHeaderListener(
[this](quiche::QuicheStringPiece name, quiche::QuicheStringPiece value) {
this->SaveHeaders(name, value);
@@ -290,20 +308,12 @@
Pair("withnul", quiche::QuicheStringPiece("one\0two", 7))));
}
-class HpackEncoderTest : public HpackEncoderTestBase,
- public ::testing::WithParamInterface<EncodeStrategy> {
- protected:
- void SetUp() override {
- strategy_ = GetParam();
- HpackEncoderTestBase::SetUp();
- }
-};
-
INSTANTIATE_TEST_SUITE_P(HpackEncoderTests,
HpackEncoderTest,
- ::testing::Values(kDefault,
- kIncremental,
- kRepresentations));
+ ::testing::Combine(::testing::Values(kDefault,
+ kIncremental,
+ kRepresentations),
+ ::testing::Bool()));
TEST_P(HpackEncoderTest, SingleDynamicIndex) {
encoder_.SetHeaderListener(
diff --git a/spdy/core/hpack/hpack_output_stream.cc b/spdy/core/hpack/hpack_output_stream.cc
index 5c2dd68..c53f07f 100644
--- a/spdy/core/hpack/hpack_output_stream.cc
+++ b/spdy/core/hpack/hpack_output_stream.cc
@@ -61,6 +61,12 @@
}
AppendBits(static_cast<uint8_t>(I), 8);
}
+ DCHECK_EQ(bit_offset_, 0u);
+}
+
+std::string* HpackOutputStream::MutableString() {
+ DCHECK_EQ(bit_offset_, 0u);
+ return &buffer_;
}
void HpackOutputStream::TakeString(std::string* output) {
diff --git a/spdy/core/hpack/hpack_output_stream.h b/spdy/core/hpack/hpack_output_stream.h
index f7e71f1..f99097a 100644
--- a/spdy/core/hpack/hpack_output_stream.h
+++ b/spdy/core/hpack/hpack_output_stream.h
@@ -48,6 +48,9 @@
// boundary after this function is called.
void AppendUint32(uint32_t I);
+ // Return pointer to internal buffer. |bit_offset_| needs to be zero.
+ std::string* MutableString();
+
// Swaps the internal buffer with |output|, then resets state.
void TakeString(std::string* output);
diff --git a/spdy/core/hpack/hpack_output_stream_test.cc b/spdy/core/hpack/hpack_output_stream_test.cc
index 21e6947..20d320c 100644
--- a/spdy/core/hpack/hpack_output_stream_test.cc
+++ b/spdy/core/hpack/hpack_output_stream_test.cc
@@ -271,6 +271,20 @@
EXPECT_EQ("\x10", str);
}
+TEST(HpackOutputStreamTest, MutableString) {
+ HpackOutputStream output_stream;
+
+ output_stream.AppendBytes("1");
+ output_stream.MutableString()->append("2");
+
+ output_stream.AppendBytes("foo");
+ output_stream.MutableString()->append("bar");
+
+ std::string str;
+ output_stream.TakeString(&str);
+ EXPECT_EQ("12foobar", str);
+}
+
} // namespace
} // namespace spdy