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
3 // found in the LICENSE file.
4
5 #include "net/spdy/hpack_entry.h"
6
7 #include <string>
8
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace net {
12
13 namespace {
14
15 using std::string;
16
17 class HpackEntryTest : public ::testing::Test {
18 protected:
HpackEntryTest()19 HpackEntryTest()
20 : name_("header-name"),
21 value_("header value"),
22 total_insertions_(0),
23 table_size_(0) {}
24
25 // These builders maintain the same external table invariants that a "real"
26 // table (ie HpackHeaderTable) would.
StaticEntry()27 HpackEntry StaticEntry() {
28 return HpackEntry(name_, value_, true, total_insertions_++);
29 }
DynamicEntry()30 HpackEntry DynamicEntry() {
31 ++table_size_;
32 size_t index = total_insertions_++;
33 return HpackEntry(name_, value_, false, index);
34 }
DropEntry()35 void DropEntry() { --table_size_; }
36
IndexOf(const HpackEntry & entry) const37 size_t IndexOf(const HpackEntry& entry) const {
38 if (entry.IsStatic()) {
39 return 1 + entry.InsertionIndex() + table_size_;
40 } else {
41 return total_insertions_ - entry.InsertionIndex();
42 }
43 }
44
Size()45 size_t Size() {
46 return name_.size() + value_.size() + HpackEntry::kSizeOverhead;
47 }
48
49 string name_, value_;
50
51 private:
52 // Referenced by HpackEntry instances.
53 size_t total_insertions_;
54 size_t table_size_;
55 };
56
TEST_F(HpackEntryTest,StaticConstructor)57 TEST_F(HpackEntryTest, StaticConstructor) {
58 HpackEntry entry(StaticEntry());
59
60 EXPECT_EQ(name_, entry.name());
61 EXPECT_EQ(value_, entry.value());
62 EXPECT_TRUE(entry.IsStatic());
63 EXPECT_EQ(1u, IndexOf(entry));
64 EXPECT_EQ(0u, entry.state());
65 EXPECT_EQ(Size(), entry.Size());
66 }
67
TEST_F(HpackEntryTest,DynamicConstructor)68 TEST_F(HpackEntryTest, DynamicConstructor) {
69 HpackEntry entry(DynamicEntry());
70
71 EXPECT_EQ(name_, entry.name());
72 EXPECT_EQ(value_, entry.value());
73 EXPECT_FALSE(entry.IsStatic());
74 EXPECT_EQ(1u, IndexOf(entry));
75 EXPECT_EQ(0u, entry.state());
76 EXPECT_EQ(Size(), entry.Size());
77 }
78
TEST_F(HpackEntryTest,LookupConstructor)79 TEST_F(HpackEntryTest, LookupConstructor) {
80 HpackEntry entry(name_, value_);
81
82 EXPECT_EQ(name_, entry.name());
83 EXPECT_EQ(value_, entry.value());
84 EXPECT_FALSE(entry.IsStatic());
85 EXPECT_EQ(0u, IndexOf(entry));
86 EXPECT_EQ(0u, entry.state());
87 EXPECT_EQ(Size(), entry.Size());
88 }
89
TEST_F(HpackEntryTest,DefaultConstructor)90 TEST_F(HpackEntryTest, DefaultConstructor) {
91 HpackEntry entry;
92
93 EXPECT_TRUE(entry.name().empty());
94 EXPECT_TRUE(entry.value().empty());
95 EXPECT_EQ(0u, entry.state());
96 EXPECT_EQ(HpackEntry::kSizeOverhead, entry.Size());
97 }
98
TEST_F(HpackEntryTest,IndexUpdate)99 TEST_F(HpackEntryTest, IndexUpdate) {
100 HpackEntry static1(StaticEntry());
101 HpackEntry static2(StaticEntry());
102
103 EXPECT_EQ(1u, IndexOf(static1));
104 EXPECT_EQ(2u, IndexOf(static2));
105
106 HpackEntry dynamic1(DynamicEntry());
107 HpackEntry dynamic2(DynamicEntry());
108
109 EXPECT_EQ(1u, IndexOf(dynamic2));
110 EXPECT_EQ(2u, IndexOf(dynamic1));
111 EXPECT_EQ(3u, IndexOf(static1));
112 EXPECT_EQ(4u, IndexOf(static2));
113
114 DropEntry(); // Drops |dynamic1|.
115
116 EXPECT_EQ(1u, IndexOf(dynamic2));
117 EXPECT_EQ(2u, IndexOf(static1));
118 EXPECT_EQ(3u, IndexOf(static2));
119
120 HpackEntry dynamic3(DynamicEntry());
121
122 EXPECT_EQ(1u, IndexOf(dynamic3));
123 EXPECT_EQ(2u, IndexOf(dynamic2));
124 EXPECT_EQ(3u, IndexOf(static1));
125 EXPECT_EQ(4u, IndexOf(static2));
126 }
127
128 } // namespace
129
130 } // namespace net
131