OLD | NEW |
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_header_table.h" | 5 #include "net/spdy/hpack/hpack_header_table.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <string> | |
10 #include <vector> | 9 #include <vector> |
11 | 10 |
12 #include "base/macros.h" | 11 #include "base/macros.h" |
13 #include "net/spdy/hpack/hpack_constants.h" | 12 #include "net/spdy/hpack/hpack_constants.h" |
14 #include "net/spdy/hpack/hpack_entry.h" | 13 #include "net/spdy/hpack/hpack_entry.h" |
| 14 #include "net/spdy/platform/api/spdy_string.h" |
15 #include "net/spdy/spdy_flags.h" | 15 #include "net/spdy/spdy_flags.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace net { | 18 namespace net { |
19 | 19 |
20 using std::distance; | 20 using std::distance; |
21 using std::string; | |
22 | 21 |
23 namespace test { | 22 namespace test { |
24 | 23 |
25 class HpackHeaderTablePeer { | 24 class HpackHeaderTablePeer { |
26 public: | 25 public: |
27 explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {} | 26 explicit HpackHeaderTablePeer(HpackHeaderTable* table) : table_(table) {} |
28 | 27 |
29 const HpackHeaderTable::EntryTable& dynamic_entries() { | 28 const HpackHeaderTable::EntryTable& dynamic_entries() { |
30 return table_->dynamic_entries_; | 29 return table_->dynamic_entries_; |
31 } | 30 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 69 |
71 class HpackHeaderTableTest : public ::testing::Test { | 70 class HpackHeaderTableTest : public ::testing::Test { |
72 protected: | 71 protected: |
73 typedef std::vector<HpackEntry> HpackEntryVector; | 72 typedef std::vector<HpackEntry> HpackEntryVector; |
74 | 73 |
75 HpackHeaderTableTest() : table_(), peer_(&table_) {} | 74 HpackHeaderTableTest() : table_(), peer_(&table_) {} |
76 | 75 |
77 // Returns an entry whose Size() is equal to the given one. | 76 // Returns an entry whose Size() is equal to the given one. |
78 static HpackEntry MakeEntryOfSize(uint32_t size) { | 77 static HpackEntry MakeEntryOfSize(uint32_t size) { |
79 EXPECT_GE(size, HpackEntry::kSizeOverhead); | 78 EXPECT_GE(size, HpackEntry::kSizeOverhead); |
80 string name((size - HpackEntry::kSizeOverhead) / 2, 'n'); | 79 SpdyString name((size - HpackEntry::kSizeOverhead) / 2, 'n'); |
81 string value(size - HpackEntry::kSizeOverhead - name.size(), 'v'); | 80 SpdyString value(size - HpackEntry::kSizeOverhead - name.size(), 'v'); |
82 HpackEntry entry(name, value, false, 0); | 81 HpackEntry entry(name, value, false, 0); |
83 EXPECT_EQ(size, entry.Size()); | 82 EXPECT_EQ(size, entry.Size()); |
84 return entry; | 83 return entry; |
85 } | 84 } |
86 | 85 |
87 // Returns a vector of entries whose total size is equal to the given | 86 // Returns a vector of entries whose total size is equal to the given |
88 // one. | 87 // one. |
89 static HpackEntryVector MakeEntriesOfTotalSize(uint32_t total_size) { | 88 static HpackEntryVector MakeEntriesOfTotalSize(uint32_t total_size) { |
90 EXPECT_GE(total_size, HpackEntry::kSizeOverhead); | 89 EXPECT_GE(total_size, HpackEntry::kSizeOverhead); |
91 uint32_t entry_size = HpackEntry::kSizeOverhead; | 90 uint32_t entry_size = HpackEntry::kSizeOverhead; |
(...skipping 25 matching lines...) Expand all Loading... |
117 for (size_t i = 0; i != entries.size(); ++i) { | 116 for (size_t i = 0; i != entries.size(); ++i) { |
118 // Static table has 61 entries, dynamic entries follow those. | 117 // Static table has 61 entries, dynamic entries follow those. |
119 size_t index = 61 + entries.size() - i; | 118 size_t index = 61 + entries.size() - i; |
120 const HpackEntry* entry = table_.GetByIndex(index); | 119 const HpackEntry* entry = table_.GetByIndex(index); |
121 EXPECT_EQ(entries[i].name(), entry->name()); | 120 EXPECT_EQ(entries[i].name(), entry->name()); |
122 EXPECT_EQ(entries[i].value(), entry->value()); | 121 EXPECT_EQ(entries[i].value(), entry->value()); |
123 EXPECT_EQ(index, table_.IndexOf(entry)); | 122 EXPECT_EQ(index, table_.IndexOf(entry)); |
124 } | 123 } |
125 } | 124 } |
126 | 125 |
127 HpackEntry DynamicEntry(const string& name, const string& value) { | 126 HpackEntry DynamicEntry(const SpdyString& name, const SpdyString& value) { |
128 peer_.AddDynamicEntry(name, value); | 127 peer_.AddDynamicEntry(name, value); |
129 return peer_.dynamic_entries().back(); | 128 return peer_.dynamic_entries().back(); |
130 } | 129 } |
131 | 130 |
132 HpackHeaderTable table_; | 131 HpackHeaderTable table_; |
133 test::HpackHeaderTablePeer peer_; | 132 test::HpackHeaderTablePeer peer_; |
134 }; | 133 }; |
135 | 134 |
136 TEST_F(HpackHeaderTableTest, StaticTableInitialization) { | 135 TEST_F(HpackHeaderTableTest, StaticTableInitialization) { |
137 EXPECT_EQ(0u, table_.size()); | 136 EXPECT_EQ(0u, table_.size()); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 EXPECT_EQ(entry2, | 251 EXPECT_EQ(entry2, |
253 table_.GetByNameAndValue(first_static_entry->name(), "Value Four")); | 252 table_.GetByNameAndValue(first_static_entry->name(), "Value Four")); |
254 | 253 |
255 // Evict |entry2|. Queries by its name & value are not found. | 254 // Evict |entry2|. Queries by its name & value are not found. |
256 peer_.Evict(1); | 255 peer_.Evict(1); |
257 EXPECT_EQ(NULL, | 256 EXPECT_EQ(NULL, |
258 table_.GetByNameAndValue(first_static_entry->name(), "Value Four")); | 257 table_.GetByNameAndValue(first_static_entry->name(), "Value Four")); |
259 } | 258 } |
260 | 259 |
261 TEST_F(HpackHeaderTableTest, SetSizes) { | 260 TEST_F(HpackHeaderTableTest, SetSizes) { |
262 string key = "key", value = "value"; | 261 SpdyString key = "key", value = "value"; |
263 const HpackEntry* entry1 = table_.TryAddEntry(key, value); | 262 const HpackEntry* entry1 = table_.TryAddEntry(key, value); |
264 const HpackEntry* entry2 = table_.TryAddEntry(key, value); | 263 const HpackEntry* entry2 = table_.TryAddEntry(key, value); |
265 const HpackEntry* entry3 = table_.TryAddEntry(key, value); | 264 const HpackEntry* entry3 = table_.TryAddEntry(key, value); |
266 | 265 |
267 // Set exactly large enough. No Evictions. | 266 // Set exactly large enough. No Evictions. |
268 size_t max_size = entry1->Size() + entry2->Size() + entry3->Size(); | 267 size_t max_size = entry1->Size() + entry2->Size() + entry3->Size(); |
269 table_.SetMaxSize(max_size); | 268 table_.SetMaxSize(max_size); |
270 EXPECT_EQ(3u, peer_.dynamic_entries().size()); | 269 EXPECT_EQ(3u, peer_.dynamic_entries().size()); |
271 | 270 |
272 // Set just too small. One eviction. | 271 // Set just too small. One eviction. |
(...skipping 11 matching lines...) Expand all Loading... |
284 // SETTINGS_HEADER_TABLE_SIZE upper-bounds |table_.max_size()|, | 283 // SETTINGS_HEADER_TABLE_SIZE upper-bounds |table_.max_size()|, |
285 // and will force evictions. | 284 // and will force evictions. |
286 max_size = entry3->Size() - 1; | 285 max_size = entry3->Size() - 1; |
287 table_.SetSettingsHeaderTableSize(max_size); | 286 table_.SetSettingsHeaderTableSize(max_size); |
288 EXPECT_EQ(max_size, table_.max_size()); | 287 EXPECT_EQ(max_size, table_.max_size()); |
289 EXPECT_EQ(max_size, table_.settings_size_bound()); | 288 EXPECT_EQ(max_size, table_.settings_size_bound()); |
290 EXPECT_EQ(0u, peer_.dynamic_entries().size()); | 289 EXPECT_EQ(0u, peer_.dynamic_entries().size()); |
291 } | 290 } |
292 | 291 |
293 TEST_F(HpackHeaderTableTest, EvictionCountForEntry) { | 292 TEST_F(HpackHeaderTableTest, EvictionCountForEntry) { |
294 string key = "key", value = "value"; | 293 SpdyString key = "key", value = "value"; |
295 const HpackEntry* entry1 = table_.TryAddEntry(key, value); | 294 const HpackEntry* entry1 = table_.TryAddEntry(key, value); |
296 const HpackEntry* entry2 = table_.TryAddEntry(key, value); | 295 const HpackEntry* entry2 = table_.TryAddEntry(key, value); |
297 size_t entry3_size = HpackEntry::Size(key, value); | 296 size_t entry3_size = HpackEntry::Size(key, value); |
298 | 297 |
299 // Just enough capacity for third entry. | 298 // Just enough capacity for third entry. |
300 table_.SetMaxSize(entry1->Size() + entry2->Size() + entry3_size); | 299 table_.SetMaxSize(entry1->Size() + entry2->Size() + entry3_size); |
301 EXPECT_EQ(0u, peer_.EvictionCountForEntry(key, value)); | 300 EXPECT_EQ(0u, peer_.EvictionCountForEntry(key, value)); |
302 EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value + "x")); | 301 EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value + "x")); |
303 | 302 |
304 // No extra capacity. Third entry would force evictions. | 303 // No extra capacity. Third entry would force evictions. |
305 table_.SetMaxSize(entry1->Size() + entry2->Size()); | 304 table_.SetMaxSize(entry1->Size() + entry2->Size()); |
306 EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value)); | 305 EXPECT_EQ(1u, peer_.EvictionCountForEntry(key, value)); |
307 EXPECT_EQ(2u, peer_.EvictionCountForEntry(key, value + "x")); | 306 EXPECT_EQ(2u, peer_.EvictionCountForEntry(key, value + "x")); |
308 } | 307 } |
309 | 308 |
310 TEST_F(HpackHeaderTableTest, EvictionCountToReclaim) { | 309 TEST_F(HpackHeaderTableTest, EvictionCountToReclaim) { |
311 string key = "key", value = "value"; | 310 SpdyString key = "key", value = "value"; |
312 const HpackEntry* entry1 = table_.TryAddEntry(key, value); | 311 const HpackEntry* entry1 = table_.TryAddEntry(key, value); |
313 const HpackEntry* entry2 = table_.TryAddEntry(key, value); | 312 const HpackEntry* entry2 = table_.TryAddEntry(key, value); |
314 | 313 |
315 EXPECT_EQ(1u, peer_.EvictionCountToReclaim(1)); | 314 EXPECT_EQ(1u, peer_.EvictionCountToReclaim(1)); |
316 EXPECT_EQ(1u, peer_.EvictionCountToReclaim(entry1->Size())); | 315 EXPECT_EQ(1u, peer_.EvictionCountToReclaim(entry1->Size())); |
317 EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + 1)); | 316 EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + 1)); |
318 EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + entry2->Size())); | 317 EXPECT_EQ(2u, peer_.EvictionCountToReclaim(entry1->Size() + entry2->Size())); |
319 } | 318 } |
320 | 319 |
321 // Fill a header table with entries. Make sure the entries are in | 320 // Fill a header table with entries. Make sure the entries are in |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 HpackHeaderTable::EntryHasher hasher; | 439 HpackHeaderTable::EntryHasher hasher; |
441 EXPECT_EQ(hasher(&entry1), hasher(&entry2)); | 440 EXPECT_EQ(hasher(&entry1), hasher(&entry2)); |
442 | 441 |
443 HpackHeaderTable::EntriesEq eq; | 442 HpackHeaderTable::EntriesEq eq; |
444 EXPECT_TRUE(eq(&entry1, &entry2)); | 443 EXPECT_TRUE(eq(&entry1, &entry2)); |
445 } | 444 } |
446 | 445 |
447 } // namespace | 446 } // namespace |
448 | 447 |
449 } // namespace net | 448 } // namespace net |
OLD | NEW |