blob: 0d172cd68470155d5e88a3a703b1ba9992f4770e [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
6
vasilvv0fb44432019-03-13 22:47:36 -07007#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05008#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
9#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
10
11using ::testing::Values;
12
13namespace quic {
14namespace test {
15namespace {
16
bnce4a6a0c2019-06-21 17:16:04 -070017class QpackInstructionEncoderTest : public QuicTest {
QUICHE teama6ef0a62019-03-07 20:34:33 -050018 protected:
bnce4a6a0c2019-06-21 17:16:04 -070019 QpackInstructionEncoderTest() : verified_position_(0) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050020 ~QpackInstructionEncoderTest() override = default;
21
bnce4a6a0c2019-06-21 17:16:04 -070022 // Append encoded |instruction| to |output_|.
bnc28bb06c2019-07-17 05:21:10 -070023 void EncodeInstruction(const QpackInstruction* instruction,
24 const QpackInstructionEncoder::Values& values) {
25 encoder_.Encode(instruction, values, &output_);
bnce4a6a0c2019-06-21 17:16:04 -070026 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050027
bnce4a6a0c2019-06-21 17:16:04 -070028 // Compare substring appended to |output_| since last EncodedSegmentMatches()
29 // call against hex-encoded argument.
30 bool EncodedSegmentMatches(QuicStringPiece hex_encoded_expected_substring) {
31 auto recently_encoded = QuicStringPiece(output_).substr(verified_position_);
32 auto expected = QuicTextUtils::HexDecode(hex_encoded_expected_substring);
33 verified_position_ = output_.size();
34 return recently_encoded == expected;
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 }
36
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 private:
bnc28bb06c2019-07-17 05:21:10 -070038 QpackInstructionEncoder encoder_;
bnce4a6a0c2019-06-21 17:16:04 -070039 std::string output_;
40 std::string::size_type verified_position_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050041};
42
bnce4a6a0c2019-06-21 17:16:04 -070043TEST_F(QpackInstructionEncoderTest, Varint) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050044 const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80},
45 {{QpackInstructionFieldType::kVarint, 7}}};
46
bnc28bb06c2019-07-17 05:21:10 -070047 QpackInstructionEncoder::Values values;
48 values.varint = 5;
49 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070050 EXPECT_TRUE(EncodedSegmentMatches("05"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050051
bnc28bb06c2019-07-17 05:21:10 -070052 values.varint = 127;
53 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070054 EXPECT_TRUE(EncodedSegmentMatches("7f00"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050055}
56
bnce4a6a0c2019-06-21 17:16:04 -070057TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050058 const QpackInstruction instruction{
59 QpackInstructionOpcode{0x80, 0xc0},
60 {{QpackInstructionFieldType::kSbit, 0x20},
61 {QpackInstructionFieldType::kVarint, 5},
62 {QpackInstructionFieldType::kVarint2, 8}}};
63
bnc28bb06c2019-07-17 05:21:10 -070064 QpackInstructionEncoder::Values values;
65 values.s_bit = true;
66 values.varint = 5;
67 values.varint2 = 200;
68 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070069 EXPECT_TRUE(EncodedSegmentMatches("a5c8"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050070
bnc28bb06c2019-07-17 05:21:10 -070071 values.s_bit = false;
72 values.varint = 31;
73 values.varint2 = 356;
74 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070075 EXPECT_TRUE(EncodedSegmentMatches("9f00ff65"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050076}
77
bnce4a6a0c2019-06-21 17:16:04 -070078TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0},
80 {{QpackInstructionFieldType::kSbit, 0x20},
81 {QpackInstructionFieldType::kVarint, 5},
82 {QpackInstructionFieldType::kValue, 7}}};
83
bnc28bb06c2019-07-17 05:21:10 -070084 QpackInstructionEncoder::Values values;
85 values.s_bit = true;
86 values.varint = 100;
87 values.value = "foo";
88 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070089 EXPECT_TRUE(EncodedSegmentMatches("ff458294e7"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050090
bnc28bb06c2019-07-17 05:21:10 -070091 values.s_bit = false;
92 values.varint = 3;
93 values.value = "bar";
94 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -070095 EXPECT_TRUE(EncodedSegmentMatches("c303626172"));
QUICHE teama6ef0a62019-03-07 20:34:33 -050096}
97
bnce4a6a0c2019-06-21 17:16:04 -070098TEST_F(QpackInstructionEncoderTest, Name) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050099 const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0},
100 {{QpackInstructionFieldType::kName, 4}}};
101
bnc28bb06c2019-07-17 05:21:10 -0700102 QpackInstructionEncoder::Values values;
103 values.name = "";
104 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700105 EXPECT_TRUE(EncodedSegmentMatches("e0"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106
bnc28bb06c2019-07-17 05:21:10 -0700107 values.name = "foo";
108 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700109 EXPECT_TRUE(EncodedSegmentMatches("f294e7"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110
bnc28bb06c2019-07-17 05:21:10 -0700111 values.name = "bar";
112 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700113 EXPECT_TRUE(EncodedSegmentMatches("e3626172"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114}
115
bnce4a6a0c2019-06-21 17:16:04 -0700116TEST_F(QpackInstructionEncoderTest, Value) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
118 {{QpackInstructionFieldType::kValue, 3}}};
119
bnc28bb06c2019-07-17 05:21:10 -0700120 QpackInstructionEncoder::Values values;
121 values.value = "";
122 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700123 EXPECT_TRUE(EncodedSegmentMatches("f0"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500124
bnc28bb06c2019-07-17 05:21:10 -0700125 values.value = "foo";
126 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700127 EXPECT_TRUE(EncodedSegmentMatches("fa94e7"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500128
bnc28bb06c2019-07-17 05:21:10 -0700129 values.value = "bar";
130 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700131 EXPECT_TRUE(EncodedSegmentMatches("f3626172"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500132}
133
bnce4a6a0c2019-06-21 17:16:04 -0700134TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500135 const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0},
136 {{QpackInstructionFieldType::kSbit, 0x08},
137 {QpackInstructionFieldType::kName, 2},
138 {QpackInstructionFieldType::kValue, 7}}};
139
bnc28bb06c2019-07-17 05:21:10 -0700140 QpackInstructionEncoder::Values values;
141 values.s_bit = false;
142 values.name = "";
143 values.value = "";
144 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700145 EXPECT_TRUE(EncodedSegmentMatches("f000"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500146
bnc28bb06c2019-07-17 05:21:10 -0700147 values.s_bit = true;
148 values.name = "foo";
149 values.value = "bar";
150 EncodeInstruction(&instruction, values);
bnce4a6a0c2019-06-21 17:16:04 -0700151 EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172"));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152}
153
154} // namespace
155} // namespace test
156} // namespace quic