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_entry.h" | 5 #include "net/spdy/hpack_entry.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace net { | 11 namespace net { |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 using std::string; | 15 using std::string; |
16 | 16 |
17 const char kName[] = "headername"; | 17 class HpackEntryTest : public ::testing::Test { |
18 const uint32 kNameStringLength = arraysize(kName) - 1; | 18 protected: |
19 const char kValue[] = "Header Value"; | 19 HpackEntryTest() |
20 const uint32 kValueStringLength = arraysize(kValue) - 1; | 20 : name_("header-name"), |
| 21 value_("header value"), |
| 22 total_insertions_(0), |
| 23 table_size_(0) {} |
21 | 24 |
22 // Make sure a default-constructed entry is still valid and starts off | 25 // These builders maintain the same external table invariants that a "real" |
23 // empty, unreferenced, and untouched. | 26 // table (ie HpackHeaderTable) would. |
24 TEST(HpackEntryTest, DefaultConstructor) { | 27 HpackEntry StaticEntry() { |
| 28 return HpackEntry(name_, value_, true, total_insertions_++, &table_size_); |
| 29 } |
| 30 HpackEntry DynamicEntry() { |
| 31 ++table_size_; |
| 32 size_t index = total_insertions_++; |
| 33 return HpackEntry(name_, value_, false, index, &total_insertions_); |
| 34 } |
| 35 void DropEntry() { --table_size_; } |
| 36 |
| 37 size_t Size() { |
| 38 return name_.size() + value_.size() + HpackEntry::kSizeOverhead; |
| 39 } |
| 40 |
| 41 string name_, value_; |
| 42 |
| 43 private: |
| 44 // Referenced by HpackEntry instances. |
| 45 size_t total_insertions_; |
| 46 size_t table_size_; |
| 47 }; |
| 48 |
| 49 TEST_F(HpackEntryTest, StaticConstructor) { |
| 50 HpackEntry entry(StaticEntry()); |
| 51 |
| 52 EXPECT_EQ(name_, entry.name()); |
| 53 EXPECT_EQ(value_, entry.value()); |
| 54 EXPECT_TRUE(entry.IsStatic()); |
| 55 EXPECT_EQ(1u, entry.Index()); |
| 56 EXPECT_EQ(0u, entry.state()); |
| 57 EXPECT_EQ(Size(), entry.Size()); |
| 58 } |
| 59 |
| 60 TEST_F(HpackEntryTest, DynamicConstructor) { |
| 61 HpackEntry entry(DynamicEntry()); |
| 62 |
| 63 EXPECT_EQ(name_, entry.name()); |
| 64 EXPECT_EQ(value_, entry.value()); |
| 65 EXPECT_FALSE(entry.IsStatic()); |
| 66 EXPECT_EQ(1u, entry.Index()); |
| 67 EXPECT_EQ(0u, entry.state()); |
| 68 EXPECT_EQ(Size(), entry.Size()); |
| 69 } |
| 70 |
| 71 TEST_F(HpackEntryTest, LookupConstructor) { |
| 72 HpackEntry entry(name_, value_); |
| 73 |
| 74 EXPECT_EQ(name_, entry.name()); |
| 75 EXPECT_EQ(value_, entry.value()); |
| 76 EXPECT_FALSE(entry.IsStatic()); |
| 77 EXPECT_EQ(0u, entry.Index()); |
| 78 EXPECT_EQ(0u, entry.state()); |
| 79 EXPECT_EQ(Size(), entry.Size()); |
| 80 } |
| 81 |
| 82 TEST_F(HpackEntryTest, DefaultConstructor) { |
25 HpackEntry entry; | 83 HpackEntry entry; |
| 84 |
26 EXPECT_TRUE(entry.name().empty()); | 85 EXPECT_TRUE(entry.name().empty()); |
27 EXPECT_TRUE(entry.value().empty()); | 86 EXPECT_TRUE(entry.value().empty()); |
28 EXPECT_FALSE(entry.IsReferenced()); | 87 EXPECT_EQ(0u, entry.state()); |
29 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
30 EXPECT_EQ(HpackEntry::kSizeOverhead, entry.Size()); | 88 EXPECT_EQ(HpackEntry::kSizeOverhead, entry.Size()); |
31 } | 89 } |
32 | 90 |
33 // Make sure a non-default-constructed HpackEntry starts off with | 91 TEST_F(HpackEntryTest, IndexUpdate) { |
34 // copies of the given name and value, and unreferenced and untouched. | 92 HpackEntry static1(StaticEntry()); |
35 TEST(HpackEntryTest, NormalConstructor) { | 93 HpackEntry static2(StaticEntry()); |
36 string name = kName; | |
37 string value = kValue; | |
38 HpackEntry entry(name, value); | |
39 EXPECT_EQ(name, entry.name()); | |
40 EXPECT_EQ(value, entry.value()); | |
41 | 94 |
42 ++name[0]; | 95 EXPECT_EQ(1u, static1.Index()); |
43 ++value[0]; | 96 EXPECT_EQ(2u, static2.Index()); |
44 EXPECT_NE(name, entry.name()); | |
45 EXPECT_NE(value, entry.name()); | |
46 | 97 |
47 EXPECT_FALSE(entry.IsReferenced()); | 98 HpackEntry dynamic1(DynamicEntry()); |
48 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | 99 HpackEntry dynamic2(DynamicEntry()); |
49 EXPECT_EQ( | 100 |
50 kNameStringLength + kValueStringLength + HpackEntry::kSizeOverhead, | 101 EXPECT_EQ(1u, dynamic2.Index()); |
51 entry.Size()); | 102 EXPECT_EQ(2u, dynamic1.Index()); |
| 103 EXPECT_EQ(3u, static1.Index()); |
| 104 EXPECT_EQ(4u, static2.Index()); |
| 105 |
| 106 DropEntry(); // Drops |dynamic1|. |
| 107 |
| 108 EXPECT_EQ(1u, dynamic2.Index()); |
| 109 EXPECT_EQ(2u, static1.Index()); |
| 110 EXPECT_EQ(3u, static2.Index()); |
| 111 |
| 112 HpackEntry dynamic3(DynamicEntry()); |
| 113 |
| 114 EXPECT_EQ(1u, dynamic3.Index()); |
| 115 EXPECT_EQ(2u, dynamic2.Index()); |
| 116 EXPECT_EQ(3u, static1.Index()); |
| 117 EXPECT_EQ(4u, static2.Index()); |
52 } | 118 } |
53 | 119 |
54 // Make sure twiddling the referenced bit doesn't affect the touch | 120 TEST_F(HpackEntryTest, ComparatorNameOrdering) { |
55 // count when it's kUntouched. | 121 HpackEntry entry1(StaticEntry()); |
56 TEST(HpackEntryTest, IsReferencedUntouched) { | 122 name_[0]--; |
57 HpackEntry entry(kName, kValue); | 123 HpackEntry entry2(StaticEntry()); |
58 EXPECT_FALSE(entry.IsReferenced()); | |
59 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
60 | 124 |
61 entry.SetReferenced(true); | 125 EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry2)); |
62 EXPECT_TRUE(entry.IsReferenced()); | 126 EXPECT_TRUE(HpackEntry::Comparator()(&entry2, &entry1)); |
63 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
64 | |
65 entry.SetReferenced(false); | |
66 EXPECT_FALSE(entry.IsReferenced()); | |
67 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
68 } | 127 } |
69 | 128 |
70 // Make sure changing the touch count doesn't affect the referenced | 129 TEST_F(HpackEntryTest, ComparatorValueOrdering) { |
71 // bit when it's false. | 130 HpackEntry entry1(StaticEntry()); |
72 TEST(HpackEntryTest, TouchCountNotReferenced) { | 131 value_[0]--; |
73 HpackEntry entry(kName, kValue); | 132 HpackEntry entry2(StaticEntry()); |
74 EXPECT_FALSE(entry.IsReferenced()); | |
75 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
76 | 133 |
77 entry.AddTouches(0); | 134 EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry2)); |
78 EXPECT_FALSE(entry.IsReferenced()); | 135 EXPECT_TRUE(HpackEntry::Comparator()(&entry2, &entry1)); |
79 EXPECT_EQ(0u, entry.TouchCount()); | |
80 | |
81 entry.AddTouches(255); | |
82 EXPECT_FALSE(entry.IsReferenced()); | |
83 EXPECT_EQ(255u, entry.TouchCount()); | |
84 | |
85 // Assumes kUntouched is 1 + max touch count. | |
86 entry.AddTouches(HpackEntry::kUntouched - 256); | |
87 EXPECT_FALSE(entry.IsReferenced()); | |
88 EXPECT_EQ(HpackEntry::kUntouched - 1, entry.TouchCount()); | |
89 | |
90 entry.ClearTouches(); | |
91 EXPECT_FALSE(entry.IsReferenced()); | |
92 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
93 } | 136 } |
94 | 137 |
95 // Make sure changing the touch count doesn't affect the referenced | 138 TEST_F(HpackEntryTest, ComparatorIndexOrdering) { |
96 // bit when it's true. | 139 HpackEntry entry1(StaticEntry()); |
97 TEST(HpackEntryTest, TouchCountReferenced) { | 140 HpackEntry entry2(StaticEntry()); |
98 HpackEntry entry(kName, kValue); | |
99 entry.SetReferenced(true); | |
100 EXPECT_TRUE(entry.IsReferenced()); | |
101 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | |
102 | 141 |
103 entry.AddTouches(0); | 142 EXPECT_TRUE(HpackEntry::Comparator()(&entry1, &entry2)); |
104 EXPECT_TRUE(entry.IsReferenced()); | 143 EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry1)); |
105 EXPECT_EQ(0u, entry.TouchCount()); | |
106 | 144 |
107 entry.AddTouches(255); | 145 HpackEntry entry3(DynamicEntry()); |
108 EXPECT_TRUE(entry.IsReferenced()); | 146 HpackEntry entry4(DynamicEntry()); |
109 EXPECT_EQ(255u, entry.TouchCount()); | |
110 | 147 |
111 // Assumes kUntouched is 1 + max touch count. | 148 // |entry4| has lower index than |entry3|. |
112 entry.AddTouches(HpackEntry::kUntouched - 256); | 149 EXPECT_TRUE(HpackEntry::Comparator()(&entry4, &entry3)); |
113 EXPECT_TRUE(entry.IsReferenced()); | 150 EXPECT_FALSE(HpackEntry::Comparator()(&entry3, &entry4)); |
114 EXPECT_EQ(HpackEntry::kUntouched - 1, entry.TouchCount()); | |
115 | 151 |
116 entry.ClearTouches(); | 152 // |entry3| has lower index than |entry1|. |
117 EXPECT_TRUE(entry.IsReferenced()); | 153 EXPECT_TRUE(HpackEntry::Comparator()(&entry3, &entry1)); |
118 EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount()); | 154 EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry3)); |
| 155 |
| 156 // |entry1| & |entry2| ordering is preserved, though each Index() has changed. |
| 157 EXPECT_TRUE(HpackEntry::Comparator()(&entry1, &entry2)); |
| 158 EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry1)); |
119 } | 159 } |
120 | 160 |
121 // Make sure equality takes into account all entry fields. | 161 TEST_F(HpackEntryTest, ComparatorEqualityOrdering) { |
122 TEST(HpackEntryTest, Equals) { | 162 HpackEntry entry1(StaticEntry()); |
123 HpackEntry entry1(kName, kValue); | 163 HpackEntry entry2(DynamicEntry()); |
124 HpackEntry entry2(kName, kValue); | |
125 EXPECT_TRUE(entry1.Equals(entry2)); | |
126 | 164 |
127 entry2.SetReferenced(true); | 165 EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry1)); |
128 EXPECT_FALSE(entry1.Equals(entry2)); | 166 EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry2)); |
129 entry2.SetReferenced(false); | |
130 EXPECT_TRUE(entry1.Equals(entry2)); | |
131 | |
132 entry2.AddTouches(0); | |
133 EXPECT_FALSE(entry1.Equals(entry2)); | |
134 entry2.ClearTouches(); | |
135 EXPECT_TRUE(entry1.Equals(entry2)); | |
136 | |
137 entry2.AddTouches(1); | |
138 EXPECT_FALSE(entry1.Equals(entry2)); | |
139 entry2.ClearTouches(); | |
140 EXPECT_TRUE(entry1.Equals(entry2)); | |
141 | |
142 HpackEntry entry3(kName, string(kValue) + kValue); | |
143 EXPECT_FALSE(entry1.Equals(entry3)); | |
144 | |
145 HpackEntry entry4(string(kName) + kName, kValue); | |
146 EXPECT_FALSE(entry1.Equals(entry4)); | |
147 } | 167 } |
148 | 168 |
149 } // namespace | 169 } // namespace |
150 | 170 |
151 } // namespace net | 171 } // namespace net |
OLD | NEW |