QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 1 | // 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 | |
vasilvv | 0fb4443 | 2019-03-13 22:47:36 -0700 | [diff] [blame] | 7 | #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h" |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 8 | #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 | |
| 11 | using ::testing::Values; |
| 12 | |
| 13 | namespace quic { |
| 14 | namespace test { |
| 15 | namespace { |
| 16 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 17 | class QpackInstructionEncoderTest : public QuicTest { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 18 | protected: |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 19 | QpackInstructionEncoderTest() : verified_position_(0) {} |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 20 | ~QpackInstructionEncoderTest() override = default; |
| 21 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 22 | // Append encoded |instruction| to |output_|. |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 23 | void EncodeInstruction(const QpackInstruction* instruction, |
| 24 | const QpackInstructionEncoder::Values& values) { |
| 25 | encoder_.Encode(instruction, values, &output_); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 26 | } |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 27 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 28 | // 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 team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 35 | } |
| 36 | |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 37 | private: |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 38 | QpackInstructionEncoder encoder_; |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 39 | std::string output_; |
| 40 | std::string::size_type verified_position_; |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 41 | }; |
| 42 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 43 | TEST_F(QpackInstructionEncoderTest, Varint) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 44 | const QpackInstruction instruction{QpackInstructionOpcode{0x00, 0x80}, |
| 45 | {{QpackInstructionFieldType::kVarint, 7}}}; |
| 46 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 47 | QpackInstructionEncoder::Values values; |
| 48 | values.varint = 5; |
| 49 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 50 | EXPECT_TRUE(EncodedSegmentMatches("05")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 51 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 52 | values.varint = 127; |
| 53 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 54 | EXPECT_TRUE(EncodedSegmentMatches("7f00")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 55 | } |
| 56 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 57 | TEST_F(QpackInstructionEncoderTest, SBitAndTwoVarint2) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 58 | const QpackInstruction instruction{ |
| 59 | QpackInstructionOpcode{0x80, 0xc0}, |
| 60 | {{QpackInstructionFieldType::kSbit, 0x20}, |
| 61 | {QpackInstructionFieldType::kVarint, 5}, |
| 62 | {QpackInstructionFieldType::kVarint2, 8}}}; |
| 63 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 64 | QpackInstructionEncoder::Values values; |
| 65 | values.s_bit = true; |
| 66 | values.varint = 5; |
| 67 | values.varint2 = 200; |
| 68 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 69 | EXPECT_TRUE(EncodedSegmentMatches("a5c8")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 70 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 71 | values.s_bit = false; |
| 72 | values.varint = 31; |
| 73 | values.varint2 = 356; |
| 74 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 75 | EXPECT_TRUE(EncodedSegmentMatches("9f00ff65")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 76 | } |
| 77 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 78 | TEST_F(QpackInstructionEncoderTest, SBitAndVarintAndValue) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 79 | const QpackInstruction instruction{QpackInstructionOpcode{0xc0, 0xc0}, |
| 80 | {{QpackInstructionFieldType::kSbit, 0x20}, |
| 81 | {QpackInstructionFieldType::kVarint, 5}, |
| 82 | {QpackInstructionFieldType::kValue, 7}}}; |
| 83 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 84 | QpackInstructionEncoder::Values values; |
| 85 | values.s_bit = true; |
| 86 | values.varint = 100; |
| 87 | values.value = "foo"; |
| 88 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 89 | EXPECT_TRUE(EncodedSegmentMatches("ff458294e7")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 90 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 91 | values.s_bit = false; |
| 92 | values.varint = 3; |
| 93 | values.value = "bar"; |
| 94 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 95 | EXPECT_TRUE(EncodedSegmentMatches("c303626172")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 96 | } |
| 97 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 98 | TEST_F(QpackInstructionEncoderTest, Name) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 99 | const QpackInstruction instruction{QpackInstructionOpcode{0xe0, 0xe0}, |
| 100 | {{QpackInstructionFieldType::kName, 4}}}; |
| 101 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 102 | QpackInstructionEncoder::Values values; |
| 103 | values.name = ""; |
| 104 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 105 | EXPECT_TRUE(EncodedSegmentMatches("e0")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 106 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 107 | values.name = "foo"; |
| 108 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 109 | EXPECT_TRUE(EncodedSegmentMatches("f294e7")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 110 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 111 | values.name = "bar"; |
| 112 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 113 | EXPECT_TRUE(EncodedSegmentMatches("e3626172")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 114 | } |
| 115 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 116 | TEST_F(QpackInstructionEncoderTest, Value) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 117 | const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0}, |
| 118 | {{QpackInstructionFieldType::kValue, 3}}}; |
| 119 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 120 | QpackInstructionEncoder::Values values; |
| 121 | values.value = ""; |
| 122 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 123 | EXPECT_TRUE(EncodedSegmentMatches("f0")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 124 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 125 | values.value = "foo"; |
| 126 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 127 | EXPECT_TRUE(EncodedSegmentMatches("fa94e7")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 128 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 129 | values.value = "bar"; |
| 130 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 131 | EXPECT_TRUE(EncodedSegmentMatches("f3626172")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 132 | } |
| 133 | |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 134 | TEST_F(QpackInstructionEncoderTest, SBitAndNameAndValue) { |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 135 | const QpackInstruction instruction{QpackInstructionOpcode{0xf0, 0xf0}, |
| 136 | {{QpackInstructionFieldType::kSbit, 0x08}, |
| 137 | {QpackInstructionFieldType::kName, 2}, |
| 138 | {QpackInstructionFieldType::kValue, 7}}}; |
| 139 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 140 | QpackInstructionEncoder::Values values; |
| 141 | values.s_bit = false; |
| 142 | values.name = ""; |
| 143 | values.value = ""; |
| 144 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 145 | EXPECT_TRUE(EncodedSegmentMatches("f000")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 146 | |
bnc | 28bb06c | 2019-07-17 05:21:10 -0700 | [diff] [blame] | 147 | values.s_bit = true; |
| 148 | values.name = "foo"; |
| 149 | values.value = "bar"; |
| 150 | EncodeInstruction(&instruction, values); |
bnc | e4a6a0c | 2019-06-21 17:16:04 -0700 | [diff] [blame] | 151 | EXPECT_TRUE(EncodedSegmentMatches("fe94e703626172")); |
QUICHE team | a6ef0a6 | 2019-03-07 20:34:33 -0500 | [diff] [blame] | 152 | } |
| 153 | |
| 154 | } // namespace |
| 155 | } // namespace test |
| 156 | } // namespace quic |