Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: net/spdy/hpack/hpack_encoder_test.cc

Issue 2237113005: Adds a listener interface to HpackEncoder. Not used in production. Not protected. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address Comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/hpack/hpack_encoder.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/hpack/hpack_encoder.h" 5 #include "net/spdy/hpack/hpack_encoder.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "net/base/arena.h"
10 #include "testing/gmock/include/gmock/gmock.h" 11 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
12 13
13 namespace net { 14 namespace net {
14 15
15 using base::StringPiece; 16 using base::StringPiece;
16 using std::string; 17 using std::string;
18 using std::vector;
19 using std::pair;
17 using testing::ElementsAre; 20 using testing::ElementsAre;
18 21
19 namespace test { 22 namespace test {
20 23
21 class HpackHeaderTablePeer { 24 class HpackHeaderTablePeer {
22 public: 25 public:
23 explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {} 26 explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {}
24 27
25 HpackHeaderTable::EntryTable* dynamic_entries() { 28 HpackHeaderTable::EntryTable* dynamic_entries() {
26 return &table_->dynamic_entries_; 29 return &table_->dynamic_entries_;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 private: 72 private:
70 HpackEncoder* encoder_; 73 HpackEncoder* encoder_;
71 }; 74 };
72 75
73 } // namespace test 76 } // namespace test
74 77
75 namespace { 78 namespace {
76 79
77 using std::map; 80 using std::map;
78 using testing::ElementsAre; 81 using testing::ElementsAre;
82 using testing::Pair;
79 83
80 class HpackEncoderTest : public ::testing::Test { 84 class HpackEncoderTest : public ::testing::Test {
81 protected: 85 protected:
82 typedef test::HpackEncoderPeer::Representations Representations; 86 typedef test::HpackEncoderPeer::Representations Representations;
83 87
84 HpackEncoderTest() 88 HpackEncoderTest()
85 : encoder_(ObtainHpackHuffmanTable()), 89 : encoder_(ObtainHpackHuffmanTable()),
86 peer_(&encoder_), 90 peer_(&encoder_),
87 static_(peer_.table()->GetByIndex(1)) {} 91 static_(peer_.table()->GetByIndex(1)),
92 headers_storage_(1024 /* block size */) {}
88 93
89 void SetUp() override { 94 void SetUp() override {
90 // Populate dynamic entries into the table fixture. For simplicity each 95 // Populate dynamic entries into the table fixture. For simplicity each
91 // entry has name.size() + value.size() == 10. 96 // entry has name.size() + value.size() == 10.
92 key_1_ = peer_.table()->TryAddEntry("key1", "value1"); 97 key_1_ = peer_.table()->TryAddEntry("key1", "value1");
93 key_2_ = peer_.table()->TryAddEntry("key2", "value2"); 98 key_2_ = peer_.table()->TryAddEntry("key2", "value2");
94 cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb"); 99 cookie_a_ = peer_.table()->TryAddEntry("cookie", "a=bb");
95 cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd"); 100 cookie_c_ = peer_.table()->TryAddEntry("cookie", "c=dd");
96 101
97 // No further insertions may occur without evictions. 102 // No further insertions may occur without evictions.
98 peer_.table()->SetMaxSize(peer_.table()->size()); 103 peer_.table()->SetMaxSize(peer_.table()->size());
99 104
100 // Disable Huffman coding by default. Most tests don't care about it. 105 // Disable Huffman coding by default. Most tests don't care about it.
101 peer_.set_allow_huffman_compression(false); 106 peer_.set_allow_huffman_compression(false);
102 } 107 }
103 108
109 void SaveHeaders(StringPiece name, StringPiece value) {
110 StringPiece n(headers_storage_.Memdup(name.data(), name.size()),
111 name.size());
112 StringPiece v(headers_storage_.Memdup(value.data(), value.size()),
113 value.size());
114 headers_observed_.push_back(make_pair(n, v));
115 }
116
104 void ExpectIndex(size_t index) { 117 void ExpectIndex(size_t index) {
105 expected_.AppendPrefix(kIndexedOpcode); 118 expected_.AppendPrefix(kIndexedOpcode);
106 expected_.AppendUint32(index); 119 expected_.AppendUint32(index);
107 } 120 }
108 void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) { 121 void ExpectIndexedLiteral(const HpackEntry* key_entry, StringPiece value) {
109 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode); 122 expected_.AppendPrefix(kLiteralIncrementalIndexOpcode);
110 expected_.AppendUint32(IndexOf(key_entry)); 123 expected_.AppendUint32(IndexOf(key_entry));
111 expected_.AppendPrefix(kStringLiteralIdentityEncoded); 124 expected_.AppendPrefix(kStringLiteralIdentityEncoded);
112 expected_.AppendUint32(value.size()); 125 expected_.AppendUint32(value.size());
113 expected_.AppendBytes(value); 126 expected_.AppendBytes(value);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 161
149 HpackEncoder encoder_; 162 HpackEncoder encoder_;
150 test::HpackEncoderPeer peer_; 163 test::HpackEncoderPeer peer_;
151 164
152 const HpackEntry* static_; 165 const HpackEntry* static_;
153 const HpackEntry* key_1_; 166 const HpackEntry* key_1_;
154 const HpackEntry* key_2_; 167 const HpackEntry* key_2_;
155 const HpackEntry* cookie_a_; 168 const HpackEntry* cookie_a_;
156 const HpackEntry* cookie_c_; 169 const HpackEntry* cookie_c_;
157 170
171 UnsafeArena headers_storage_;
172 vector<pair<StringPiece, StringPiece>> headers_observed_;
173
158 HpackOutputStream expected_; 174 HpackOutputStream expected_;
159 }; 175 };
160 176
161 TEST_F(HpackEncoderTest, SingleDynamicIndex) { 177 TEST_F(HpackEncoderTest, SingleDynamicIndex) {
178 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
179 this->SaveHeaders(name, value);
180 });
181
162 ExpectIndex(IndexOf(key_2_)); 182 ExpectIndex(IndexOf(key_2_));
163 183
164 SpdyHeaderBlock headers; 184 SpdyHeaderBlock headers;
165 headers[key_2_->name().as_string()] = key_2_->value().as_string(); 185 headers[key_2_->name().as_string()] = key_2_->value().as_string();
166 CompareWithExpectedEncoding(headers); 186 CompareWithExpectedEncoding(headers);
187 EXPECT_THAT(headers_observed_,
188 ElementsAre(Pair(key_2_->name(), key_2_->value())));
167 } 189 }
168 190
169 TEST_F(HpackEncoderTest, SingleStaticIndex) { 191 TEST_F(HpackEncoderTest, SingleStaticIndex) {
170 ExpectIndex(IndexOf(static_)); 192 ExpectIndex(IndexOf(static_));
171 193
172 SpdyHeaderBlock headers; 194 SpdyHeaderBlock headers;
173 headers[static_->name().as_string()] = static_->value().as_string(); 195 headers[static_->name().as_string()] = static_->value().as_string();
174 CompareWithExpectedEncoding(headers); 196 CompareWithExpectedEncoding(headers);
175 } 197 }
176 198
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 expected_.AppendUint32(6); 283 expected_.AppendUint32(6);
262 expected_.AppendBytes("@@@@@@"); 284 expected_.AppendBytes("@@@@@@");
263 285
264 string expected_out, actual_out; 286 string expected_out, actual_out;
265 expected_.TakeString(&expected_out); 287 expected_.TakeString(&expected_out);
266 peer_.TakeString(&actual_out); 288 peer_.TakeString(&actual_out);
267 EXPECT_EQ(expected_out, actual_out); 289 EXPECT_EQ(expected_out, actual_out);
268 } 290 }
269 291
270 TEST_F(HpackEncoderTest, EncodingWithoutCompression) { 292 TEST_F(HpackEncoderTest, EncodingWithoutCompression) {
293 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
294 this->SaveHeaders(name, value);
295 });
296
271 // Implementation should internally disable. 297 // Implementation should internally disable.
272 peer_.set_allow_huffman_compression(true); 298 peer_.set_allow_huffman_compression(true);
273 299
274 ExpectNonIndexedLiteral(":path", "/index.html"); 300 ExpectNonIndexedLiteral(":path", "/index.html");
275 ExpectNonIndexedLiteral("cookie", "foo=bar; baz=bing"); 301 ExpectNonIndexedLiteral("cookie", "foo=bar; baz=bing");
276 ExpectNonIndexedLiteral("hello", "goodbye"); 302 ExpectNonIndexedLiteral("hello", "goodbye");
277 303
278 SpdyHeaderBlock headers; 304 SpdyHeaderBlock headers;
279 headers[":path"] = "/index.html"; 305 headers[":path"] = "/index.html";
280 headers["cookie"] = "foo=bar; baz=bing"; 306 headers["cookie"] = "foo=bar; baz=bing";
281 headers["hello"] = "goodbye"; 307 headers["hello"] = "goodbye";
282 308
283 string expected_out, actual_out; 309 string expected_out, actual_out;
284 expected_.TakeString(&expected_out); 310 expected_.TakeString(&expected_out);
285 encoder_.EncodeHeaderSetWithoutCompression(headers, &actual_out); 311 encoder_.EncodeHeaderSetWithoutCompression(headers, &actual_out);
286 EXPECT_EQ(expected_out, actual_out); 312 EXPECT_EQ(expected_out, actual_out);
313
314 EXPECT_THAT(headers_observed_,
315 ElementsAre(Pair(":path", "/index.html"),
316 Pair("cookie", "foo=bar; baz=bing"),
317 Pair("hello", "goodbye")));
287 } 318 }
288 319
289 TEST_F(HpackEncoderTest, MultipleEncodingPasses) { 320 TEST_F(HpackEncoderTest, MultipleEncodingPasses) {
321 encoder_.SetHeaderListener([this](StringPiece name, StringPiece value) {
322 this->SaveHeaders(name, value);
323 });
324
290 // Pass 1. 325 // Pass 1.
291 { 326 {
292 SpdyHeaderBlock headers; 327 SpdyHeaderBlock headers;
293 headers["key1"] = "value1"; 328 headers["key1"] = "value1";
294 headers["cookie"] = "a=bb"; 329 headers["cookie"] = "a=bb";
295 330
296 ExpectIndex(IndexOf(key_1_)); 331 ExpectIndex(IndexOf(key_1_));
297 ExpectIndex(IndexOf(cookie_a_)); 332 ExpectIndex(IndexOf(cookie_a_));
298 CompareWithExpectedEncoding(headers); 333 CompareWithExpectedEncoding(headers);
299 } 334 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 ExpectIndex(65); 367 ExpectIndex(65);
333 // "cookie: a=bb" 368 // "cookie: a=bb"
334 ExpectIndex(64); 369 ExpectIndex(64);
335 // This cookie evicts |key2| from the dynamic table. 370 // This cookie evicts |key2| from the dynamic table.
336 ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "b=cc"); 371 ExpectIndexedLiteral(peer_.table()->GetByName("cookie"), "b=cc");
337 // "cookie: c=dd" 372 // "cookie: c=dd"
338 ExpectIndex(64); 373 ExpectIndex(64);
339 374
340 CompareWithExpectedEncoding(headers); 375 CompareWithExpectedEncoding(headers);
341 } 376 }
377
378 // clang-format off
379 EXPECT_THAT(headers_observed_,
380 ElementsAre(Pair("key1", "value1"),
381 Pair("cookie", "a=bb"),
382 Pair("key2", "value2"),
383 Pair("cookie", "c=dd"),
384 Pair("cookie", "e=ff"),
385 Pair("key2", "value2"),
386 Pair("cookie", "a=bb"),
387 Pair("cookie", "b=cc"),
388 Pair("cookie", "c=dd")));
389 // clang-format on
342 } 390 }
343 391
344 TEST_F(HpackEncoderTest, PseudoHeadersFirst) { 392 TEST_F(HpackEncoderTest, PseudoHeadersFirst) {
345 SpdyHeaderBlock headers; 393 SpdyHeaderBlock headers;
346 // A pseudo-header that should not be indexed. 394 // A pseudo-header that should not be indexed.
347 headers[":path"] = "/spam/eggs.html"; 395 headers[":path"] = "/spam/eggs.html";
348 // A pseudo-header to be indexed. 396 // A pseudo-header to be indexed.
349 headers[":authority"] = "www.example.com"; 397 headers[":authority"] = "www.example.com";
350 // A regular header which precedes ":" alphabetically, should still be encoded 398 // A regular header which precedes ":" alphabetically, should still be encoded
351 // after pseudo-headers. 399 // after pseudo-headers.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 CompareWithExpectedEncoding(headers); 545 CompareWithExpectedEncoding(headers);
498 546
499 HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front(); 547 HpackEntry* new_entry = &peer_.table_peer().dynamic_entries()->front();
500 EXPECT_EQ(new_entry->name(), "key3"); 548 EXPECT_EQ(new_entry->name(), "key3");
501 EXPECT_EQ(new_entry->value(), "value3"); 549 EXPECT_EQ(new_entry->value(), "value3");
502 } 550 }
503 551
504 } // namespace 552 } // namespace
505 553
506 } // namespace net 554 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack/hpack_encoder.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698