using std::string;
-const char kName[] = "headername";
-const uint32 kNameStringLength = arraysize(kName) - 1;
-const char kValue[] = "Header Value";
-const uint32 kValueStringLength = arraysize(kValue) - 1;
-
-// Make sure a default-constructed entry is still valid and starts off
-// empty, unreferenced, and untouched.
-TEST(HpackEntryTest, DefaultConstructor) {
+class HpackEntryTest : public ::testing::Test {
+ protected:
+ HpackEntryTest()
+ : name_("header-name"),
+ value_("header value"),
+ total_insertions_(0),
+ table_size_(0) {}
+
+ // These builders maintain the same external table invariants that a "real"
+ // table (ie HpackHeaderTable) would.
+ HpackEntry StaticEntry() {
+ return HpackEntry(name_, value_, true, total_insertions_++, &table_size_);
+ }
+ HpackEntry DynamicEntry() {
+ ++table_size_;
+ size_t index = total_insertions_++;
+ return HpackEntry(name_, value_, false, index, &total_insertions_);
+ }
+ void DropEntry() { --table_size_; }
+
+ size_t Size() {
+ return name_.size() + value_.size() + HpackEntry::kSizeOverhead;
+ }
+
+ string name_, value_;
+
+ private:
+ // Referenced by HpackEntry instances.
+ size_t total_insertions_;
+ size_t table_size_;
+};
+
+TEST_F(HpackEntryTest, StaticConstructor) {
+ HpackEntry entry(StaticEntry());
+
+ EXPECT_EQ(name_, entry.name());
+ EXPECT_EQ(value_, entry.value());
+ EXPECT_TRUE(entry.IsStatic());
+ EXPECT_EQ(1u, entry.Index());
+ EXPECT_EQ(0u, entry.state());
+ EXPECT_EQ(Size(), entry.Size());
+}
+
+TEST_F(HpackEntryTest, DynamicConstructor) {
+ HpackEntry entry(DynamicEntry());
+
+ EXPECT_EQ(name_, entry.name());
+ EXPECT_EQ(value_, entry.value());
+ EXPECT_FALSE(entry.IsStatic());
+ EXPECT_EQ(1u, entry.Index());
+ EXPECT_EQ(0u, entry.state());
+ EXPECT_EQ(Size(), entry.Size());
+}
+
+TEST_F(HpackEntryTest, LookupConstructor) {
+ HpackEntry entry(name_, value_);
+
+ EXPECT_EQ(name_, entry.name());
+ EXPECT_EQ(value_, entry.value());
+ EXPECT_FALSE(entry.IsStatic());
+ EXPECT_EQ(0u, entry.Index());
+ EXPECT_EQ(0u, entry.state());
+ EXPECT_EQ(Size(), entry.Size());
+}
+
+TEST_F(HpackEntryTest, DefaultConstructor) {
HpackEntry entry;
+
EXPECT_TRUE(entry.name().empty());
EXPECT_TRUE(entry.value().empty());
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+ EXPECT_EQ(0u, entry.state());
EXPECT_EQ(HpackEntry::kSizeOverhead, entry.Size());
}
-// Make sure a non-default-constructed HpackEntry starts off with
-// copies of the given name and value, and unreferenced and untouched.
-TEST(HpackEntryTest, NormalConstructor) {
- string name = kName;
- string value = kValue;
- HpackEntry entry(name, value);
- EXPECT_EQ(name, entry.name());
- EXPECT_EQ(value, entry.value());
-
- ++name[0];
- ++value[0];
- EXPECT_NE(name, entry.name());
- EXPECT_NE(value, entry.name());
-
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
- EXPECT_EQ(
- kNameStringLength + kValueStringLength + HpackEntry::kSizeOverhead,
- entry.Size());
-}
+TEST_F(HpackEntryTest, IndexUpdate) {
+ HpackEntry static1(StaticEntry());
+ HpackEntry static2(StaticEntry());
-// Make sure twiddling the referenced bit doesn't affect the touch
-// count when it's kUntouched.
-TEST(HpackEntryTest, IsReferencedUntouched) {
- HpackEntry entry(kName, kValue);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+ EXPECT_EQ(1u, static1.Index());
+ EXPECT_EQ(2u, static2.Index());
- entry.SetReferenced(true);
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+ HpackEntry dynamic1(DynamicEntry());
+ HpackEntry dynamic2(DynamicEntry());
- entry.SetReferenced(false);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+ EXPECT_EQ(1u, dynamic2.Index());
+ EXPECT_EQ(2u, dynamic1.Index());
+ EXPECT_EQ(3u, static1.Index());
+ EXPECT_EQ(4u, static2.Index());
+
+ DropEntry(); // Drops |dynamic1|.
+
+ EXPECT_EQ(1u, dynamic2.Index());
+ EXPECT_EQ(2u, static1.Index());
+ EXPECT_EQ(3u, static2.Index());
+
+ HpackEntry dynamic3(DynamicEntry());
+
+ EXPECT_EQ(1u, dynamic3.Index());
+ EXPECT_EQ(2u, dynamic2.Index());
+ EXPECT_EQ(3u, static1.Index());
+ EXPECT_EQ(4u, static2.Index());
}
-// Make sure changing the touch count doesn't affect the referenced
-// bit when it's false.
-TEST(HpackEntryTest, TouchCountNotReferenced) {
- HpackEntry entry(kName, kValue);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
-
- entry.AddTouches(0);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(0u, entry.TouchCount());
-
- entry.AddTouches(255);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(255u, entry.TouchCount());
-
- // Assumes kUntouched is 1 + max touch count.
- entry.AddTouches(HpackEntry::kUntouched - 256);
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched - 1, entry.TouchCount());
-
- entry.ClearTouches();
- EXPECT_FALSE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+TEST_F(HpackEntryTest, ComparatorNameOrdering) {
+ HpackEntry entry1(StaticEntry());
+ name_[0]--;
+ HpackEntry entry2(StaticEntry());
+
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry2));
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry2, &entry1));
}
-// Make sure changing the touch count doesn't affect the referenced
-// bit when it's true.
-TEST(HpackEntryTest, TouchCountReferenced) {
- HpackEntry entry(kName, kValue);
- entry.SetReferenced(true);
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
-
- entry.AddTouches(0);
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(0u, entry.TouchCount());
-
- entry.AddTouches(255);
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(255u, entry.TouchCount());
-
- // Assumes kUntouched is 1 + max touch count.
- entry.AddTouches(HpackEntry::kUntouched - 256);
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched - 1, entry.TouchCount());
-
- entry.ClearTouches();
- EXPECT_TRUE(entry.IsReferenced());
- EXPECT_EQ(HpackEntry::kUntouched, entry.TouchCount());
+TEST_F(HpackEntryTest, ComparatorValueOrdering) {
+ HpackEntry entry1(StaticEntry());
+ value_[0]--;
+ HpackEntry entry2(StaticEntry());
+
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry2));
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry2, &entry1));
}
-// Make sure equality takes into account all entry fields.
-TEST(HpackEntryTest, Equals) {
- HpackEntry entry1(kName, kValue);
- HpackEntry entry2(kName, kValue);
- EXPECT_TRUE(entry1.Equals(entry2));
+TEST_F(HpackEntryTest, ComparatorIndexOrdering) {
+ HpackEntry entry1(StaticEntry());
+ HpackEntry entry2(StaticEntry());
+
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry1, &entry2));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry1));
- entry2.SetReferenced(true);
- EXPECT_FALSE(entry1.Equals(entry2));
- entry2.SetReferenced(false);
- EXPECT_TRUE(entry1.Equals(entry2));
+ HpackEntry entry3(DynamicEntry());
+ HpackEntry entry4(DynamicEntry());
- entry2.AddTouches(0);
- EXPECT_FALSE(entry1.Equals(entry2));
- entry2.ClearTouches();
- EXPECT_TRUE(entry1.Equals(entry2));
+ // |entry4| has lower index than |entry3|.
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry4, &entry3));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry3, &entry4));
- entry2.AddTouches(1);
- EXPECT_FALSE(entry1.Equals(entry2));
- entry2.ClearTouches();
- EXPECT_TRUE(entry1.Equals(entry2));
+ // |entry3| has lower index than |entry1|.
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry3, &entry1));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry3));
+
+ // |entry1| & |entry2| ordering is preserved, though each Index() has changed.
+ EXPECT_TRUE(HpackEntry::Comparator()(&entry1, &entry2));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry1));
+}
- HpackEntry entry3(kName, string(kValue) + kValue);
- EXPECT_FALSE(entry1.Equals(entry3));
+TEST_F(HpackEntryTest, ComparatorEqualityOrdering) {
+ HpackEntry entry1(StaticEntry());
+ HpackEntry entry2(DynamicEntry());
- HpackEntry entry4(string(kName) + kName, kValue);
- EXPECT_FALSE(entry1.Equals(entry4));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry1, &entry1));
+ EXPECT_FALSE(HpackEntry::Comparator()(&entry2, &entry2));
}
} // namespace