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 AlternativeServiceVector alternative_service_vector
=
54 impl_
.GetAlternativeServices(origin
);
55 return !alternative_service_vector
.empty();
58 bool SetAlternativeService(const HostPortPair
& origin
,
59 const AlternativeService
& alternative_service
,
60 double alternative_probability
) {
61 const base::Time expiration
=
62 base::Time::Now() + base::TimeDelta::FromDays(1);
63 return impl_
.SetAlternativeService(origin
, alternative_service
,
64 alternative_probability
, expiration
);
67 HttpServerPropertiesImpl impl_
;
70 typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest
;
72 TEST_F(SpdyServerPropertiesTest
, Initialize
) {
73 HostPortPair
spdy_server_google("www.google.com", 443);
74 std::string spdy_server_g
= spdy_server_google
.ToString();
76 HostPortPair
spdy_server_docs("docs.google.com", 443);
77 std::string spdy_server_d
= spdy_server_docs
.ToString();
79 // Check by initializing NULL spdy servers.
80 impl_
.InitializeSpdyServers(NULL
, true);
81 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
83 // Check by initializing empty spdy servers.
84 std::vector
<std::string
> spdy_servers
;
85 impl_
.InitializeSpdyServers(&spdy_servers
, true);
86 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
88 // Check by initializing with www.google.com:443 spdy server.
89 std::vector
<std::string
> spdy_servers1
;
90 spdy_servers1
.push_back(spdy_server_g
);
91 impl_
.InitializeSpdyServers(&spdy_servers1
, true);
92 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
94 // Check by initializing with www.google.com:443 and docs.google.com:443 spdy
96 std::vector
<std::string
> spdy_servers2
;
97 spdy_servers2
.push_back(spdy_server_g
);
98 spdy_servers2
.push_back(spdy_server_d
);
99 impl_
.InitializeSpdyServers(&spdy_servers2
, true);
101 // Verify spdy_server_g and spdy_server_d are in the list in the same order.
102 base::ListValue spdy_server_list
;
103 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
104 EXPECT_EQ(2U, spdy_server_list
.GetSize());
105 std::string string_value_g
;
106 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
107 ASSERT_EQ(spdy_server_g
, string_value_g
);
108 std::string string_value_d
;
109 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_d
));
110 ASSERT_EQ(spdy_server_d
, string_value_d
);
111 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
112 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
115 TEST_F(SpdyServerPropertiesTest
, SupportsRequestPriorityTest
) {
116 HostPortPair
spdy_server_empty(std::string(), 443);
117 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_empty
));
119 // Add www.google.com:443 as supporting SPDY.
120 HostPortPair
spdy_server_google("www.google.com", 443);
121 impl_
.SetSupportsSpdy(spdy_server_google
, true);
122 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
124 // Add mail.google.com:443 as not supporting SPDY.
125 HostPortPair
spdy_server_mail("mail.google.com", 443);
126 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
128 // Add docs.google.com:443 as supporting SPDY.
129 HostPortPair
spdy_server_docs("docs.google.com", 443);
130 impl_
.SetSupportsSpdy(spdy_server_docs
, true);
131 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
133 // Add www.youtube.com:443 as supporting QUIC.
134 HostPortPair
quic_server_youtube("www.youtube.com", 443);
135 const AlternativeService
alternative_service1(QUIC
, "www.youtube.com", 443);
136 SetAlternativeService(quic_server_youtube
, alternative_service1
, 1.0);
137 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_youtube
));
139 // Add www.example.com:443 with two alternative services, one supporting QUIC.
140 HostPortPair
quic_server_example("www.example.com", 443);
141 const AlternativeService
alternative_service2(NPN_HTTP_2
, "", 443);
142 SetAlternativeService(quic_server_example
, alternative_service2
, 1.0);
143 SetAlternativeService(quic_server_example
, alternative_service1
, 1.0);
144 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_example
));
146 // Verify all the entries are the same after additions.
147 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
148 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
149 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_docs
));
150 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_youtube
));
151 EXPECT_TRUE(impl_
.SupportsRequestPriority(quic_server_example
));
154 TEST_F(SpdyServerPropertiesTest
, Clear
) {
155 // Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
156 HostPortPair
spdy_server_google("www.google.com", 443);
157 impl_
.SetSupportsSpdy(spdy_server_google
, true);
158 HostPortPair
spdy_server_mail("mail.google.com", 443);
159 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
161 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
162 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_mail
));
165 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_google
));
166 EXPECT_FALSE(impl_
.SupportsRequestPriority(spdy_server_mail
));
169 TEST_F(SpdyServerPropertiesTest
, GetSpdyServerList
) {
170 base::ListValue spdy_server_list
;
172 // Check there are no spdy_servers.
173 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
174 EXPECT_EQ(0U, spdy_server_list
.GetSize());
176 // Check empty server is not added.
177 HostPortPair
spdy_server_empty(std::string(), 443);
178 impl_
.SetSupportsSpdy(spdy_server_empty
, true);
179 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
180 EXPECT_EQ(0U, spdy_server_list
.GetSize());
182 std::string string_value_g
;
183 std::string string_value_m
;
184 HostPortPair
spdy_server_google("www.google.com", 443);
185 std::string spdy_server_g
= spdy_server_google
.ToString();
186 HostPortPair
spdy_server_mail("mail.google.com", 443);
187 std::string spdy_server_m
= spdy_server_mail
.ToString();
189 // Add www.google.com:443 as not supporting SPDY.
190 impl_
.SetSupportsSpdy(spdy_server_google
, false);
191 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
192 EXPECT_EQ(0U, spdy_server_list
.GetSize());
194 // Add www.google.com:443 as supporting SPDY.
195 impl_
.SetSupportsSpdy(spdy_server_google
, true);
196 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
197 ASSERT_EQ(1U, spdy_server_list
.GetSize());
198 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
199 ASSERT_EQ(spdy_server_g
, string_value_g
);
201 // Add mail.google.com:443 as not supporting SPDY.
202 impl_
.SetSupportsSpdy(spdy_server_mail
, false);
203 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
204 ASSERT_EQ(1U, spdy_server_list
.GetSize());
205 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
206 ASSERT_EQ(spdy_server_g
, string_value_g
);
208 // Add mail.google.com:443 as supporting SPDY.
209 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
210 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
211 ASSERT_EQ(2U, spdy_server_list
.GetSize());
213 // Verify www.google.com:443 and mail.google.com:443 are in the list.
214 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
215 ASSERT_EQ(spdy_server_m
, string_value_m
);
216 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_g
));
217 ASSERT_EQ(spdy_server_g
, string_value_g
);
219 // Request for only one server and verify that we get only one server.
220 impl_
.GetSpdyServerList(&spdy_server_list
, 1);
221 ASSERT_EQ(1U, spdy_server_list
.GetSize());
222 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
223 ASSERT_EQ(spdy_server_m
, string_value_m
);
226 TEST_F(SpdyServerPropertiesTest
, MRUOfGetSpdyServerList
) {
227 base::ListValue spdy_server_list
;
229 std::string string_value_g
;
230 std::string string_value_m
;
231 HostPortPair
spdy_server_google("www.google.com", 443);
232 std::string spdy_server_g
= spdy_server_google
.ToString();
233 HostPortPair
spdy_server_mail("mail.google.com", 443);
234 std::string spdy_server_m
= spdy_server_mail
.ToString();
236 // Add www.google.com:443 as supporting SPDY.
237 impl_
.SetSupportsSpdy(spdy_server_google
, true);
238 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
239 ASSERT_EQ(1U, spdy_server_list
.GetSize());
240 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
241 ASSERT_EQ(spdy_server_g
, string_value_g
);
243 // Add mail.google.com:443 as supporting SPDY. Verify mail.google.com:443 and
244 // www.google.com:443 are in the list.
245 impl_
.SetSupportsSpdy(spdy_server_mail
, true);
246 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
247 ASSERT_EQ(2U, spdy_server_list
.GetSize());
248 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_m
));
249 ASSERT_EQ(spdy_server_m
, string_value_m
);
250 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_g
));
251 ASSERT_EQ(spdy_server_g
, string_value_g
);
253 // Get www.google.com:443 should reorder SpdyServerHostPortMap. Verify that it
254 // is www.google.com:443 is the MRU server.
255 EXPECT_TRUE(impl_
.SupportsRequestPriority(spdy_server_google
));
256 impl_
.GetSpdyServerList(&spdy_server_list
, kMaxSupportsSpdyServerHosts
);
257 ASSERT_EQ(2U, spdy_server_list
.GetSize());
258 ASSERT_TRUE(spdy_server_list
.GetString(0, &string_value_g
));
259 ASSERT_EQ(spdy_server_g
, string_value_g
);
260 ASSERT_TRUE(spdy_server_list
.GetString(1, &string_value_m
));
261 ASSERT_EQ(spdy_server_m
, string_value_m
);
264 typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest
;
266 TEST_F(AlternateProtocolServerPropertiesTest
, Basic
) {
267 HostPortPair
test_host_port_pair("foo", 80);
268 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
270 AlternativeService
alternative_service(NPN_HTTP_2
, "foo", 443);
271 SetAlternativeService(test_host_port_pair
, alternative_service
, 1.0);
272 const AlternativeServiceVector alternative_service_vector
=
273 impl_
.GetAlternativeServices(test_host_port_pair
);
274 ASSERT_EQ(1u, alternative_service_vector
.size());
275 EXPECT_EQ(alternative_service
, alternative_service_vector
[0]);
278 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
281 TEST_F(AlternateProtocolServerPropertiesTest
, ExcludeOrigin
) {
282 AlternativeServiceInfoVector alternative_service_info_vector
;
283 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
284 // Same hostname, same port, TCP: should be ignored.
285 AlternativeService
alternative_service1(NPN_HTTP_2
, "foo", 443);
286 alternative_service_info_vector
.push_back(
287 AlternativeServiceInfo(alternative_service1
, 1.0, expiration
));
288 // Different hostname: GetAlternativeServices should return this one.
289 AlternativeService
alternative_service2(NPN_HTTP_2
, "bar", 443);
290 alternative_service_info_vector
.push_back(
291 AlternativeServiceInfo(alternative_service2
, 1.0, expiration
));
292 // Different port: GetAlternativeServices should return this one too.
293 AlternativeService
alternative_service3(NPN_HTTP_2
, "foo", 80);
294 alternative_service_info_vector
.push_back(
295 AlternativeServiceInfo(alternative_service3
, 1.0, expiration
));
296 // QUIC: GetAlternativeServices should return this one too.
297 AlternativeService
alternative_service4(QUIC
, "foo", 443);
298 alternative_service_info_vector
.push_back(
299 AlternativeServiceInfo(alternative_service4
, 1.0, expiration
));
301 HostPortPair
test_host_port_pair("foo", 443);
302 impl_
.SetAlternativeServices(test_host_port_pair
,
303 alternative_service_info_vector
);
305 const AlternativeServiceVector alternative_service_vector
=
306 impl_
.GetAlternativeServices(test_host_port_pair
);
307 ASSERT_EQ(3u, alternative_service_vector
.size());
308 EXPECT_EQ(alternative_service2
, alternative_service_vector
[0]);
309 EXPECT_EQ(alternative_service3
, alternative_service_vector
[1]);
310 EXPECT_EQ(alternative_service4
, alternative_service_vector
[2]);
313 TEST_F(AlternateProtocolServerPropertiesTest
, DefaultProbabilityExcluded
) {
314 HostPortPair
test_host_port_pair("foo", 80);
315 const AlternativeService
alternative_service(NPN_HTTP_2
, "foo", 443);
316 SetAlternativeService(test_host_port_pair
, alternative_service
, 0.99);
318 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
321 // GetAlternativeServices and HasAlternativeServices should only return the ones
322 // with probability greater than or equal to the threshold.
323 TEST_F(AlternateProtocolServerPropertiesTest
, Probability
) {
324 impl_
.SetAlternativeServiceProbabilityThreshold(0.5);
326 AlternativeServiceInfoVector alternative_service_info_vector
;
327 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
328 const AlternativeService
alternative_service1(NPN_HTTP_2
, "foo", 443);
329 alternative_service_info_vector
.push_back(
330 AlternativeServiceInfo(alternative_service1
, 0.3, expiration
));
331 const AlternativeService
alternative_service2(QUIC
, "bar", 123);
332 alternative_service_info_vector
.push_back(
333 AlternativeServiceInfo(alternative_service2
, 0.7, expiration
));
334 const AlternativeService
alternative_service3(NPN_SPDY_3_1
, "baz", 443);
335 alternative_service_info_vector
.push_back(
336 AlternativeServiceInfo(alternative_service3
, 0.4, expiration
));
337 const AlternativeService
alternative_service4(NPN_HTTP_2
, "qux", 1234);
338 alternative_service_info_vector
.push_back(
339 AlternativeServiceInfo(alternative_service4
, 0.6, expiration
));
341 HostPortPair
test_host_port_pair("foo", 80);
342 impl_
.SetAlternativeServices(test_host_port_pair
,
343 alternative_service_info_vector
);
345 const AlternativeServiceVector alternative_service_vector
=
346 impl_
.GetAlternativeServices(test_host_port_pair
);
347 ASSERT_EQ(2u, alternative_service_vector
.size());
348 EXPECT_EQ(alternative_service2
, alternative_service_vector
[0]);
349 EXPECT_EQ(alternative_service4
, alternative_service_vector
[1]);
352 TEST_F(AlternateProtocolServerPropertiesTest
, ProbabilityExcluded
) {
353 impl_
.SetAlternativeServiceProbabilityThreshold(0.75);
355 HostPortPair
test_host_port_pair("foo", 80);
356 const AlternativeService
alternative_service(NPN_HTTP_2
, "foo", 443);
357 SetAlternativeService(test_host_port_pair
, alternative_service
, 0.5);
358 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
361 TEST_F(AlternateProtocolServerPropertiesTest
, Initialize
) {
362 // |test_host_port_pair1| has one alternative service, which is non-broken,
363 // and thus will be removed by InitializeAlternativeServiceServers().
364 HostPortPair
test_host_port_pair1("foo1", 80);
365 const AlternativeService
alternative_service1(NPN_HTTP_2
, "bar1", 443);
366 const base::Time now
= base::Time::Now();
367 base::Time expiration1
= now
+ base::TimeDelta::FromDays(1);
368 impl_
.SetAlternativeService(test_host_port_pair1
, alternative_service1
, 1.0,
371 // |test_host_port_pair2| has two alternative services. The broken one will
372 // remain, the non-broken one will be removed by
373 // InitializeAlternativeServiceServers().
374 AlternativeServiceInfoVector alternative_service_info_vector
;
375 const AlternativeService
alternative_service2(NPN_SPDY_3_1
, "bar2", 443);
376 base::Time expiration2
= now
+ base::TimeDelta::FromDays(2);
377 alternative_service_info_vector
.push_back(
378 AlternativeServiceInfo(alternative_service2
, 1.0, expiration2
));
379 const AlternativeService
alternative_service3(NPN_SPDY_3_1
, "bar3", 1234);
380 base::Time expiration3
= now
+ base::TimeDelta::FromDays(3);
381 alternative_service_info_vector
.push_back(
382 AlternativeServiceInfo(alternative_service3
, 0.8, expiration3
));
383 HostPortPair
test_host_port_pair2("foo2", 80);
384 impl_
.SetAlternativeServices(test_host_port_pair2
,
385 alternative_service_info_vector
);
386 impl_
.MarkAlternativeServiceBroken(alternative_service2
);
388 // Prepare |alternative_service_map| to be loaded by
389 // InitializeAlternativeServiceServers().
390 AlternativeServiceMap
alternative_service_map(
391 AlternativeServiceMap::NO_AUTO_EVICT
);
392 const AlternativeService
alternative_service4(NPN_HTTP_2
, "bar4", 123);
393 base::Time expiration4
= now
+ base::TimeDelta::FromDays(4);
394 const AlternativeServiceInfo
alternative_service_info1(alternative_service4
,
396 alternative_service_map
.Put(
397 test_host_port_pair2
,
398 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info1
));
400 HostPortPair
test_host_port_pair3("foo3", 80);
401 const AlternativeService
alternative_service5(NPN_HTTP_2
, "bar5", 1234);
402 base::Time expiration5
= now
+ base::TimeDelta::FromDays(5);
403 const AlternativeServiceInfo
alternative_service_info2(alternative_service5
,
405 alternative_service_map
.Put(
406 test_host_port_pair3
,
407 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info2
));
409 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
411 // Verify alternative_service_map.
412 const AlternativeServiceMap
& map
= impl_
.alternative_service_map();
413 ASSERT_EQ(2u, map
.size());
414 AlternativeServiceMap::const_iterator map_it
= map
.begin();
415 EXPECT_TRUE(map_it
->first
.Equals(test_host_port_pair3
));
416 ASSERT_EQ(1u, map_it
->second
.size());
417 EXPECT_EQ(alternative_service5
, map_it
->second
[0].alternative_service
);
418 EXPECT_EQ(0.2, map_it
->second
[0].probability
);
419 EXPECT_EQ(expiration5
, map_it
->second
[0].expiration
);
421 EXPECT_TRUE(map_it
->first
.Equals(test_host_port_pair2
));
422 ASSERT_EQ(2u, map_it
->second
.size());
423 EXPECT_EQ(alternative_service2
, map_it
->second
[0].alternative_service
);
424 EXPECT_EQ(1.0, map_it
->second
[0].probability
);
425 EXPECT_EQ(expiration2
, map_it
->second
[0].expiration
);
426 EXPECT_EQ(alternative_service4
, map_it
->second
[1].alternative_service
);
427 EXPECT_EQ(0.7, map_it
->second
[1].probability
);
428 EXPECT_EQ(expiration4
, map_it
->second
[1].expiration
);
431 // Regression test for https://crbug.com/504032:
432 // InitializeAlternativeServiceServers() should not crash if there is an empty
433 // hostname is the mapping.
434 TEST_F(AlternateProtocolServerPropertiesTest
, InitializeWithEmptyHostname
) {
435 const HostPortPair
host_port_pair("foo", 443);
436 const AlternativeService
alternative_service_with_empty_hostname(NPN_HTTP_2
,
438 const AlternativeService
alternative_service_with_foo_hostname(NPN_HTTP_2
,
440 SetAlternativeService(host_port_pair
, alternative_service_with_empty_hostname
,
442 impl_
.MarkAlternativeServiceBroken(alternative_service_with_foo_hostname
);
444 AlternativeServiceMap
alternative_service_map(
445 AlternativeServiceMap::NO_AUTO_EVICT
);
446 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
449 impl_
.IsAlternativeServiceBroken(alternative_service_with_foo_hostname
));
450 const AlternativeServiceVector alternative_service_vector
=
451 impl_
.GetAlternativeServices(host_port_pair
);
452 ASSERT_EQ(1u, alternative_service_vector
.size());
453 EXPECT_EQ(alternative_service_with_foo_hostname
,
454 alternative_service_vector
[0]);
457 // Regression test for https://crbug.com/516486:
458 // GetAlternativeServices() should remove |alternative_service_map_| elements
460 TEST_F(AlternateProtocolServerPropertiesTest
, EmptyVector
) {
461 HostPortPair
host_port_pair("foo", 443);
462 const AlternativeService
alternative_service(NPN_HTTP_2
, "bar", 443);
463 base::Time expiration
= base::Time::Now() - base::TimeDelta::FromDays(1);
464 const AlternativeServiceInfo
alternative_service_info(alternative_service
,
466 AlternativeServiceMap
alternative_service_map(
467 AlternativeServiceMap::NO_AUTO_EVICT
);
468 alternative_service_map
.Put(
470 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info
));
472 // Prepare |alternative_service_map_| with a single key that has a single
473 // AlternativeServiceInfo with identical hostname and port.
474 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
476 // GetAlternativeServices() should remove such AlternativeServiceInfo from
477 // |alternative_service_map_|, emptying the AlternativeServiceInfoVector
478 // corresponding to |host_port_pair|.
479 AlternativeServiceVector alternative_service_vector
=
480 impl_
.GetAlternativeServices(host_port_pair
);
481 ASSERT_TRUE(alternative_service_vector
.empty());
483 // GetAlternativeServices() should remove this key from
484 // |alternative_service_map_|, and SetAlternativeServices() should not crash.
485 impl_
.SetAlternativeServices(
487 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info
));
489 // There should still be no alternative service assigned to |host_port_pair|.
490 alternative_service_vector
= impl_
.GetAlternativeServices(host_port_pair
);
491 ASSERT_TRUE(alternative_service_vector
.empty());
494 // Regression test for https://crbug.com/516486 for the canonical host case.
495 TEST_F(AlternateProtocolServerPropertiesTest
, EmptyVectorForCanonical
) {
496 HostPortPair
host_port_pair("foo.c.youtube.com", 443);
497 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 443);
498 const AlternativeService
alternative_service(NPN_HTTP_2
, "", 443);
499 base::Time expiration
= base::Time::Now() - base::TimeDelta::FromDays(1);
500 const AlternativeServiceInfo
alternative_service_info(alternative_service
,
502 AlternativeServiceMap
alternative_service_map(
503 AlternativeServiceMap::NO_AUTO_EVICT
);
504 alternative_service_map
.Put(
505 canonical_host_port_pair
,
506 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info
));
508 // Prepare |alternative_service_map_| with a single key that has a single
509 // AlternativeServiceInfo with identical hostname and port.
510 impl_
.InitializeAlternativeServiceServers(&alternative_service_map
);
512 // GetAlternativeServices() should remove such AlternativeServiceInfo from
513 // |alternative_service_map_|, emptying the AlternativeServiceInfoVector
514 // corresponding to |canonical_host_port_pair|, even when looking up
515 // alternative services for |host_port_pair|.
516 AlternativeServiceVector alternative_service_vector
=
517 impl_
.GetAlternativeServices(host_port_pair
);
518 ASSERT_TRUE(alternative_service_vector
.empty());
520 // GetAlternativeServices() should remove this key from
521 // |alternative_service_map_|, and SetAlternativeServices() should not crash.
522 impl_
.SetAlternativeServices(
523 canonical_host_port_pair
,
524 AlternativeServiceInfoVector(/*size=*/1, alternative_service_info
));
526 // There should still be no alternative service assigned to
527 // |canonical_host_port_pair|.
528 alternative_service_vector
=
529 impl_
.GetAlternativeServices(canonical_host_port_pair
);
530 ASSERT_TRUE(alternative_service_vector
.empty());
533 TEST_F(AlternateProtocolServerPropertiesTest
, MRUOfGetAlternativeServices
) {
534 HostPortPair
test_host_port_pair1("foo1", 80);
535 const AlternativeService
alternative_service1(NPN_SPDY_3_1
, "foo1", 443);
536 SetAlternativeService(test_host_port_pair1
, alternative_service1
, 1.0);
537 HostPortPair
test_host_port_pair2("foo2", 80);
538 const AlternativeService
alternative_service2(NPN_HTTP_2
, "foo2", 1234);
539 SetAlternativeService(test_host_port_pair2
, alternative_service2
, 1.0);
541 const AlternativeServiceMap
& map
= impl_
.alternative_service_map();
542 AlternativeServiceMap::const_iterator it
= map
.begin();
543 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair2
));
544 ASSERT_EQ(1u, it
->second
.size());
545 EXPECT_EQ(alternative_service2
, it
->second
[0].alternative_service
);
547 const AlternativeServiceVector alternative_service_vector
=
548 impl_
.GetAlternativeServices(test_host_port_pair1
);
549 ASSERT_EQ(1u, alternative_service_vector
.size());
550 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
552 // GetAlternativeServices should reorder the AlternateProtocol map.
554 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair1
));
555 ASSERT_EQ(1u, it
->second
.size());
556 EXPECT_EQ(alternative_service1
, it
->second
[0].alternative_service
);
559 TEST_F(AlternateProtocolServerPropertiesTest
, SetBroken
) {
560 HostPortPair
test_host_port_pair("foo", 80);
561 const AlternativeService
alternative_service1(NPN_HTTP_2
, "foo", 443);
562 SetAlternativeService(test_host_port_pair
, alternative_service1
, 1.0);
563 AlternativeServiceVector alternative_service_vector
=
564 impl_
.GetAlternativeServices(test_host_port_pair
);
565 ASSERT_EQ(1u, alternative_service_vector
.size());
566 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
567 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service1
));
569 // GetAlternativeServices should return the broken alternative service.
570 impl_
.MarkAlternativeServiceBroken(alternative_service1
);
571 alternative_service_vector
=
572 impl_
.GetAlternativeServices(test_host_port_pair
);
573 ASSERT_EQ(1u, alternative_service_vector
.size());
574 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
575 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service1
));
577 // SetAlternativeServices should add a broken alternative service to the map.
578 AlternativeServiceInfoVector alternative_service_info_vector
;
579 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
580 alternative_service_info_vector
.push_back(
581 AlternativeServiceInfo(alternative_service1
, 1.0, expiration
));
582 const AlternativeService
alternative_service2(NPN_HTTP_2
, "foo", 1234);
583 alternative_service_info_vector
.push_back(
584 AlternativeServiceInfo(alternative_service2
, 1.0, expiration
));
585 impl_
.SetAlternativeServices(test_host_port_pair
,
586 alternative_service_info_vector
);
587 alternative_service_vector
=
588 impl_
.GetAlternativeServices(test_host_port_pair
);
589 ASSERT_EQ(2u, alternative_service_vector
.size());
590 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
591 EXPECT_EQ(alternative_service2
, alternative_service_vector
[1]);
592 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service_vector
[0]));
593 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service_vector
[1]));
595 // SetAlternativeService should add a broken alternative service to the map.
596 SetAlternativeService(test_host_port_pair
, alternative_service1
, 1.0);
597 alternative_service_vector
=
598 impl_
.GetAlternativeServices(test_host_port_pair
);
599 ASSERT_EQ(1u, alternative_service_vector
.size());
600 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
601 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service_vector
[0]));
604 TEST_F(AlternateProtocolServerPropertiesTest
, MaxAge
) {
605 AlternativeServiceInfoVector alternative_service_info_vector
;
606 base::Time now
= base::Time::Now();
607 base::TimeDelta one_day
= base::TimeDelta::FromDays(1);
609 // First alternative service expired one day ago, should not be returned by
610 // GetAlternativeServices().
611 const AlternativeService
alternative_service1(NPN_SPDY_3_1
, "foo", 443);
612 alternative_service_info_vector
.push_back(
613 AlternativeServiceInfo(alternative_service1
, 1.0, now
- one_day
));
615 // Second alterrnative service will expire one day from now, should be
616 // returned by GetAlternativeSerices().
617 const AlternativeService
alternative_service2(NPN_HTTP_2
, "bar", 1234);
618 alternative_service_info_vector
.push_back(
619 AlternativeServiceInfo(alternative_service2
, 1.0, now
+ one_day
));
621 HostPortPair
test_host_port_pair("foo", 80);
622 impl_
.SetAlternativeServices(test_host_port_pair
,
623 alternative_service_info_vector
);
625 AlternativeServiceVector alternative_service_vector
=
626 impl_
.GetAlternativeServices(test_host_port_pair
);
627 ASSERT_EQ(1u, alternative_service_vector
.size());
628 EXPECT_EQ(alternative_service2
, alternative_service_vector
[0]);
631 TEST_F(AlternateProtocolServerPropertiesTest
, MaxAgeCanonical
) {
632 AlternativeServiceInfoVector alternative_service_info_vector
;
633 base::Time now
= base::Time::Now();
634 base::TimeDelta one_day
= base::TimeDelta::FromDays(1);
636 // First alternative service expired one day ago, should not be returned by
637 // GetAlternativeServices().
638 const AlternativeService
alternative_service1(NPN_SPDY_3_1
, "foo", 443);
639 alternative_service_info_vector
.push_back(
640 AlternativeServiceInfo(alternative_service1
, 1.0, now
- one_day
));
642 // Second alterrnative service will expire one day from now, should be
643 // returned by GetAlternativeSerices().
644 const AlternativeService
alternative_service2(NPN_HTTP_2
, "bar", 1234);
645 alternative_service_info_vector
.push_back(
646 AlternativeServiceInfo(alternative_service2
, 1.0, now
+ one_day
));
648 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
649 impl_
.SetAlternativeServices(canonical_host_port_pair
,
650 alternative_service_info_vector
);
652 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
653 AlternativeServiceVector alternative_service_vector
=
654 impl_
.GetAlternativeServices(test_host_port_pair
);
655 ASSERT_EQ(1u, alternative_service_vector
.size());
656 EXPECT_EQ(alternative_service2
, alternative_service_vector
[0]);
659 TEST_F(AlternateProtocolServerPropertiesTest
, ClearAlternativeServices
) {
660 AlternativeServiceInfoVector alternative_service_info_vector
;
661 const AlternativeService
alternative_service1(NPN_SPDY_3_1
, "foo", 443);
662 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
663 alternative_service_info_vector
.push_back(
664 AlternativeServiceInfo(alternative_service1
, 1.0, expiration
));
665 const AlternativeService
alternative_service2(NPN_HTTP_2
, "bar", 1234);
666 alternative_service_info_vector
.push_back(
667 AlternativeServiceInfo(alternative_service2
, 1.0, expiration
));
668 HostPortPair
test_host_port_pair("foo", 80);
669 impl_
.SetAlternativeServices(test_host_port_pair
,
670 alternative_service_info_vector
);
672 const net::AlternativeServiceMap
& map
= impl_
.alternative_service_map();
673 net::AlternativeServiceMap::const_iterator it
= map
.begin();
674 EXPECT_TRUE(it
->first
.Equals(test_host_port_pair
));
675 ASSERT_EQ(2u, it
->second
.size());
676 EXPECT_EQ(alternative_service1
, it
->second
[0].alternative_service
);
677 EXPECT_EQ(alternative_service2
, it
->second
[1].alternative_service
);
679 impl_
.ClearAlternativeServices(test_host_port_pair
);
680 EXPECT_TRUE(map
.empty());
683 // A broken alternative service in the mapping carries meaningful information,
684 // therefore it should not be ignored by SetAlternativeService(). In
685 // particular, an alternative service mapped to an origin shadows alternative
686 // services of canonical hosts.
687 TEST_F(AlternateProtocolServerPropertiesTest
, BrokenShadowsCanonical
) {
688 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
689 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
690 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
692 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
694 AlternativeServiceVector alternative_service_vector
=
695 impl_
.GetAlternativeServices(test_host_port_pair
);
696 ASSERT_EQ(1u, alternative_service_vector
.size());
697 EXPECT_EQ(canonical_alternative_service
, alternative_service_vector
[0]);
699 const AlternativeService
broken_alternative_service(NPN_HTTP_2
, "foo", 443);
700 impl_
.MarkAlternativeServiceBroken(broken_alternative_service
);
701 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(broken_alternative_service
));
703 SetAlternativeService(test_host_port_pair
, broken_alternative_service
, 1.0);
704 alternative_service_vector
=
705 impl_
.GetAlternativeServices(test_host_port_pair
);
706 ASSERT_EQ(1u, alternative_service_vector
.size());
707 EXPECT_EQ(broken_alternative_service
, alternative_service_vector
[0]);
708 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(broken_alternative_service
));
711 TEST_F(AlternateProtocolServerPropertiesTest
, ClearBroken
) {
712 HostPortPair
test_host_port_pair("foo", 80);
713 const AlternativeService
alternative_service(NPN_HTTP_2
, "foo", 443);
714 SetAlternativeService(test_host_port_pair
, alternative_service
, 1.0);
715 impl_
.MarkAlternativeServiceBroken(alternative_service
);
716 ASSERT_TRUE(HasAlternativeService(test_host_port_pair
));
717 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
718 // ClearAlternativeServices should leave a broken alternative service marked
720 impl_
.ClearAlternativeServices(test_host_port_pair
);
721 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
724 TEST_F(AlternateProtocolServerPropertiesTest
, MarkRecentlyBroken
) {
725 HostPortPair
host_port_pair("foo", 80);
726 const AlternativeService
alternative_service(NPN_HTTP_2
, "foo", 443);
727 SetAlternativeService(host_port_pair
, alternative_service
, 1.0);
729 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
730 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
732 impl_
.MarkAlternativeServiceRecentlyBroken(alternative_service
);
733 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
734 EXPECT_TRUE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
736 impl_
.ConfirmAlternativeService(alternative_service
);
737 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
738 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
741 TEST_F(AlternateProtocolServerPropertiesTest
, Canonical
) {
742 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
743 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
745 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
746 EXPECT_FALSE(HasAlternativeService(canonical_host_port_pair
));
748 AlternativeServiceInfoVector alternative_service_info_vector
;
749 const AlternativeService
canonical_alternative_service1(
750 QUIC
, "bar.c.youtube.com", 1234);
751 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
752 alternative_service_info_vector
.push_back(
753 AlternativeServiceInfo(canonical_alternative_service1
, 1.0, expiration
));
754 const AlternativeService
canonical_alternative_service2(NPN_HTTP_2
, "", 443);
755 alternative_service_info_vector
.push_back(
756 AlternativeServiceInfo(canonical_alternative_service2
, 1.0, expiration
));
757 impl_
.SetAlternativeServices(canonical_host_port_pair
,
758 alternative_service_info_vector
);
760 // Since |test_host_port_pair| does not have an alternative service itself,
761 // GetAlternativeServices should return those of |canonical_host_port_pair|.
762 AlternativeServiceVector alternative_service_vector
=
763 impl_
.GetAlternativeServices(test_host_port_pair
);
764 ASSERT_EQ(2u, alternative_service_vector
.size());
765 EXPECT_EQ(canonical_alternative_service1
, alternative_service_vector
[0]);
767 // Since |canonical_alternative_service2| has an empty host,
768 // GetAlternativeServices should substitute the hostname of its |origin|
770 EXPECT_EQ(test_host_port_pair
.host(), alternative_service_vector
[1].host
);
771 EXPECT_EQ(canonical_alternative_service2
.protocol
,
772 alternative_service_vector
[1].protocol
);
773 EXPECT_EQ(canonical_alternative_service2
.port
,
774 alternative_service_vector
[1].port
);
776 // Verify the canonical suffix.
777 EXPECT_EQ(".c.youtube.com",
778 impl_
.GetCanonicalSuffix(test_host_port_pair
.host()));
779 EXPECT_EQ(".c.youtube.com",
780 impl_
.GetCanonicalSuffix(canonical_host_port_pair
.host()));
783 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalBelowThreshold
) {
784 impl_
.SetAlternativeServiceProbabilityThreshold(0.02);
786 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
787 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
788 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
791 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
793 EXPECT_FALSE(HasAlternativeService(canonical_host_port_pair
));
794 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
797 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalAboveThreshold
) {
798 impl_
.SetAlternativeServiceProbabilityThreshold(0.02);
800 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
801 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
802 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
805 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
807 EXPECT_TRUE(HasAlternativeService(canonical_host_port_pair
));
808 EXPECT_TRUE(HasAlternativeService(test_host_port_pair
));
811 TEST_F(AlternateProtocolServerPropertiesTest
, ClearCanonical
) {
812 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
813 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
814 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
817 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
819 impl_
.ClearAlternativeServices(canonical_host_port_pair
);
820 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
823 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalBroken
) {
824 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
825 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
826 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
829 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
831 impl_
.MarkAlternativeServiceBroken(canonical_alternative_service
);
832 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
835 // Adding an alternative service for a new host overrides canonical host.
836 TEST_F(AlternateProtocolServerPropertiesTest
, CanonicalOverride
) {
837 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
838 HostPortPair
bar_host_port_pair("bar.c.youtube.com", 80);
839 AlternativeService
bar_alternative_service(QUIC
, "bar.c.youtube.com", 1234);
840 SetAlternativeService(bar_host_port_pair
, bar_alternative_service
, 1.0);
841 AlternativeServiceVector alternative_service_vector
=
842 impl_
.GetAlternativeServices(test_host_port_pair
);
843 ASSERT_EQ(1u, alternative_service_vector
.size());
844 EXPECT_EQ(bar_alternative_service
, alternative_service_vector
[0]);
846 HostPortPair
qux_host_port_pair("qux.c.youtube.com", 80);
847 AlternativeService
qux_alternative_service(QUIC
, "qux.c.youtube.com", 443);
848 SetAlternativeService(qux_host_port_pair
, qux_alternative_service
, 1.0);
849 alternative_service_vector
=
850 impl_
.GetAlternativeServices(test_host_port_pair
);
851 ASSERT_EQ(1u, alternative_service_vector
.size());
852 EXPECT_EQ(qux_alternative_service
, alternative_service_vector
[0]);
855 TEST_F(AlternateProtocolServerPropertiesTest
, ClearWithCanonical
) {
856 HostPortPair
test_host_port_pair("foo.c.youtube.com", 80);
857 HostPortPair
canonical_host_port_pair("bar.c.youtube.com", 80);
858 AlternativeService
canonical_alternative_service(QUIC
, "bar.c.youtube.com",
861 SetAlternativeService(canonical_host_port_pair
, canonical_alternative_service
,
864 EXPECT_FALSE(HasAlternativeService(test_host_port_pair
));
867 TEST_F(AlternateProtocolServerPropertiesTest
,
868 ExpireBrokenAlternateProtocolMappings
) {
869 HostPortPair
host_port_pair("foo", 443);
870 AlternativeService
alternative_service(QUIC
, "foo", 443);
871 SetAlternativeService(host_port_pair
, alternative_service
, 1.0);
872 EXPECT_TRUE(HasAlternativeService(host_port_pair
));
873 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
874 EXPECT_FALSE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
876 base::TimeTicks past
=
877 base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42);
878 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime(
879 impl_
, alternative_service
, past
);
880 EXPECT_TRUE(impl_
.IsAlternativeServiceBroken(alternative_service
));
881 EXPECT_TRUE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
883 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(impl_
);
884 EXPECT_FALSE(impl_
.IsAlternativeServiceBroken(alternative_service
));
885 EXPECT_TRUE(impl_
.WasAlternativeServiceRecentlyBroken(alternative_service
));
888 // Regression test for https://crbug.com/505413.
889 TEST_F(AlternateProtocolServerPropertiesTest
, RemoveExpiredBrokenAltSvc
) {
890 HostPortPair
foo_host_port_pair("foo", 443);
891 AlternativeService
bar_alternative_service(QUIC
, "bar", 443);
892 SetAlternativeService(foo_host_port_pair
, bar_alternative_service
, 1.0);
893 EXPECT_TRUE(HasAlternativeService(foo_host_port_pair
));
895 HostPortPair
bar_host_port_pair1("bar", 80);
896 AlternativeService
nohost_alternative_service(QUIC
, "", 443);
897 SetAlternativeService(bar_host_port_pair1
, nohost_alternative_service
, 1.0);
898 EXPECT_TRUE(HasAlternativeService(bar_host_port_pair1
));
900 HostPortPair
bar_host_port_pair2("bar", 443);
901 AlternativeService
baz_alternative_service(QUIC
, "baz", 1234);
902 SetAlternativeService(bar_host_port_pair2
, baz_alternative_service
, 1.0);
903 EXPECT_TRUE(HasAlternativeService(bar_host_port_pair2
));
905 // Mark "bar:443" as broken.
906 base::TimeTicks past
=
907 base::TimeTicks::Now() - base::TimeDelta::FromSeconds(42);
908 HttpServerPropertiesImplPeer::AddBrokenAlternativeServiceWithExpirationTime(
909 impl_
, bar_alternative_service
, past
);
911 // Expire brokenness of "bar:443".
912 HttpServerPropertiesImplPeer::ExpireBrokenAlternateProtocolMappings(impl_
);
914 // "foo:443" should have no alternative service now.
915 EXPECT_FALSE(HasAlternativeService(foo_host_port_pair
));
916 // "bar:80" should have no alternative service now.
917 EXPECT_FALSE(HasAlternativeService(bar_host_port_pair1
));
918 // The alternative service of "bar:443" should be unaffected.
919 EXPECT_TRUE(HasAlternativeService(bar_host_port_pair2
));
922 impl_
.WasAlternativeServiceRecentlyBroken(bar_alternative_service
));
924 impl_
.WasAlternativeServiceRecentlyBroken(baz_alternative_service
));
927 typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest
;
929 TEST_F(SpdySettingsServerPropertiesTest
, Initialize
) {
930 HostPortPair
spdy_server_google("www.google.com", 443);
932 // Check by initializing empty spdy settings.
933 SpdySettingsMap
spdy_settings_map(SpdySettingsMap::NO_AUTO_EVICT
);
934 impl_
.InitializeSpdySettingsServers(&spdy_settings_map
);
935 EXPECT_TRUE(impl_
.GetSpdySettings(spdy_server_google
).empty());
937 // Check by initializing with www.google.com:443 spdy server settings.
938 SettingsMap settings_map
;
939 const SpdySettingsIds id
= SETTINGS_UPLOAD_BANDWIDTH
;
940 const SpdySettingsFlags flags
= SETTINGS_FLAG_PERSISTED
;
941 const uint32 value
= 31337;
942 SettingsFlagsAndValue
flags_and_value(flags
, value
);
943 settings_map
[id
] = flags_and_value
;
944 spdy_settings_map
.Put(spdy_server_google
, settings_map
);
945 impl_
.InitializeSpdySettingsServers(&spdy_settings_map
);
947 const SettingsMap
& settings_map2
= impl_
.GetSpdySettings(spdy_server_google
);
948 ASSERT_EQ(1U, settings_map2
.size());
949 SettingsMap::const_iterator it
= settings_map2
.find(id
);
950 EXPECT_TRUE(it
!= settings_map2
.end());
951 SettingsFlagsAndValue flags_and_value2
= it
->second
;
952 EXPECT_EQ(flags
, flags_and_value2
.first
);
953 EXPECT_EQ(value
, flags_and_value2
.second
);
956 TEST_F(SpdySettingsServerPropertiesTest
, SetSpdySetting
) {
957 HostPortPair
spdy_server_empty(std::string(), 443);
958 const SettingsMap
& settings_map0
= impl_
.GetSpdySettings(spdy_server_empty
);
959 EXPECT_EQ(0U, settings_map0
.size()); // Returns kEmptySettingsMap.
961 // Add www.google.com:443 as persisting.
962 HostPortPair
spdy_server_google("www.google.com", 443);
963 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
964 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
965 const uint32 value1
= 31337;
966 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
968 const SettingsMap
& settings_map1_ret
=
969 impl_
.GetSpdySettings(spdy_server_google
);
970 ASSERT_EQ(1U, settings_map1_ret
.size());
971 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
972 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
973 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
974 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
975 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
977 // Add mail.google.com:443 as not persisting.
978 HostPortPair
spdy_server_mail("mail.google.com", 443);
979 const SpdySettingsIds id2
= SETTINGS_DOWNLOAD_BANDWIDTH
;
980 const SpdySettingsFlags flags2
= SETTINGS_FLAG_NONE
;
981 const uint32 value2
= 62667;
982 EXPECT_FALSE(impl_
.SetSpdySetting(spdy_server_mail
, id2
, flags2
, value2
));
983 const SettingsMap
& settings_map2_ret
=
984 impl_
.GetSpdySettings(spdy_server_mail
);
985 EXPECT_EQ(0U, settings_map2_ret
.size()); // Returns kEmptySettingsMap.
987 // Add docs.google.com:443 as persisting
988 HostPortPair
spdy_server_docs("docs.google.com", 443);
989 const SpdySettingsIds id3
= SETTINGS_ROUND_TRIP_TIME
;
990 const SpdySettingsFlags flags3
= SETTINGS_FLAG_PLEASE_PERSIST
;
991 const uint32 value3
= 93997;
992 SettingsFlagsAndValue
flags_and_value3(flags3
, value3
);
993 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id3
, flags3
, value3
));
995 const SettingsMap
& settings_map3_ret
=
996 impl_
.GetSpdySettings(spdy_server_docs
);
997 ASSERT_EQ(1U, settings_map3_ret
.size());
998 SettingsMap::const_iterator it3_ret
= settings_map3_ret
.find(id3
);
999 EXPECT_TRUE(it3_ret
!= settings_map3_ret
.end());
1000 SettingsFlagsAndValue flags_and_value3_ret
= it3_ret
->second
;
1001 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value3_ret
.first
);
1002 EXPECT_EQ(value3
, flags_and_value3_ret
.second
);
1004 // Check data for www.google.com:443 (id1).
1005 const SettingsMap
& settings_map4_ret
=
1006 impl_
.GetSpdySettings(spdy_server_google
);
1007 ASSERT_EQ(1U, settings_map4_ret
.size());
1008 SettingsMap::const_iterator it4_ret
= settings_map4_ret
.find(id1
);
1009 EXPECT_TRUE(it4_ret
!= settings_map4_ret
.end());
1010 SettingsFlagsAndValue flags_and_value4_ret
= it4_ret
->second
;
1011 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value4_ret
.first
);
1012 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
1014 // Clear www.google.com:443 as persisting.
1015 impl_
.ClearSpdySettings(spdy_server_google
);
1016 // Check the values.
1017 const SettingsMap
& settings_map5_ret
=
1018 impl_
.GetSpdySettings(spdy_server_google
);
1019 ASSERT_EQ(0U, settings_map5_ret
.size());
1021 // Clear all settings.
1022 ASSERT_GT(impl_
.spdy_settings_map().size(), 0U);
1023 impl_
.ClearAllSpdySettings();
1024 ASSERT_EQ(0U, impl_
.spdy_settings_map().size());
1027 TEST_F(SpdySettingsServerPropertiesTest
, Clear
) {
1028 // Add www.google.com:443 as persisting.
1029 HostPortPair
spdy_server_google("www.google.com", 443);
1030 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
1031 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
1032 const uint32 value1
= 31337;
1033 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
1034 // Check the values.
1035 const SettingsMap
& settings_map1_ret
=
1036 impl_
.GetSpdySettings(spdy_server_google
);
1037 ASSERT_EQ(1U, settings_map1_ret
.size());
1038 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
1039 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
1040 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
1041 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
1042 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
1044 // Add docs.google.com:443 as persisting
1045 HostPortPair
spdy_server_docs("docs.google.com", 443);
1046 const SpdySettingsIds id3
= SETTINGS_ROUND_TRIP_TIME
;
1047 const SpdySettingsFlags flags3
= SETTINGS_FLAG_PLEASE_PERSIST
;
1048 const uint32 value3
= 93997;
1049 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id3
, flags3
, value3
));
1050 // Check the values.
1051 const SettingsMap
& settings_map3_ret
=
1052 impl_
.GetSpdySettings(spdy_server_docs
);
1053 ASSERT_EQ(1U, settings_map3_ret
.size());
1054 SettingsMap::const_iterator it3_ret
= settings_map3_ret
.find(id3
);
1055 EXPECT_TRUE(it3_ret
!= settings_map3_ret
.end());
1056 SettingsFlagsAndValue flags_and_value3_ret
= it3_ret
->second
;
1057 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value3_ret
.first
);
1058 EXPECT_EQ(value3
, flags_and_value3_ret
.second
);
1061 EXPECT_EQ(0U, impl_
.GetSpdySettings(spdy_server_google
).size());
1062 EXPECT_EQ(0U, impl_
.GetSpdySettings(spdy_server_docs
).size());
1065 TEST_F(SpdySettingsServerPropertiesTest
, MRUOfGetSpdySettings
) {
1066 // Add www.google.com:443 as persisting.
1067 HostPortPair
spdy_server_google("www.google.com", 443);
1068 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
1069 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
1070 const uint32 value1
= 31337;
1071 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_google
, id1
, flags1
, value1
));
1073 // Add docs.google.com:443 as persisting
1074 HostPortPair
spdy_server_docs("docs.google.com", 443);
1075 const SpdySettingsIds id2
= SETTINGS_ROUND_TRIP_TIME
;
1076 const SpdySettingsFlags flags2
= SETTINGS_FLAG_PLEASE_PERSIST
;
1077 const uint32 value2
= 93997;
1078 EXPECT_TRUE(impl_
.SetSpdySetting(spdy_server_docs
, id2
, flags2
, value2
));
1080 // Verify the first element is docs.google.com:443.
1081 const SpdySettingsMap
& map
= impl_
.spdy_settings_map();
1082 SpdySettingsMap::const_iterator it
= map
.begin();
1083 EXPECT_TRUE(it
->first
.Equals(spdy_server_docs
));
1084 const SettingsMap
& settings_map2_ret
= it
->second
;
1085 ASSERT_EQ(1U, settings_map2_ret
.size());
1086 SettingsMap::const_iterator it2_ret
= settings_map2_ret
.find(id2
);
1087 EXPECT_TRUE(it2_ret
!= settings_map2_ret
.end());
1088 SettingsFlagsAndValue flags_and_value2_ret
= it2_ret
->second
;
1089 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value2_ret
.first
);
1090 EXPECT_EQ(value2
, flags_and_value2_ret
.second
);
1092 // GetSpdySettings should reorder the SpdySettingsMap.
1093 const SettingsMap
& settings_map1_ret
=
1094 impl_
.GetSpdySettings(spdy_server_google
);
1095 ASSERT_EQ(1U, settings_map1_ret
.size());
1096 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
1097 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
1098 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
1099 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
1100 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
1102 // Check the first entry is spdy_server_google by accessing it via iterator.
1104 EXPECT_TRUE(it
->first
.Equals(spdy_server_google
));
1105 const SettingsMap
& settings_map1_it_ret
= it
->second
;
1106 ASSERT_EQ(1U, settings_map1_it_ret
.size());
1107 it1_ret
= settings_map1_it_ret
.find(id1
);
1108 EXPECT_TRUE(it1_ret
!= settings_map1_it_ret
.end());
1109 flags_and_value1_ret
= it1_ret
->second
;
1110 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
1111 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
1114 typedef HttpServerPropertiesImplTest SupportsQuicServerPropertiesTest
;
1116 TEST_F(SupportsQuicServerPropertiesTest
, Initialize
) {
1117 HostPortPair
quic_server_google("www.google.com", 443);
1119 // Check by initializing empty address.
1120 IPAddressNumber initial_address
;
1121 impl_
.InitializeSupportsQuic(&initial_address
);
1123 IPAddressNumber address
;
1124 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
1125 EXPECT_TRUE(address
.empty());
1127 // Check by initializing with a valid address.
1128 CHECK(ParseIPLiteralToNumber("127.0.0.1", &initial_address
));
1129 impl_
.InitializeSupportsQuic(&initial_address
);
1131 EXPECT_TRUE(impl_
.GetSupportsQuic(&address
));
1132 EXPECT_EQ(initial_address
, address
);
1135 TEST_F(SupportsQuicServerPropertiesTest
, SetSupportsQuic
) {
1136 IPAddressNumber address
;
1137 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
1138 EXPECT_TRUE(address
.empty());
1140 IPAddressNumber actual_address
;
1141 CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address
));
1142 impl_
.SetSupportsQuic(true, actual_address
);
1144 EXPECT_TRUE(impl_
.GetSupportsQuic(&address
));
1145 EXPECT_EQ(actual_address
, address
);
1149 EXPECT_FALSE(impl_
.GetSupportsQuic(&address
));
1152 typedef HttpServerPropertiesImplTest ServerNetworkStatsServerPropertiesTest
;
1154 TEST_F(ServerNetworkStatsServerPropertiesTest
, Initialize
) {
1155 HostPortPair
google_server("www.google.com", 443);
1157 // Check by initializing empty ServerNetworkStats.
1158 ServerNetworkStatsMap
server_network_stats_map(
1159 ServerNetworkStatsMap::NO_AUTO_EVICT
);
1160 impl_
.InitializeServerNetworkStats(&server_network_stats_map
);
1161 const ServerNetworkStats
* stats
= impl_
.GetServerNetworkStats(google_server
);
1162 EXPECT_EQ(NULL
, stats
);
1164 // Check by initializing with www.google.com:443.
1165 ServerNetworkStats stats1
;
1166 stats1
.srtt
= base::TimeDelta::FromMicroseconds(10);
1167 stats1
.bandwidth_estimate
= QuicBandwidth::FromBitsPerSecond(100);
1168 server_network_stats_map
.Put(google_server
, stats1
);
1169 impl_
.InitializeServerNetworkStats(&server_network_stats_map
);
1171 const ServerNetworkStats
* stats2
= impl_
.GetServerNetworkStats(google_server
);
1172 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
1173 EXPECT_EQ(100, stats2
->bandwidth_estimate
.ToBitsPerSecond());
1176 TEST_F(ServerNetworkStatsServerPropertiesTest
, SetServerNetworkStats
) {
1177 HostPortPair
foo_server("foo", 80);
1178 const ServerNetworkStats
* stats
= impl_
.GetServerNetworkStats(foo_server
);
1179 EXPECT_EQ(NULL
, stats
);
1181 ServerNetworkStats stats1
;
1182 stats1
.srtt
= base::TimeDelta::FromMicroseconds(10);
1183 stats1
.bandwidth_estimate
= QuicBandwidth::FromBitsPerSecond(100);
1184 impl_
.SetServerNetworkStats(foo_server
, stats1
);
1186 const ServerNetworkStats
* stats2
= impl_
.GetServerNetworkStats(foo_server
);
1187 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
1188 EXPECT_EQ(100, stats2
->bandwidth_estimate
.ToBitsPerSecond());
1191 const ServerNetworkStats
* stats3
= impl_
.GetServerNetworkStats(foo_server
);
1192 EXPECT_EQ(NULL
, stats3
);