1 // Copyright (c) 2012 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.
5 #include "net/http/http_server_properties_impl.h"
10 #include "base/basictypes.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/values.h"
15 #include "net/base/host_port_pair.h"
16 #include "net/base/ip_address_number.h"
17 #include "testing/gtest/include/gtest/gtest.h"
25 const int kMaxSupportsSpdyServerHosts
= 500;
27 class HttpServerPropertiesImplPeer
{
29 static void AddBrokenAlternativeServiceWithExpirationTime(
30 HttpServerPropertiesImpl
& impl
,
31 AlternativeService alternative_service
,
32 base::TimeTicks when
) {
33 impl
.broken_alternative_services_
.insert(
34 std::make_pair(alternative_service
, when
));
35 ++impl
.recently_broken_alternative_services_
[alternative_service
];
38 static void ExpireBrokenAlternateProtocolMappings(
39 HttpServerPropertiesImpl
& impl
) {
40 impl
.ExpireBrokenAlternateProtocolMappings();
44 void PrintTo(const AlternativeService
& alternative_service
, std::ostream
* os
) {
45 *os
<< alternative_service
.ToString();
50 class HttpServerPropertiesImplTest
: public testing::Test
{
52 bool HasAlternativeService(const HostPortPair
& origin
) {
53 const AlternativeService alternative_service
=
54 impl_
.GetAlternativeService(origin
);
55 return alternative_service
.protocol
!= UNINITIALIZED_ALTERNATE_PROTOCOL
;
58 HttpServerPropertiesImpl impl_
;
61 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest
;
63 TEST_F(SpdyServerPropertiesTest
, Initialize
) {
64 HostPortPair
spdy_server_google("www.google.com", 443);
65 std::string spdy_server_g
= spdy_server_google
.ToString();
67 HostPortPair
spdy_server_docs("docs.google.com", 443);
68 std::string spdy_server_d
= spdy_server_docs
.ToString();
70 // Check by initializing NULL spdy servers.
71 impl_
.InitializeSpdyServers(NULL
, true);
72 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
74 // Check by initializing empty spdy servers.
75 std::vector
<std::string
> spdy_servers
;
76 impl_
.InitializeSpdyServers(&spdy_servers
, true);
77 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
79 // Check by initializing with www.google.com:443 spdy server.
80 std::vector
<std::string
> spdy_servers1
;
81 spdy_servers1
.push_back(spdy_server_g
);
82 impl_
.InitializeSpdyServers(&spdy_servers1
, true);
83 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
85 // Check by initializing with www.google.com:443 and docs.google.com:443 spdy
87 std::vector
<std::string
> spdy_servers2
;
88 spdy_servers2
.push_back(spdy_server_g
);
89 spdy_servers2
.push_back(spdy_server_d
);
90 impl_
.InitializeSpdyServers(&spdy_servers2
, true);
92 // Verify spdy_server_g and spdy_server_d are in the list in the same order.
93 base::ListValue spdy_server_list
;
94 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
95 EXPECT_EQ(2U, spdy_server_list
.GetSize());
96 std::string string_value_g
;
97 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
98 ASSERT_EQ(spdy_server_g
, string_value_g
);
99 std::string string_value_d
;
100 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_d
));
101 ASSERT_EQ(spdy_server_d
, string_value_d
);
102 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
103 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
106 TEST_F(SpdyServerPropertiesTest
, SupportsRequestPriorityTest
) {
107 HostPortPair
spdy_server_empty(std::string(), 443);
108 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_empty
));
110 // Add www.google.com:443 as supporting SPDY.
111 HostPortPair
spdy_server_google("www.google.com", 443);
112 impl_
.SetSupportsSpdy(spdy_server_google
, true);
113 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
115 // Add mail.google.com:443 as not supporting SPDY.
116 HostPortPair
spdy_server_mail("mail.google.com", 443);
117 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
119 // Add docs.google.com:443 as supporting SPDY.
120 HostPortPair
spdy_server_docs("docs.google.com", 443);
121 impl_
.SetSupportsSpdy(spdy_server_docs
, true);
122 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
124 // Add www.youtube.com:443 as supporting QUIC.
125 HostPortPair
quic_server_youtube("www.youtube.com", 443);
126 const AlternativeService
alternative_service(QUIC
, "www.youtube.com", 443);
127 impl_
.SetAlternativeService(quic_server_youtube
, alternative_service
, 1.0);
128 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_youtube
));
130 // Verify all the entries are the same after additions.
131 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
132 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
133 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
134 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_youtube
));
137 TEST_F(SpdyServerPropertiesTest
, Clear
) {
138 // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
139 HostPortPair
spdy_server_google("www.google.com", 443);
140 impl_
.SetSupportsSpdy(spdy_server_google
, true);
141 HostPortPair
spdy_server_mail("mail.google.com", 443);
142 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
144 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
145 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_mail
));
148 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
149 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
152 TEST_F(SpdyServerPropertiesTest
, GetSpdyServerList
) {
153 base::ListValue spdy_server_list
;
155 // Check there are no spdy_servers.
156 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
157 EXPECT_EQ(0U, spdy_server_list
.GetSize());
159 // Check empty server is not added.
160 HostPortPair
spdy_server_empty(std::string(), 443);
161 impl_
.SetSupportsSpdy(spdy_server_empty
, true);
162 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
163 EXPECT_EQ(0U, spdy_server_list
.GetSize());
165 std::string string_value_g
;
166 std::string string_value_m
;
167 HostPortPair
spdy_server_google("www.google.com", 443);
168 std::string spdy_server_g
= spdy_server_google
.ToString();
169 HostPortPair
spdy_server_mail("mail.google.com", 443);
170 std::string spdy_server_m
= spdy_server_mail
.ToString();
172 // Add www.google.com:443 as not supporting SPDY.
173 impl_
.SetSupportsSpdy(spdy_server_google
, false);
174 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
175 EXPECT_EQ(0U, spdy_server_list
.GetSize());
177 // Add www.google.com:443 as supporting SPDY.
178 impl_
.SetSupportsSpdy(spdy_server_google
, true);
179 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
180 ASSERT_EQ(1U, spdy_server_list
.GetSize());
181 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
182 ASSERT_EQ(spdy_server_g
, string_value_g
);
184 // Add mail.google.com:443 as not supporting SPDY.
185 impl_
.SetSupportsSpdy(spdy_server_mail
, false);
186 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
187 ASSERT_EQ(1U, spdy_server_list
.GetSize());
188 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
189 ASSERT_EQ(spdy_server_g
, string_value_g
);
191 // Add mail.google.com:443 as supporting SPDY.
192 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
193 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
194 ASSERT_EQ(2U, spdy_server_list
.GetSize());
196 // Verify www.google.com:443 and mail.google.com:443 are in the list.
197 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
198 ASSERT_EQ(spdy_server_m
, string_value_m
);
199 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_g
));
200 ASSERT_EQ(spdy_server_g
, string_value_g
);
202 // Request for only one server and verify that we get only one server.
203 impl_
.GetSpdyServerList(&spdy_server_list
, 1);
204 ASSERT_EQ(1U, spdy_server_list
.GetSize());
205 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
206 ASSERT_EQ(spdy_server_m
, string_value_m
);
209 TEST_F(SpdyServerPropertiesTest
, MRUOfGetSpdyServerList
) {
210 base::ListValue spdy_server_list
;
212 std::string string_value_g
;
213 std::string string_value_m
;
214 HostPortPair
spdy_server_google("www.google.com", 443);
215 std::string spdy_server_g
= spdy_server_google
.ToString();
216 HostPortPair
spdy_server_mail("mail.google.com", 443);
217 std::string spdy_server_m
= spdy_server_mail
.ToString();
219 // Add www.google.com:443 as supporting SPDY.
220 impl_
.SetSupportsSpdy(spdy_server_google
, true);
221 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
222 ASSERT_EQ(1U, spdy_server_list
.GetSize());
223 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
224 ASSERT_EQ(spdy_server_g
, string_value_g
);
226 // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
227 // www.google.com:443 are in the list.
228 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
229 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
230 ASSERT_EQ(2U, spdy_server_list
.GetSize());
231 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
232 ASSERT_EQ(spdy_server_m
, string_value_m
);
233 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_g
));
234 ASSERT_EQ(spdy_server_g
, string_value_g
);
236 // Get www.google.com:443 should reorder SpdyServerHostPortMap. Verify that it
237 // is www.google.com:443 is the MRU server.
238 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
239 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
240 ASSERT_EQ(2U, spdy_server_list
.GetSize());
241 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
242 ASSERT_EQ(spdy_server_g
, string_value_g
);
243 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_m
));
244 ASSERT_EQ(spdy_server_m
, string_value_m
);
247 typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest
;
249 TEST_F(AlternateProtocolServerPropertiesTest
, Basic
) {
250 HostPortPair
test_host_port_pair("foo", 80);
251 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
253 AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
254 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service
, 1.0);
255 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
256 alternative_service
= impl_
.GetAlternativeService(test_host_port_pair
);
257 EXPECT_EQ(443, alternative_service
.port
);
258 EXPECT_EQ(NPN_SPDY_4
, alternative_service
.protocol
);
261 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
264 TEST_F(AlternateProtocolServerPropertiesTest
, DefaultProbabilityExcluded
) {
265 HostPortPair
test_host_port_pair("foo", 80);
266 const AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
267 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service
, 0.99);
269 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
272 TEST_F(AlternateProtocolServerPropertiesTest
, Probability
) {
273 impl_
.SetAlternativeServiceProbabilityThreshold(0.25);
275 HostPortPair
test_host_port_pair("foo", 80);
276 const AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
277 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service
, 0.5);
278 EXPECT_TRUE(HasAlternativeService(test_host_port_pair
));
280 AlternativeServiceMap::const_iterator it
=
281 impl_
.alternative_service_map().Peek(test_host_port_pair
);
282 ASSERT_TRUE(it
!= impl_
.alternative_service_map().end());
283 EXPECT_EQ(443, it
->second
.alternative_service
.port
);
284 EXPECT_EQ(NPN_SPDY_4
, it
->second
.alternative_service
.protocol
);
285 EXPECT_EQ(0.5, it
->second
.probability
);
288 TEST_F(AlternateProtocolServerPropertiesTest
, ProbabilityExcluded
) {
289 impl_
.SetAlternativeServiceProbabilityThreshold(0.75);
291 HostPortPair
test_host_port_pair("foo", 80);
292 const AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
293 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service
, 0.5);
294 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
297 TEST_F(AlternateProtocolServerPropertiesTest
, Initialize
) {
298 HostPortPair
test_host_port_pair1("foo1", 80);
299 const AlternativeService
alternative_service1(NPN_SPDY_4
, "foo1", 443);
300 impl_
.SetAlternativeService(test_host_port_pair1
, alternative_service1
, 1.0);
301 impl_
.MarkAlternativeServiceBroken(alternative_service1
);
303 HostPortPair
test_host_port_pair2("foo2", 80);
304 const AlternativeService
alternative_service2(NPN_SPDY_4
, "foo2", 443);
305 impl_
.SetAlternativeService(test_host_port_pair2
, alternative_service2
, 1.0);
307 AlternativeServiceMap
alternative_service_map(
308 AlternativeServiceMap::NO_AUTO_EVICT
);
309 AlternativeServiceInfo
alternative_service_info(NPN_SPDY_4
, "bar", 123, 1.0);
310 alternative_service_map
.Put(test_host_port_pair2
, alternative_service_info
);
311 HostPortPair
test_host_port_pair3("foo3", 80);
312 alternative_service_info
.alternative_service
.port
= 1234;
313 alternative_service_map
.Put(test_host_port_pair3
, alternative_service_info
);
314 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
316 // Verify test_host_port_pair3 is the MRU server.
317 const AlternativeServiceMap
& map
= impl_
.alternative_service_map();
318 AlternativeServiceMap::const_iterator it
= map
.begin();
319 ASSERT_TRUE(it
!= map
.end());
320 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair3
));
321 EXPECT_EQ(NPN_SPDY_4
, it
->second
.alternative_service
.protocol
);
322 EXPECT_EQ(1234, it
->second
.alternative_service
.port
);
324 ASSERT_TRUE(HasAlternativeService(test_host_port_pair1
));
325 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service1
));
326 const AlternativeService alternative_service
=
327 impl_
.GetAlternativeService(test_host_port_pair2
);
328 EXPECT_EQ(NPN_SPDY_4
, alternative_service
.protocol
);
329 EXPECT_EQ(123, alternative_service
.port
);
332 // Regression test for https://crbug.com/504032:
333 // InitializeAlternativeServiceServers() should not crash if there is an empty
334 // hostname is the mapping.
335 TEST_F(AlternateProtocolServerPropertiesTest
, InitializeWithEmptyHostname
) {
336 const HostPortPair
host_port_pair("foo", 443);
337 const AlternativeService
alternative_service_with_empty_hostname(NPN_SPDY_4
,
339 const AlternativeService
alternative_service_with_foo_hostname(NPN_SPDY_4
,
341 impl_
.SetAlternativeService(host_port_pair
,
342 alternative_service_with_empty_hostname
, 1.0);
343 impl_
.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname
);
345 AlternativeServiceMap
alternative_service_map(
346 AlternativeServiceMap::NO_AUTO_EVICT
);
347 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
350 impl_
.IsAlternativeServiceBroken(alternative_service_with_foo_hostname
));
351 EXPECT_TRUE(impl_
.GetAlternativeService(host_port_pair
) ==
352 alternative_service_with_foo_hostname
);
355 TEST_F(AlternateProtocolServerPropertiesTest
, MRUOfGetAlternateProtocol
) {
356 HostPortPair
test_host_port_pair1("foo1", 80);
357 const AlternativeService
alternative_service1(NPN_SPDY_4
, "foo1", 443);
358 impl_
.SetAlternativeService(test_host_port_pair1
, alternative_service1
, 1.0);
359 HostPortPair
test_host_port_pair2("foo2", 80);
360 const AlternativeService
alternative_service2(NPN_SPDY_4
, "foo2", 1234);
361 impl_
.SetAlternativeService(test_host_port_pair2
, alternative_service2
, 1.0);
363 const AlternativeServiceMap
& map
= impl_
.alternative_service_map();
364 AlternativeServiceMap::const_iterator it
= map
.begin();
365 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair2
));
366 EXPECT_EQ(NPN_SPDY_4
, it
->second
.alternative_service
.protocol
);
367 EXPECT_EQ(1234, it
->second
.alternative_service
.port
);
369 // GetAlternativeService should reorder the AlternateProtocol map.
370 const AlternativeService alternative_service
=
371 impl_
.GetAlternativeService(test_host_port_pair1
);
372 EXPECT_EQ(443, alternative_service
.port
);
373 EXPECT_EQ(NPN_SPDY_4
, alternative_service
.protocol
);
375 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair1
));
376 EXPECT_EQ(NPN_SPDY_4
, it
->second
.alternative_service
.protocol
);
377 EXPECT_EQ(443, it
->second
.alternative_service
.port
);
380 TEST_F(AlternateProtocolServerPropertiesTest
, SetBroken
) {
381 HostPortPair
test_host_port_pair("foo", 80);
382 const AlternativeService
alternative_service1(NPN_SPDY_4
, "foo", 443);
383 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service1
, 1.0);
384 impl_
.MarkAlternativeServiceBroken(alternative_service1
);
385 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
386 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service1
));
388 const AlternativeService
alternative_service2(NPN_SPDY_4
, "foo", 1234);
389 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service2
, 1.0);
390 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service1
));
391 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service2
));
392 EXPECT_EQ(1234, impl_
.GetAlternativeService(test_host_port_pair
).port
);
395 // A broken alternative service in the mapping carries meaningful information,
396 // therefore it should not be ignored by SetAlternativeService(). In
397 // particular, an alternative service mapped to an origin shadows alternative
398 // services of canonical hosts.
399 TEST_F(AlternateProtocolServerPropertiesTest
, BrokenShadowsCanonical
) {
400 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
401 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
402 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
403 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
404 EXPECT_TRUE(impl_
.GetAlternativeService(test_host_port_pair
) ==
407 const AlternativeService
broken_alternative_service(NPN_SPDY_4
, "foo", 443);
408 impl_
.MarkAlternativeServiceBroken(broken_alternative_service
);
409 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(broken_alternative_service
));
411 impl_
.SetAlternativeService(test_host_port_pair
, broken_alternative_service
,
413 ASSERT_EQ(broken_alternative_service
,
414 impl_
.GetAlternativeService(test_host_port_pair
));
415 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(broken_alternative_service
));
418 TEST_F(AlternateProtocolServerPropertiesTest
, ClearBroken
) {
419 HostPortPair
test_host_port_pair("foo", 80);
420 const AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
421 impl_
.SetAlternativeService(test_host_port_pair
, alternative_service
, 1.0);
422 impl_
.MarkAlternativeServiceBroken(alternative_service
);
423 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
424 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
425 impl_
.ClearAlternativeService(test_host_port_pair
);
426 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
429 TEST_F(AlternateProtocolServerPropertiesTest
, MarkRecentlyBroken
) {
430 HostPortPair
host_port_pair("foo", 80);
431 const AlternativeService
alternative_service(NPN_SPDY_4
, "foo", 443);
432 impl_
.SetAlternativeService(host_port_pair
, alternative_service
, 1.0);
434 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
435 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
437 impl_
.MarkAlternativeServiceRecentlyBroken(alternative_service
);
438 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
439 EXPECT_TRUE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
441 impl_
.ConfirmAlternativeService(alternative_service
);
442 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
443 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
446 TEST_F(AlternateProtocolServerPropertiesTest
, Canonical
) {
447 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
448 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
450 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
451 EXPECT_FALSE(HasAlternativeService(canonical_port_pair
));
453 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
454 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
455 // Verify the forced protocol.
456 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
457 const AlternativeService alternative_service
=
458 impl_
.GetAlternativeService(test_host_port_pair
);
459 EXPECT_EQ(canonical_altsvc
.port
, alternative_service
.port
);
460 EXPECT_EQ(canonical_altsvc
.protocol
, alternative_service
.protocol
);
462 // Verify the canonical suffix.
463 EXPECT_EQ(".c.youtube.com",
464 impl_
.GetCanonicalSuffix(test_host_port_pair
.host()));
465 EXPECT_EQ(".c.youtube.com",
466 impl_
.GetCanonicalSuffix(canonical_port_pair
.host()));
469 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalDefaultHost
) {
470 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
471 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
473 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
474 EXPECT_FALSE(HasAlternativeService(canonical_port_pair
));
476 AlternativeService
canonical_altsvc(QUIC
, "", 1234);
477 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
478 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
479 const AlternativeService alternative_service
=
480 impl_
.GetAlternativeService(test_host_port_pair
);
481 EXPECT_EQ(canonical_altsvc
.protocol
, alternative_service
.protocol
);
482 EXPECT_EQ(test_host_port_pair
.host(), alternative_service
.host
);
483 EXPECT_EQ(canonical_altsvc
.port
, alternative_service
.port
);
486 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalBelowThreshold
) {
487 impl_
.SetAlternativeServiceProbabilityThreshold(0.02);
489 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
490 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
491 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
493 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 0.01);
494 EXPECT_FALSE(HasAlternativeService(canonical_port_pair
));
495 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
498 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalAboveThreshold
) {
499 impl_
.SetAlternativeServiceProbabilityThreshold(0.02);
501 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
502 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
503 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
505 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 0.03);
506 EXPECT_TRUE(HasAlternativeService(canonical_port_pair
));
507 EXPECT_TRUE(HasAlternativeService(test_host_port_pair
));
510 TEST_F(AlternateProtocolServerPropertiesTest
, ClearCanonical
) {
511 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
512 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
513 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
515 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
516 impl_
.ClearAlternativeService(canonical_port_pair
);
517 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
520 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalBroken
) {
521 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
522 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
523 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
525 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
526 impl_
.MarkAlternativeServiceBroken(canonical_altsvc
);
527 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
530 // Adding an alternative service for a new host overrides canonical host.
531 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalOverride
) {
532 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
533 HostPortPair
bar_host_port_pair("bar.c.youtube.com", 80);
534 AlternativeService
bar_alternative_service(QUIC
, "bar.c.youtube.com", 1234);
535 impl_
.SetAlternativeService(bar_host_port_pair
, bar_alternative_service
, 1.0);
536 AlternativeService altsvc
= impl_
.GetAlternativeService(test_host_port_pair
);
537 EXPECT_EQ(1234, altsvc
.port
);
539 HostPortPair
qux_host_port_pair("qux.c.youtube.com", 80);
540 AlternativeService
qux_alternative_service(QUIC
, "qux.c.youtube.com", 443);
541 impl_
.SetAlternativeService(qux_host_port_pair
, qux_alternative_service
, 1.0);
542 altsvc
= impl_
.GetAlternativeService(test_host_port_pair
);
543 EXPECT_EQ(443, altsvc
.port
);
546 TEST_F(AlternateProtocolServerPropertiesTest
, ClearWithCanonical
) {
547 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
548 HostPortPair
canonical_port_pair("bar.c.youtube.com", 80);
549 AlternativeService
canonical_altsvc(QUIC
, "bar.c.youtube.com", 1234);
551 impl_
.SetAlternativeService(canonical_port_pair
, canonical_altsvc
, 1.0);
553 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
556 TEST_F(AlternateProtocolServerPropertiesTest
,
557 ExpireBrokenAlternateProtocolMappings
) {
558 HostPortPair
host_port_pair("foo", 443);
559 AlternativeService
alternative_service(QUIC
, "foo", 443);
560 impl_
.SetAlternativeService(host_port_pair
, alternative_service
, 1.0);
561 EXPECT_TRUE(HasAlternativeService(host_port_pair
));
562 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
563 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
565 base::TimeTicks past
=
566 base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42);
567 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime(
568 impl_
, alternative_service
, past
);
569 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
570 EXPECT_TRUE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
572 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(impl_
);
573 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
574 // TODO(bnc): Test WasAlternativeServiceRecentlyBroken once it's changed to
575 // take AlternativeService as argument.
578 typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest
;
580 TEST_F(SpdySettingsServerPropertiesTest
, Initialize
) {
581 HostPortPair
spdy_server_google("www.google.com", 443);
583 // Check by initializing empty spdy settings.
584 SpdySettingsMap
spdy_settings_map(SpdySettingsMap::NO_AUTO_EVICT
);
585 impl_
.InitializeSpdySettingsServers(&spdy_settings_map
);
586 EXPECT_TRUE(impl_
.GetSpdySettings(spdy_server_google
).empty());
588 // Check by initializing with www.google.com:443 spdy server settings.
589 SettingsMap settings_map
;
590 const SpdySettingsIds id
= SETTINGS_UPLOAD_BANDWIDTH
;
591 const SpdySettingsFlags flags
= SETTINGS_FLAG_PERSISTED
;
592 const uint32 value
= 31337;
593 SettingsFlagsAndValue
flags_and_value(flags
, value
);
594 settings_map
[id
] = flags_and_value
;
595 spdy_settings_map
.Put(spdy_server_google
, settings_map
);
596 impl_
.InitializeSpdySettingsServers(&spdy_settings_map
);
598 const SettingsMap
& settings_map2
= impl_
.GetSpdySettings(spdy_server_google
);
599 ASSERT_EQ(1U, settings_map2
.size());
600 SettingsMap::const_iterator it
= settings_map2
.find(id
);
601 EXPECT_TRUE(it
!= settings_map2
.end());
602 SettingsFlagsAndValue flags_and_value2
= it
->second
;
603 EXPECT_EQ(flags
, flags_and_value2
.first
);
604 EXPECT_EQ(value
, flags_and_value2
.second
);
607 TEST_F(SpdySettingsServerPropertiesTest
, SetSpdySetting
) {
608 HostPortPair
spdy_server_empty(std::string(), 443);
609 const SettingsMap
& settings_map0
= impl_
.GetSpdySettings(spdy_server_empty
);
610 EXPECT_EQ(0U, settings_map0
.size()); // Returns kEmptySettingsMap.
612 // Add www.google.com:443 as persisting.
613 HostPortPair
spdy_server_google("www.google.com", 443);
614 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
615 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
616 const uint32 value1
= 31337;
617 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
619 const SettingsMap
& settings_map1_ret
=
620 impl_
.GetSpdySettings(spdy_server_google
);
621 ASSERT_EQ(1U, settings_map1_ret
.size());
622 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
623 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
624 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
625 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
626 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
628 // Add mail.google.com:443 as not persisting.
629 HostPortPair
spdy_server_mail("mail.google.com", 443);
630 const SpdySettingsIds id2
= SETTINGS_DOWNLOAD_BANDWIDTH
;
631 const SpdySettingsFlags flags2
= SETTINGS_FLAG_NONE
;
632 const uint32 value2
= 62667;
633 EXPECT_FALSE(impl_
.SetSpdySetting(spdy_server_mail
, id2
, flags2
, value2
));
634 const SettingsMap
& settings_map2_ret
=
635 impl_
.GetSpdySettings(spdy_server_mail
);
636 EXPECT_EQ(0U, settings_map2_ret
.size()); // Returns kEmptySettingsMap.
638 // Add docs.google.com:443 as persisting
639 HostPortPair
spdy_server_docs("docs.google.com", 443);
640 const SpdySettingsIds id3
= SETTINGS_ROUND_TRIP_TIME
;
641 const SpdySettingsFlags flags3
= SETTINGS_FLAG_PLEASE_PERSIST
;
642 const uint32 value3
= 93997;
643 SettingsFlagsAndValue
flags_and_value3(flags3
, value3
);
644 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id3
, flags3
, value3
));
646 const SettingsMap
& settings_map3_ret
=
647 impl_
.GetSpdySettings(spdy_server_docs
);
648 ASSERT_EQ(1U, settings_map3_ret
.size());
649 SettingsMap::const_iterator it3_ret
= settings_map3_ret
.find(id3
);
650 EXPECT_TRUE(it3_ret
!= settings_map3_ret
.end());
651 SettingsFlagsAndValue flags_and_value3_ret
= it3_ret
->second
;
652 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value3_ret
.first
);
653 EXPECT_EQ(value3
, flags_and_value3_ret
.second
);
655 // Check data for www.google.com:443 (id1).
656 const SettingsMap
& settings_map4_ret
=
657 impl_
.GetSpdySettings(spdy_server_google
);
658 ASSERT_EQ(1U, settings_map4_ret
.size());
659 SettingsMap::const_iterator it4_ret
= settings_map4_ret
.find(id1
);
660 EXPECT_TRUE(it4_ret
!= settings_map4_ret
.end());
661 SettingsFlagsAndValue flags_and_value4_ret
= it4_ret
->second
;
662 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value4_ret
.first
);
663 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
665 // Clear www.google.com:443 as persisting.
666 impl_
.ClearSpdySettings(spdy_server_google
);
668 const SettingsMap
& settings_map5_ret
=
669 impl_
.GetSpdySettings(spdy_server_google
);
670 ASSERT_EQ(0U, settings_map5_ret
.size());
672 // Clear all settings.
673 ASSERT_GT(impl_
.spdy_settings_map().size(), 0U);
674 impl_
.ClearAllSpdySettings();
675 ASSERT_EQ(0U, impl_
.spdy_settings_map().size());
678 TEST_F(SpdySettingsServerPropertiesTest
, Clear
) {
679 // Add www.google.com:443 as persisting.
680 HostPortPair
spdy_server_google("www.google.com", 443);
681 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
682 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
683 const uint32 value1
= 31337;
684 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
686 const SettingsMap
& settings_map1_ret
=
687 impl_
.GetSpdySettings(spdy_server_google
);
688 ASSERT_EQ(1U, settings_map1_ret
.size());
689 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
690 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
691 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
692 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
693 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
695 // Add docs.google.com:443 as persisting
696 HostPortPair
spdy_server_docs("docs.google.com", 443);
697 const SpdySettingsIds id3
= SETTINGS_ROUND_TRIP_TIME
;
698 const SpdySettingsFlags flags3
= SETTINGS_FLAG_PLEASE_PERSIST
;
699 const uint32 value3
= 93997;
700 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id3
, flags3
, value3
));
702 const SettingsMap
& settings_map3_ret
=
703 impl_
.GetSpdySettings(spdy_server_docs
);
704 ASSERT_EQ(1U, settings_map3_ret
.size());
705 SettingsMap::const_iterator it3_ret
= settings_map3_ret
.find(id3
);
706 EXPECT_TRUE(it3_ret
!= settings_map3_ret
.end());
707 SettingsFlagsAndValue flags_and_value3_ret
= it3_ret
->second
;
708 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value3_ret
.first
);
709 EXPECT_EQ(value3
, flags_and_value3_ret
.second
);
712 EXPECT_EQ(0U, impl_
.GetSpdySettings(spdy_server_google
).size());
713 EXPECT_EQ(0U, impl_
.GetSpdySettings(spdy_server_docs
).size());
716 TEST_F(SpdySettingsServerPropertiesTest
, MRUOfGetSpdySettings
) {
717 // Add www.google.com:443 as persisting.
718 HostPortPair
spdy_server_google("www.google.com", 443);
719 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
720 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
721 const uint32 value1
= 31337;
722 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
724 // Add docs.google.com:443 as persisting
725 HostPortPair
spdy_server_docs("docs.google.com", 443);
726 const SpdySettingsIds id2
= SETTINGS_ROUND_TRIP_TIME
;
727 const SpdySettingsFlags flags2
= SETTINGS_FLAG_PLEASE_PERSIST
;
728 const uint32 value2
= 93997;
729 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id2
, flags2
, value2
));
731 // Verify the first element is docs.google.com:443.
732 const SpdySettingsMap
& map
= impl_
.spdy_settings_map();
733 SpdySettingsMap::const_iterator it
= map
.begin();
734 EXPECT_TRUE(it
->first
.Equals(spdy_server_docs
));
735 const SettingsMap
& settings_map2_ret
= it
->second
;
736 ASSERT_EQ(1U, settings_map2_ret
.size());
737 SettingsMap::const_iterator it2_ret
= settings_map2_ret
.find(id2
);
738 EXPECT_TRUE(it2_ret
!= settings_map2_ret
.end());
739 SettingsFlagsAndValue flags_and_value2_ret
= it2_ret
->second
;
740 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value2_ret
.first
);
741 EXPECT_EQ(value2
, flags_and_value2_ret
.second
);
743 // GetSpdySettings should reorder the SpdySettingsMap.
744 const SettingsMap
& settings_map1_ret
=
745 impl_
.GetSpdySettings(spdy_server_google
);
746 ASSERT_EQ(1U, settings_map1_ret
.size());
747 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
748 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
749 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
750 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
751 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
753 // Check the first entry is spdy_server_google by accessing it via iterator.
755 EXPECT_TRUE(it
->first
.Equals(spdy_server_google
));
756 const SettingsMap
& settings_map1_it_ret
= it
->second
;
757 ASSERT_EQ(1U, settings_map1_it_ret
.size());
758 it1_ret
= settings_map1_it_ret
.find(id1
);
759 EXPECT_TRUE(it1_ret
!= settings_map1_it_ret
.end());
760 flags_and_value1_ret
= it1_ret
->second
;
761 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
762 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
765 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest
;
767 TEST_F(SupportsQuicServerPropertiesTest
, Initialize
) {
768 HostPortPair
quic_server_google("www.google.com", 443);
770 // Check by initializing empty address.
771 IPAddressNumber initial_address
;
772 impl_
.InitializeSupportsQuic(&initial_address
);
774 IPAddressNumber address
;
775 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
776 EXPECT_TRUE(address
.empty());
778 // Check by initializing with a valid address.
779 CHECK(ParseIPLiteralToNumber("127.0.0.1", &initial_address
));
780 impl_
.InitializeSupportsQuic(&initial_address
);
782 EXPECT_TRUE(impl_
.GetSupportsQuic(&address
));
783 EXPECT_EQ(initial_address
, address
);
786 TEST_F(SupportsQuicServerPropertiesTest
, SetSupportsQuic
) {
787 IPAddressNumber address
;
788 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
789 EXPECT_TRUE(address
.empty());
791 IPAddressNumber actual_address
;
792 CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address
));
793 impl_
.SetSupportsQuic(true, actual_address
);
795 EXPECT_TRUE(impl_
.GetSupportsQuic(&address
));
796 EXPECT_EQ(actual_address
, address
);
800 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
803 typedef HttpServerPropertiesImplTest ServerNetworkStatsServerPropertiesTest
;
805 TEST_F(ServerNetworkStatsServerPropertiesTest
, Initialize
) {
806 HostPortPair
google_server("www.google.com", 443);
808 // Check by initializing empty ServerNetworkStats.
809 ServerNetworkStatsMap
server_network_stats_map(
810 ServerNetworkStatsMap::NO_AUTO_EVICT
);
811 impl_
.InitializeServerNetworkStats(&server_network_stats_map
);
812 const ServerNetworkStats
* stats
= impl_
.GetServerNetworkStats(google_server
);
813 EXPECT_EQ(NULL
, stats
);
815 // Check by initializing with www.google.com:443.
816 ServerNetworkStats stats1
;
817 stats1
.srtt
= base::TimeDelta::FromMicroseconds(10);
818 stats1
.bandwidth_estimate
= QuicBandwidth::FromBitsPerSecond(100);
819 server_network_stats_map
.Put(google_server
, stats1
);
820 impl_
.InitializeServerNetworkStats(&server_network_stats_map
);
822 const ServerNetworkStats
* stats2
= impl_
.GetServerNetworkStats(google_server
);
823 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
824 EXPECT_EQ(100, stats2
->bandwidth_estimate
.ToBitsPerSecond());
827 TEST_F(ServerNetworkStatsServerPropertiesTest
, SetServerNetworkStats
) {
828 HostPortPair
foo_server("foo", 80);
829 const ServerNetworkStats
* stats
= impl_
.GetServerNetworkStats(foo_server
);
830 EXPECT_EQ(NULL
, stats
);
832 ServerNetworkStats stats1
;
833 stats1
.srtt
= base::TimeDelta::FromMicroseconds(10);
834 stats1
.bandwidth_estimate
= QuicBandwidth::FromBitsPerSecond(100);
835 impl_
.SetServerNetworkStats(foo_server
, stats1
);
837 const ServerNetworkStats
* stats2
= impl_
.GetServerNetworkStats(foo_server
);
838 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
839 EXPECT_EQ(100, stats2
->bandwidth_estimate
.ToBitsPerSecond());
842 const ServerNetworkStats
* stats3
= impl_
.GetServerNetworkStats(foo_server
);
843 EXPECT_EQ(NULL
, stats3
);