Modify QpackInstructionEncoder API.

QpackInstructionEncoder does not need to support progressive encoding.  This CL
modifies the API, a follow-up CL will clean up internals.

Taking |&output| and appending is more performant than returning std::string
when encoding headers, which involve concatenating a large number of
instructions.

gfe-relnote: n/a, QUIC v99-only change.
PiperOrigin-RevId: 254497735
Change-Id: I62d74a0523220e5730ffc85ea66ab071345fc8fb
diff --git a/quic/core/qpack/qpack_instruction_encoder_test.cc b/quic/core/qpack/qpack_instruction_encoder_test.cc
index 738a1b7..d921fa6 100644
--- a/quic/core/qpack/qpack_instruction_encoder_test.cc
+++ b/quic/core/qpack/qpack_instruction_encoder_test.cc
@@ -4,7 +4,6 @@
 
 #include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
 
-#include "net/third_party/quiche/src/quic/core/qpack/qpack_test_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.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"
@@ -15,49 +14,46 @@
 namespace test {
 namespace {
 
-class QpackInstructionEncoderTest : public QuicTestWithParam<FragmentMode> {
+class QpackInstructionEncoderTest : public QuicTest {
  protected:
-  QpackInstructionEncoderTest() : fragment_mode_(GetParam()) {}
+  QpackInstructionEncoderTest() : verified_position_(0) {}
   ~QpackInstructionEncoderTest() override = default;
 
-  // Encode |instruction| with fragment sizes dictated by |fragment_mode_|.
-  std::string EncodeInstruction(const QpackInstruction* instruction) {
-    EXPECT_FALSE(encoder_.HasNext());
+  // Append encoded |instruction| to |output_|.
+  void EncodeInstruction(const QpackInstruction* instruction) {
+    encoder_.Encode(instruction, &output_);
+  }
 
-    FragmentSizeGenerator fragment_size_generator =
-        FragmentModeToFragmentSizeGenerator(fragment_mode_);
-    std::string output;
-    encoder_.Encode(instruction);
-    while (encoder_.HasNext()) {
-      encoder_.Next(fragment_size_generator(), &output);
-    }
-
-    return output;
+  // Compare substring appended to |output_| since last EncodedSegmentMatches()
+  // call against hex-encoded argument.
+  bool EncodedSegmentMatches(QuicStringPiece hex_encoded_expected_substring) {
+    auto recently_encoded = QuicStringPiece(output_).substr(verified_position_);
+    auto expected = QuicTextUtils::HexDecode(hex_encoded_expected_substring);
+    verified_position_ = output_.size();
+    return recently_encoded == expected;
   }
 
   QpackInstructionEncoder encoder_;
 
  private:
-  const FragmentMode fragment_mode_;
+  std::string output_;
+  std::string::size_type verified_position_;
 };
 
-INSTANTIATE_TEST_SUITE_P(,
-                         QpackInstructionEncoderTest,
-                         Values(FragmentMode::kSingleChunk,
-                                FragmentMode::kOctetByOctet));
-
-TEST_P(QpackInstructionEncoderTest, Varint) {
+TEST_F(QpackInstructionEncoderTest, Varint) {
   const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
                                      {{QpackInstructionFieldType::kVarint, 7}}};
 
   encoder_.set_varint(5);
-  EXPECT_EQ(QuicTextUtils::HexDecode("05"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("05"));
 
   encoder_.set_varint(127);
-  EXPECT_EQ(QuicTextUtils::HexDecode("7f00"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("7f00"));
 }
 
-TEST_P(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
+TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
   const QpackInstruction instruction{
       QpackInstructionOpcode{0x80, 0xc0},
       {{QpackInstructionFieldType::kSbit, 0x20},
@@ -67,16 +63,17 @@
   encoder_.set_s_bit(true);
   encoder_.set_varint(5);
   encoder_.set_varint2(200);
-  EXPECT_EQ(QuicTextUtils::HexDecode("a5c8"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
 
   encoder_.set_s_bit(false);
   encoder_.set_varint(31);
   encoder_.set_varint2(356);
-  EXPECT_EQ(QuicTextUtils::HexDecode("9f00ff65"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
 }
 
-TEST_P(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
+TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
   const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
                                      {{QpackInstructionFieldType::kSbit, 0x20},
                                       {QpackInstructionFieldType::kVarint, 5},
@@ -85,49 +82,51 @@
   encoder_.set_s_bit(true);
   encoder_.set_varint(100);
   encoder_.set_value("foo");
-  EXPECT_EQ(QuicTextUtils::HexDecode("ff458294e7"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
 
   encoder_.set_s_bit(false);
   encoder_.set_varint(3);
   encoder_.set_value("bar");
-  EXPECT_EQ(QuicTextUtils::HexDecode("c303626172"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
 }
 
-TEST_P(QpackInstructionEncoderTest, Name) {
+TEST_F(QpackInstructionEncoderTest, Name) {
   const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
                                      {{QpackInstructionFieldType::kName, 4}}};
 
   encoder_.set_name("");
-  EXPECT_EQ(QuicTextUtils::HexDecode("e0"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("e0"));
 
   encoder_.set_name("foo");
-  EXPECT_EQ(QuicTextUtils::HexDecode("f294e7"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
 
   encoder_.set_name("bar");
-  EXPECT_EQ(QuicTextUtils::HexDecode("e3626172"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
 }
 
-TEST_P(QpackInstructionEncoderTest, Value) {
+TEST_F(QpackInstructionEncoderTest, Value) {
   const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
                                      {{QpackInstructionFieldType::kValue, 3}}};
 
   encoder_.set_value("");
-  EXPECT_EQ(QuicTextUtils::HexDecode("f0"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("f0"));
 
   encoder_.set_value("foo");
-  EXPECT_EQ(QuicTextUtils::HexDecode("fa94e7"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
 
   encoder_.set_value("bar");
-  EXPECT_EQ(QuicTextUtils::HexDecode("f3626172"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
 }
 
-TEST_P(QpackInstructionEncoderTest, SBitAndNameAndValue) {
+TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
   const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
                                      {{QpackInstructionFieldType::kSbit, 0x08},
                                       {QpackInstructionFieldType::kName, 2},
@@ -136,13 +135,14 @@
   encoder_.set_s_bit(false);
   encoder_.set_name("");
   encoder_.set_value("");
-  EXPECT_EQ(QuicTextUtils::HexDecode("f000"), EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("f000"));
 
   encoder_.set_s_bit(true);
   encoder_.set_name("foo");
   encoder_.set_value("bar");
-  EXPECT_EQ(QuicTextUtils::HexDecode("fe94e703626172"),
-            EncodeInstruction(&instruction));
+  EncodeInstruction(&instruction);
+  EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
 }
 
 }  // namespace