Port Android relocation packer to chromium build
[chromium-blink-merge.git] / net / spdy / hpack_huffman_aggregator_test.cc
blob23a9a43edb762e21553c8a99ed70c66645d723e1
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 #include "net/spdy/hpack_huffman_aggregator.h"
6 #include "base/metrics/histogram.h"
7 #include "base/metrics/statistics_recorder.h"
8 #include "net/base/load_flags.h"
9 #include "net/http/http_request_headers.h"
10 #include "net/http/http_request_info.h"
11 #include "net/http/http_response_headers.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace net {
17 using ::testing::Each;
18 using ::testing::ElementsAre;
19 using ::testing::Eq;
20 using ::testing::Pair;
22 namespace {
23 const char kHistogramName[] = "Net.SpdyHpackEncodedCharacterFrequency";
24 } // namespace
26 namespace test {
28 class HpackHuffmanAggregatorPeer {
29 public:
30 explicit HpackHuffmanAggregatorPeer(HpackHuffmanAggregator* agg)
31 : agg_(agg) {}
33 std::vector<size_t>* counts() {
34 return &agg_->counts_;
36 HpackHuffmanAggregator::OriginEncoders* encoders() {
37 return &agg_->encoders_;
39 size_t total_counts() {
40 return agg_->total_counts_;
42 void set_total_counts(size_t total_counts) {
43 agg_->total_counts_ = total_counts;
45 void set_max_encoders(size_t max_encoders) {
46 agg_->max_encoders_ = max_encoders;
48 static bool IsCrossOrigin(const HttpRequestInfo& request) {
49 return HpackHuffmanAggregator::IsCrossOrigin(request);
51 static void CreateSpdyHeadersFromHttpResponse(
52 const HttpResponseHeaders& headers,
53 SpdyHeaderBlock* headers_out) {
54 HpackHuffmanAggregator::CreateSpdyHeadersFromHttpResponse(
55 headers, headers_out);
57 HpackEncoder* ObtainEncoder(const SpdySessionKey& key) {
58 return agg_->ObtainEncoder(key);
60 void PublishCounts() {
61 agg_->PublishCounts();
64 private:
65 HpackHuffmanAggregator* agg_;
68 } // namespace test
70 class HpackHuffmanAggregatorTest : public ::testing::Test {
71 protected:
72 HpackHuffmanAggregatorTest()
73 : peer_(&agg_) {}
75 HpackHuffmanAggregator agg_;
76 test::HpackHuffmanAggregatorPeer peer_;
79 TEST_F(HpackHuffmanAggregatorTest, CrossOriginDetermination) {
80 HttpRequestInfo request;
81 request.url = GURL("https://www.foo.com/a/page");
83 // Main load without referer.
84 request.load_flags = LOAD_MAIN_FRAME;
85 EXPECT_FALSE(peer_.IsCrossOrigin(request));
87 // Non-main load without referer. Treated as cross-origin.
88 request.load_flags = 0;
89 EXPECT_TRUE(peer_.IsCrossOrigin(request));
91 // Main load with different referer origin.
92 request.load_flags = LOAD_MAIN_FRAME;
93 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
94 "https://www.bar.com/other/page");
95 EXPECT_FALSE(peer_.IsCrossOrigin(request));
97 // Non-main load with different referer orign.
98 request.load_flags = 0;
99 EXPECT_TRUE(peer_.IsCrossOrigin(request));
101 // Non-main load with same referer orign.
102 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
103 "https://www.foo.com/other/page");
104 EXPECT_FALSE(peer_.IsCrossOrigin(request));
106 // Non-main load with same referer host but different schemes.
107 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
108 "http://www.foo.com/other/page");
109 EXPECT_TRUE(peer_.IsCrossOrigin(request));
112 TEST_F(HpackHuffmanAggregatorTest, EncoderLRUQueue) {
113 peer_.set_max_encoders(2);
115 SpdySessionKey key1(HostPortPair("one.com", 443), ProxyServer::Direct(),
116 PRIVACY_MODE_ENABLED);
117 SpdySessionKey key2(HostPortPair("two.com", 443), ProxyServer::Direct(),
118 PRIVACY_MODE_ENABLED);
119 SpdySessionKey key3(HostPortPair("three.com", 443), ProxyServer::Direct(),
120 PRIVACY_MODE_ENABLED);
122 // Creates one.com.
123 HpackEncoder* one = peer_.ObtainEncoder(key1);
124 EXPECT_EQ(1u, peer_.encoders()->size());
126 // Creates two.com. No evictions.
127 HpackEncoder* two = peer_.ObtainEncoder(key2);
128 EXPECT_EQ(2u, peer_.encoders()->size());
129 EXPECT_NE(one, two);
131 // Touch one.com.
132 EXPECT_EQ(one, peer_.ObtainEncoder(key1));
134 // Creates three.com. Evicts two.com, as it's least-recently used.
135 HpackEncoder* three = peer_.ObtainEncoder(key3);
136 EXPECT_EQ(one, peer_.ObtainEncoder(key1));
137 EXPECT_NE(one, three);
138 EXPECT_EQ(2u, peer_.encoders()->size());
141 TEST_F(HpackHuffmanAggregatorTest, PublishCounts) {
142 (*peer_.counts())[0] = 1;
143 (*peer_.counts())[255] = 10;
144 (*peer_.counts())[128] = 101;
145 peer_.set_total_counts(112);
147 peer_.PublishCounts();
149 // Internal counts were reset after being published.
150 EXPECT_THAT(*peer_.counts(), Each(Eq(0u)));
151 EXPECT_EQ(0u, peer_.total_counts());
153 // Verify histogram counts match the expectation.
154 scoped_ptr<base::HistogramSamples> samples =
155 base::StatisticsRecorder::FindHistogram(kHistogramName)
156 ->SnapshotSamples();
158 EXPECT_EQ(0, samples->GetCount(0));
159 EXPECT_EQ(1, samples->GetCount(1));
160 EXPECT_EQ(101, samples->GetCount(129));
161 EXPECT_EQ(10, samples->GetCount(256));
162 EXPECT_EQ(112, samples->TotalCount());
164 // Publish a second round of counts;
165 (*peer_.counts())[1] = 32;
166 (*peer_.counts())[128] = 5;
167 peer_.set_total_counts(37);
169 peer_.PublishCounts();
171 // Verify they've been aggregated into the previous counts.
172 samples = base::StatisticsRecorder::FindHistogram(kHistogramName)
173 ->SnapshotSamples();
175 EXPECT_EQ(0, samples->GetCount(0));
176 EXPECT_EQ(1, samples->GetCount(1));
177 EXPECT_EQ(32, samples->GetCount(2));
178 EXPECT_EQ(106, samples->GetCount(129));
179 EXPECT_EQ(10, samples->GetCount(256));
180 EXPECT_EQ(149, samples->TotalCount());
183 TEST_F(HpackHuffmanAggregatorTest, CreateSpdyResponseHeaders) {
184 char kRawHeaders[] =
185 "HTTP/1.1 202 Accepted \0"
186 "Content-TYPE : text/html; charset=utf-8 \0"
187 "Set-Cookie: foo=bar \0"
188 "Set-Cookie: baz=bing \0"
189 "Cache-Control: pragma=no-cache \0"
190 "Cache-CONTROL: expires=12345 \0\0";
192 scoped_refptr<HttpResponseHeaders> parsed_headers(new HttpResponseHeaders(
193 std::string(kRawHeaders, arraysize(kRawHeaders) - 1)));
195 SpdyHeaderBlock headers;
196 peer_.CreateSpdyHeadersFromHttpResponse(*parsed_headers, &headers);
197 EXPECT_THAT(headers, ElementsAre(
198 Pair(":status", "202"),
199 Pair("cache-control", std::string("pragma=no-cache\0expires=12345", 29)),
200 Pair("content-type", "text/html; charset=utf-8"),
201 Pair("set-cookie", std::string("foo=bar\0baz=bing", 16))));
204 } // namespace net