• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 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 "quiche/quic/core/qpack/qpack_encoder_stream_sender.h"
6 
7 #include "absl/strings/escaping.h"
8 #include "quiche/quic/platform/api/quic_test.h"
9 #include "quiche/quic/test_tools/qpack/qpack_test_utils.h"
10 
11 using ::testing::Eq;
12 using ::testing::StrictMock;
13 
14 namespace quic {
15 namespace test {
16 namespace {
17 
18 class QpackEncoderStreamSenderTest : public QuicTest {
19  protected:
QpackEncoderStreamSenderTest()20   QpackEncoderStreamSenderTest() {
21     stream_.set_qpack_stream_sender_delegate(&delegate_);
22   }
23   ~QpackEncoderStreamSenderTest() override = default;
24 
25   StrictMock<MockQpackStreamSenderDelegate> delegate_;
26   QpackEncoderStreamSender stream_;
27 };
28 
TEST_F(QpackEncoderStreamSenderTest,InsertWithNameReference)29 TEST_F(QpackEncoderStreamSenderTest, InsertWithNameReference) {
30   EXPECT_EQ(0u, stream_.BufferedByteCount());
31 
32   // Static, index fits in prefix, empty value.
33   std::string expected_encoded_data = absl::HexStringToBytes("c500");
34   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
35   stream_.SendInsertWithNameReference(true, 5, "");
36   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
37   stream_.Flush();
38 
39   // Static, index fits in prefix, Huffman encoded value.
40   expected_encoded_data = absl::HexStringToBytes("c28294e7");
41   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
42   stream_.SendInsertWithNameReference(true, 2, "foo");
43   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
44   stream_.Flush();
45 
46   // Not static, index does not fit in prefix, not Huffman encoded value.
47   expected_encoded_data = absl::HexStringToBytes("bf4a03626172");
48   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
49   stream_.SendInsertWithNameReference(false, 137, "bar");
50   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
51   stream_.Flush();
52 
53   // Value length does not fit in prefix.
54   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
55   expected_encoded_data = absl::HexStringToBytes(
56       "aa7f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
57       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
58       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
59       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
60   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
61   stream_.SendInsertWithNameReference(false, 42, std::string(127, 'Z'));
62   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
63   stream_.Flush();
64 }
65 
TEST_F(QpackEncoderStreamSenderTest,InsertWithoutNameReference)66 TEST_F(QpackEncoderStreamSenderTest, InsertWithoutNameReference) {
67   EXPECT_EQ(0u, stream_.BufferedByteCount());
68 
69   // Empty name and value.
70   std::string expected_encoded_data = absl::HexStringToBytes("4000");
71   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
72   stream_.SendInsertWithoutNameReference("", "");
73   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
74   stream_.Flush();
75 
76   // Huffman encoded short strings.
77   expected_encoded_data = absl::HexStringToBytes("6294e78294e7");
78   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
79   stream_.SendInsertWithoutNameReference("foo", "foo");
80   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
81   stream_.Flush();
82 
83   // Not Huffman encoded short strings.
84   expected_encoded_data = absl::HexStringToBytes("4362617203626172");
85   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
86   stream_.SendInsertWithoutNameReference("bar", "bar");
87   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
88   stream_.Flush();
89 
90   // Not Huffman encoded long strings; length does not fit on prefix.
91   // 'Z' would be Huffman encoded to 8 bits, so no Huffman encoding is used.
92   expected_encoded_data = absl::HexStringToBytes(
93       "5f005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a7f"
94       "005a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
95       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
96       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a"
97       "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a");
98   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
99   stream_.SendInsertWithoutNameReference(std::string(31, 'Z'),
100                                          std::string(127, 'Z'));
101   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
102   stream_.Flush();
103 }
104 
TEST_F(QpackEncoderStreamSenderTest,Duplicate)105 TEST_F(QpackEncoderStreamSenderTest, Duplicate) {
106   EXPECT_EQ(0u, stream_.BufferedByteCount());
107 
108   // Small index fits in prefix.
109   std::string expected_encoded_data = absl::HexStringToBytes("11");
110   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
111   stream_.SendDuplicate(17);
112   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
113   stream_.Flush();
114 
115   // Large index requires two extension bytes.
116   expected_encoded_data = absl::HexStringToBytes("1fd503");
117   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
118   stream_.SendDuplicate(500);
119   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
120   stream_.Flush();
121 }
122 
TEST_F(QpackEncoderStreamSenderTest,SetDynamicTableCapacity)123 TEST_F(QpackEncoderStreamSenderTest, SetDynamicTableCapacity) {
124   EXPECT_EQ(0u, stream_.BufferedByteCount());
125 
126   // Small capacity fits in prefix.
127   std::string expected_encoded_data = absl::HexStringToBytes("31");
128   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
129   stream_.SendSetDynamicTableCapacity(17);
130   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
131   stream_.Flush();
132   EXPECT_EQ(0u, stream_.BufferedByteCount());
133 
134   // Large capacity requires two extension bytes.
135   expected_encoded_data = absl::HexStringToBytes("3fd503");
136   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
137   stream_.SendSetDynamicTableCapacity(500);
138   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
139   stream_.Flush();
140   EXPECT_EQ(0u, stream_.BufferedByteCount());
141 }
142 
143 // No writes should happen until Flush is called.
TEST_F(QpackEncoderStreamSenderTest,Coalesce)144 TEST_F(QpackEncoderStreamSenderTest, Coalesce) {
145   // Insert entry with static name reference, empty value.
146   stream_.SendInsertWithNameReference(true, 5, "");
147 
148   // Insert entry with static name reference, Huffman encoded value.
149   stream_.SendInsertWithNameReference(true, 2, "foo");
150 
151   // Insert literal entry, Huffman encoded short strings.
152   stream_.SendInsertWithoutNameReference("foo", "foo");
153 
154   // Duplicate entry.
155   stream_.SendDuplicate(17);
156 
157   std::string expected_encoded_data = absl::HexStringToBytes(
158       "c500"          // Insert entry with static name reference.
159       "c28294e7"      // Insert entry with static name reference.
160       "6294e78294e7"  // Insert literal entry.
161       "11");          // Duplicate entry.
162 
163   EXPECT_CALL(delegate_, WriteStreamData(Eq(expected_encoded_data)));
164   EXPECT_EQ(expected_encoded_data.size(), stream_.BufferedByteCount());
165   stream_.Flush();
166   EXPECT_EQ(0u, stream_.BufferedByteCount());
167 }
168 
169 // No writes should happen if QpackEncoderStreamSender::Flush() is called
170 // when the buffer is empty.
TEST_F(QpackEncoderStreamSenderTest,FlushEmpty)171 TEST_F(QpackEncoderStreamSenderTest, FlushEmpty) {
172   EXPECT_EQ(0u, stream_.BufferedByteCount());
173   stream_.Flush();
174   EXPECT_EQ(0u, stream_.BufferedByteCount());
175 }
176 
177 }  // namespace
178 }  // namespace test
179 }  // namespace quic
180