This source file includes following definitions.
- MakeEntryOfSize
- MakeEntriesOfTotalSize
- AddEntriesExpectNoEviction
- GetReferenceSet
- TEST
- TEST
- TEST
- TEST
- TEST
#include "net/spdy/hpack_header_table.h"
#include <algorithm>
#include <set>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/macros.h"
#include "net/spdy/hpack_entry.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
using std::string;
typedef std::vector<HpackEntry> HpackEntryVector;
HpackEntry MakeEntryOfSize(uint32 size) {
EXPECT_GE(size, HpackEntry::kSizeOverhead);
string name((size - HpackEntry::kSizeOverhead) / 2, 'n');
string value(size - HpackEntry::kSizeOverhead - name.size(), 'v');
HpackEntry entry(name, value);
EXPECT_EQ(size, entry.Size());
return entry;
}
HpackEntryVector MakeEntriesOfTotalSize(uint32 total_size) {
EXPECT_GE(total_size, HpackEntry::kSizeOverhead);
uint32 entry_size = HpackEntry::kSizeOverhead;
uint32 remaining_size = total_size;
HpackEntryVector entries;
while (remaining_size > 0) {
EXPECT_LE(entry_size, remaining_size);
entries.push_back(MakeEntryOfSize(entry_size));
remaining_size -= entry_size;
entry_size = std::min(remaining_size, entry_size + 32);
}
return entries;
}
void AddEntriesExpectNoEviction(const HpackEntryVector& entries,
HpackHeaderTable* header_table) {
unsigned start_entry_count = header_table->GetEntryCount();
for (HpackEntryVector::const_iterator it = entries.begin();
it != entries.end(); ++it) {
uint32 index = 0;
std::vector<uint32> removed_referenced_indices;
header_table->TryAddEntry(*it, &index, &removed_referenced_indices);
EXPECT_EQ(1u, index);
EXPECT_TRUE(removed_referenced_indices.empty());
EXPECT_EQ(start_entry_count + (it - entries.begin()) + 1u,
header_table->GetEntryCount());
}
for (HpackEntryVector::const_iterator it = entries.begin();
it != entries.end(); ++it) {
uint32 index = header_table->GetEntryCount() - (it - entries.begin());
HpackEntry entry = header_table->GetEntry(index);
EXPECT_TRUE(it->Equals(entry))
<< "it = " << it->GetDebugString() << " != entry = "
<< entry.GetDebugString();
}
}
std::set<uint32> GetReferenceSet(const HpackHeaderTable& header_table) {
std::set<uint32> reference_set;
for (uint32 i = 1; i <= header_table.GetEntryCount(); ++i) {
if (header_table.GetEntry(i).IsReferenced()) {
reference_set.insert(i);
}
}
return reference_set;
}
TEST(HpackHeaderTableTest, TryAddEntryBasic) {
HpackHeaderTable header_table;
EXPECT_EQ(0u, header_table.size());
HpackEntryVector entries = MakeEntriesOfTotalSize(header_table.max_size());
AddEntriesExpectNoEviction(entries, &header_table);
EXPECT_EQ(header_table.max_size(), header_table.size());
}
TEST(HpackHeaderTableTest, SetMaxSize) {
HpackHeaderTable header_table;
HpackEntryVector entries = MakeEntriesOfTotalSize(header_table.max_size());
AddEntriesExpectNoEviction(entries, &header_table);
for (HpackEntryVector::const_iterator it = entries.begin();
it != entries.end(); ++it) {
uint32 expected_count = entries.end() - it;
EXPECT_EQ(expected_count, header_table.GetEntryCount());
header_table.SetMaxSize(header_table.size() + 1);
EXPECT_EQ(expected_count, header_table.GetEntryCount());
header_table.SetMaxSize(header_table.size());
EXPECT_EQ(expected_count, header_table.GetEntryCount());
--expected_count;
header_table.SetMaxSize(header_table.size() - 1);
EXPECT_EQ(expected_count, header_table.GetEntryCount());
}
EXPECT_EQ(0u, header_table.size());
}
TEST(HpackHeaderTableTest, SetMaxSizeZeroClearsReferenceSet) {
HpackHeaderTable header_table;
HpackEntryVector entries = MakeEntriesOfTotalSize(header_table.max_size());
AddEntriesExpectNoEviction(entries, &header_table);
std::set<uint32> expected_reference_set;
for (uint32 i = 1; i <= header_table.GetEntryCount(); ++i) {
header_table.GetMutableEntry(i)->SetReferenced(true);
expected_reference_set.insert(i);
}
EXPECT_EQ(expected_reference_set, GetReferenceSet(header_table));
header_table.SetMaxSize(0);
EXPECT_TRUE(GetReferenceSet(header_table).empty());
}
TEST(HpackHeaderTableTest, TryAddEntryEviction) {
HpackHeaderTable header_table;
HpackEntryVector entries = MakeEntriesOfTotalSize(header_table.max_size());
AddEntriesExpectNoEviction(entries, &header_table);
EXPECT_EQ(entries.size(), header_table.GetEntryCount());
HpackEntry first_entry = header_table.GetEntry(1);
HpackEntry long_entry =
MakeEntryOfSize(header_table.size() - first_entry.Size());
header_table.SetMaxSize(header_table.size());
EXPECT_EQ(entries.size(), header_table.GetEntryCount());
std::set<uint32> expected_reference_set;
for (uint32 i = 2; i <= header_table.GetEntryCount(); ++i) {
header_table.GetMutableEntry(i)->SetReferenced(true);
expected_reference_set.insert(i);
}
EXPECT_EQ(expected_reference_set, GetReferenceSet(header_table));
uint32 index = 0;
std::vector<uint32> removed_referenced_indices;
header_table.TryAddEntry(long_entry, &index, &removed_referenced_indices);
EXPECT_EQ(1u, index);
EXPECT_EQ(expected_reference_set,
std::set<uint32>(removed_referenced_indices.begin(),
removed_referenced_indices.end()));
EXPECT_TRUE(GetReferenceSet(header_table).empty());
EXPECT_EQ(2u, header_table.GetEntryCount());
EXPECT_TRUE(header_table.GetEntry(1).Equals(long_entry));
EXPECT_TRUE(header_table.GetEntry(2).Equals(first_entry));
}
TEST(HpackHeaderTableTest, TryAddTooLargeEntry) {
HpackHeaderTable header_table;
HpackEntryVector entries = MakeEntriesOfTotalSize(header_table.max_size());
AddEntriesExpectNoEviction(entries, &header_table);
header_table.SetMaxSize(header_table.size());
EXPECT_EQ(entries.size(), header_table.GetEntryCount());
std::set<uint32> expected_removed_referenced_indices;
for (uint32 i = 1; i <= header_table.GetEntryCount(); ++i) {
header_table.GetMutableEntry(i)->SetReferenced(true);
expected_removed_referenced_indices.insert(i);
}
HpackEntry long_entry = MakeEntryOfSize(header_table.size() + 1);
uint32 index = 0;
std::vector<uint32> removed_referenced_indices;
header_table.TryAddEntry(long_entry, &index, &removed_referenced_indices);
EXPECT_EQ(0u, index);
EXPECT_EQ(expected_removed_referenced_indices,
std::set<uint32>(removed_referenced_indices.begin(),
removed_referenced_indices.end()));
EXPECT_EQ(0u, header_table.GetEntryCount());
}
}
}