1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_server_properties_manager.h"
7 #include "base/basictypes.h"
8 #include "base/json/json_writer.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/testing_pref_service.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/test/test_simple_task_runner.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "base/values.h"
19 #include "net/base/ip_address_number.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
28 using base::StringPrintf
;
30 using ::testing::Invoke
;
31 using ::testing::Mock
;
32 using ::testing::StrictMock
;
34 const char kTestHttpServerProperties
[] = "TestHttpServerProperties";
36 class TestingHttpServerPropertiesManager
: public HttpServerPropertiesManager
{
38 TestingHttpServerPropertiesManager(
39 PrefService
* pref_service
,
40 const char* pref_path
,
41 scoped_refptr
<base::SingleThreadTaskRunner
> io_task_runner
)
42 : HttpServerPropertiesManager(pref_service
, pref_path
, io_task_runner
) {
43 InitializeOnNetworkThread();
46 ~TestingHttpServerPropertiesManager() override
{}
48 // Make these methods public for testing.
49 using HttpServerPropertiesManager::ScheduleUpdateCacheOnPrefThread
;
51 // Post tasks without a delay during tests.
52 void StartPrefsUpdateTimerOnNetworkThread(base::TimeDelta delay
) override
{
53 HttpServerPropertiesManager::StartPrefsUpdateTimerOnNetworkThread(
57 void UpdateCacheFromPrefsOnUIConcrete() {
58 HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread();
61 // Post tasks without a delay during tests.
62 void StartCacheUpdateTimerOnPrefThread(base::TimeDelta delay
) override
{
63 HttpServerPropertiesManager::StartCacheUpdateTimerOnPrefThread(
67 void UpdatePrefsFromCacheOnNetworkThreadConcrete(
68 const base::Closure
& callback
) {
69 HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(callback
);
72 void ScheduleUpdatePrefsOnNetworkThreadConcrete(Location location
) {
73 HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread(location
);
76 void ScheduleUpdatePrefsOnNetworkThread() {
77 // Picked a random Location as caller.
78 HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread(
79 DETECTED_CORRUPTED_PREFS
);
82 MOCK_METHOD0(UpdateCacheFromPrefsOnPrefThread
, void());
83 MOCK_METHOD1(UpdatePrefsFromCacheOnNetworkThread
, void(const base::Closure
&));
84 MOCK_METHOD1(ScheduleUpdatePrefsOnNetworkThread
, void(Location location
));
85 MOCK_METHOD6(UpdateCacheFromPrefsOnNetworkThread
,
86 void(std::vector
<std::string
>* spdy_servers
,
87 SpdySettingsMap
* spdy_settings_map
,
88 AlternativeServiceMap
* alternative_service_map
,
89 IPAddressNumber
* last_quic_address
,
90 ServerNetworkStatsMap
* server_network_stats_map
,
91 bool detected_corrupted_prefs
));
92 MOCK_METHOD5(UpdatePrefsOnPref
,
93 void(base::ListValue
* spdy_server_list
,
94 SpdySettingsMap
* spdy_settings_map
,
95 AlternativeServiceMap
* alternative_service_map
,
96 IPAddressNumber
* last_quic_address
,
97 ServerNetworkStatsMap
* server_network_stats_map
));
100 DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager
);
103 class HttpServerPropertiesManagerTest
: public testing::Test
{
105 HttpServerPropertiesManagerTest() {}
107 void SetUp() override
{
108 one_day_from_now_
= base::Time::Now() + base::TimeDelta::FromDays(1);
109 pref_service_
.registry()->RegisterDictionaryPref(kTestHttpServerProperties
);
110 http_server_props_manager_
.reset(
111 new StrictMock
<TestingHttpServerPropertiesManager
>(
112 &pref_service_
, kTestHttpServerProperties
,
113 base::ThreadTaskRunnerHandle::Get()));
115 base::RunLoop().RunUntilIdle();
118 void TearDown() override
{
119 if (http_server_props_manager_
.get())
120 http_server_props_manager_
->ShutdownOnPrefThread();
121 base::RunLoop().RunUntilIdle();
122 http_server_props_manager_
.reset();
125 void ExpectCacheUpdate() {
126 EXPECT_CALL(*http_server_props_manager_
, UpdateCacheFromPrefsOnPrefThread())
127 .WillOnce(Invoke(http_server_props_manager_
.get(),
128 &TestingHttpServerPropertiesManager::
129 UpdateCacheFromPrefsOnUIConcrete
));
132 void ExpectScheduleUpdatePrefsOnNetworkThread() {
133 EXPECT_CALL(*http_server_props_manager_
,
134 ScheduleUpdatePrefsOnNetworkThread(_
))
135 .WillOnce(Invoke(http_server_props_manager_
.get(),
136 &TestingHttpServerPropertiesManager::
137 ScheduleUpdatePrefsOnNetworkThreadConcrete
));
140 void ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly() {
141 EXPECT_CALL(*http_server_props_manager_
,
142 ScheduleUpdatePrefsOnNetworkThread(_
))
143 .WillRepeatedly(Invoke(http_server_props_manager_
.get(),
144 &TestingHttpServerPropertiesManager::
145 ScheduleUpdatePrefsOnNetworkThreadConcrete
));
148 void ExpectPrefsUpdate() {
149 EXPECT_CALL(*http_server_props_manager_
,
150 UpdatePrefsFromCacheOnNetworkThread(_
))
151 .WillOnce(Invoke(http_server_props_manager_
.get(),
152 &TestingHttpServerPropertiesManager::
153 UpdatePrefsFromCacheOnNetworkThreadConcrete
));
156 void ExpectPrefsUpdateRepeatedly() {
157 EXPECT_CALL(*http_server_props_manager_
,
158 UpdatePrefsFromCacheOnNetworkThread(_
))
160 Invoke(http_server_props_manager_
.get(),
161 &TestingHttpServerPropertiesManager::
162 UpdatePrefsFromCacheOnNetworkThreadConcrete
));
165 bool HasAlternativeService(const HostPortPair
& server
) {
166 const AlternativeServiceVector alternative_service_vector
=
167 http_server_props_manager_
->GetAlternativeServices(server
);
168 return !alternative_service_vector
.empty();
171 //base::RunLoop loop_;
172 TestingPrefServiceSimple pref_service_
;
173 scoped_ptr
<TestingHttpServerPropertiesManager
> http_server_props_manager_
;
174 base::Time one_day_from_now_
;
177 DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest
);
180 TEST_F(HttpServerPropertiesManagerTest
,
181 SingleUpdateForTwoSpdyServerPrefChanges
) {
184 // Set up the prefs for www.google.com:80 and mail.google.com:80 and then set
185 // it twice. Only expect a single cache update.
187 base::DictionaryValue
* server_pref_dict
= new base::DictionaryValue
;
188 HostPortPair
google_server("www.google.com", 80);
189 HostPortPair
mail_server("mail.google.com", 80);
191 // Set supports_spdy for www.google.com:80.
192 server_pref_dict
->SetBoolean("supports_spdy", true);
194 // Set up alternative_services for www.google.com:80.
195 base::DictionaryValue
* alternative_service_dict0
= new base::DictionaryValue
;
196 alternative_service_dict0
->SetInteger("port", 443);
197 alternative_service_dict0
->SetString("protocol_str", "npn-h2");
198 base::DictionaryValue
* alternative_service_dict1
= new base::DictionaryValue
;
199 alternative_service_dict1
->SetInteger("port", 1234);
200 alternative_service_dict1
->SetString("protocol_str", "quic");
201 base::ListValue
* alternative_service_list
= new base::ListValue
;
202 alternative_service_list
->Append(alternative_service_dict0
);
203 alternative_service_list
->Append(alternative_service_dict1
);
204 server_pref_dict
->SetWithoutPathExpansion("alternative_service",
205 alternative_service_list
);
207 // Set up ServerNetworkStats for www.google.com:80.
208 base::DictionaryValue
* stats
= new base::DictionaryValue
;
209 stats
->SetInteger("srtt", 10);
210 server_pref_dict
->SetWithoutPathExpansion("network_stats", stats
);
212 // Set the server preference for www.google.com:80.
213 base::DictionaryValue
* servers_dict
= new base::DictionaryValue
;
214 servers_dict
->SetWithoutPathExpansion("www.google.com:80", server_pref_dict
);
216 // Set the preference for mail.google.com server.
217 base::DictionaryValue
* server_pref_dict1
= new base::DictionaryValue
;
219 // Set supports_spdy for mail.google.com:80
220 server_pref_dict1
->SetBoolean("supports_spdy", true);
222 // Set up alternate_protocol for mail.google.com:80 to test migration to
223 // alternative_service.
224 base::DictionaryValue
* alternate_protocol_dict
= new base::DictionaryValue
;
225 alternate_protocol_dict
->SetString("protocol_str", "npn-spdy/3.1");
226 alternate_protocol_dict
->SetInteger("port", 444);
227 server_pref_dict1
->SetWithoutPathExpansion("alternate_protocol",
228 alternate_protocol_dict
);
230 // Set up ServerNetworkStats for mail.google.com:80.
231 base::DictionaryValue
* stats1
= new base::DictionaryValue
;
232 stats1
->SetInteger("srtt", 20);
233 server_pref_dict1
->SetWithoutPathExpansion("network_stats", stats1
);
234 // Set the server preference for mail.google.com:80.
235 servers_dict
->SetWithoutPathExpansion("mail.google.com:80",
238 base::DictionaryValue
* http_server_properties_dict
=
239 new base::DictionaryValue
;
240 HttpServerPropertiesManager::SetVersion(http_server_properties_dict
, -1);
241 http_server_properties_dict
->SetWithoutPathExpansion("servers", servers_dict
);
242 base::DictionaryValue
* supports_quic
= new base::DictionaryValue
;
243 supports_quic
->SetBoolean("used_quic", true);
244 supports_quic
->SetString("address", "127.0.0.1");
245 http_server_properties_dict
->SetWithoutPathExpansion("supports_quic",
248 // Set the same value for kHttpServerProperties multiple times.
249 pref_service_
.SetManagedPref(kTestHttpServerProperties
,
250 http_server_properties_dict
);
251 base::DictionaryValue
* http_server_properties_dict2
=
252 http_server_properties_dict
->DeepCopy();
253 pref_service_
.SetManagedPref(kTestHttpServerProperties
,
254 http_server_properties_dict2
);
256 base::RunLoop().RunUntilIdle();
257 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
259 // Verify SupportsSpdy.
261 http_server_props_manager_
->SupportsRequestPriority(google_server
));
262 EXPECT_TRUE(http_server_props_manager_
->SupportsRequestPriority(mail_server
));
263 EXPECT_FALSE(http_server_props_manager_
->SupportsRequestPriority(
264 HostPortPair::FromString("foo.google.com:1337")));
266 // Verify alternative service.
267 const AlternativeServiceMap
& map
=
268 http_server_props_manager_
->alternative_service_map();
269 ASSERT_EQ(2u, map
.size());
270 AlternativeServiceMap::const_iterator map_it
= map
.begin();
271 EXPECT_EQ("www.google.com", map_it
->first
.host());
272 ASSERT_EQ(2u, map_it
->second
.size());
273 EXPECT_EQ(NPN_HTTP_2
, map_it
->second
[0].alternative_service
.protocol
);
274 EXPECT_TRUE(map_it
->second
[0].alternative_service
.host
.empty());
275 EXPECT_EQ(443, map_it
->second
[0].alternative_service
.port
);
276 EXPECT_EQ(QUIC
, map_it
->second
[1].alternative_service
.protocol
);
277 EXPECT_TRUE(map_it
->second
[1].alternative_service
.host
.empty());
278 EXPECT_EQ(1234, map_it
->second
[1].alternative_service
.port
);
280 EXPECT_EQ("mail.google.com", map_it
->first
.host());
281 ASSERT_EQ(1u, map_it
->second
.size());
282 EXPECT_EQ(NPN_SPDY_3_1
, map_it
->second
[0].alternative_service
.protocol
);
283 EXPECT_TRUE(map_it
->second
[0].alternative_service
.host
.empty());
284 EXPECT_EQ(444, map_it
->second
[0].alternative_service
.port
);
286 // Verify SupportsQuic.
287 IPAddressNumber last_address
;
288 EXPECT_TRUE(http_server_props_manager_
->GetSupportsQuic(&last_address
));
289 EXPECT_EQ("127.0.0.1", IPAddressToString(last_address
));
291 // Verify ServerNetworkStats.
292 const ServerNetworkStats
* stats2
=
293 http_server_props_manager_
->GetServerNetworkStats(google_server
);
294 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
295 const ServerNetworkStats
* stats3
=
296 http_server_props_manager_
->GetServerNetworkStats(mail_server
);
297 EXPECT_EQ(20, stats3
->srtt
.ToInternalValue());
300 TEST_F(HttpServerPropertiesManagerTest
, BadCachedHostPortPair
) {
302 // The prefs are automaticalls updated in the case corruption is detected.
304 ExpectScheduleUpdatePrefsOnNetworkThread();
306 base::DictionaryValue
* server_pref_dict
= new base::DictionaryValue
;
308 // Set supports_spdy for www.google.com:65536.
309 server_pref_dict
->SetBoolean("supports_spdy", true);
311 // Set up alternative_service for www.google.com:65536.
312 base::DictionaryValue
* alternative_service_dict
= new base::DictionaryValue
;
313 alternative_service_dict
->SetString("protocol_str", "npn-h2");
314 alternative_service_dict
->SetInteger("port", 80);
315 base::ListValue
* alternative_service_list
= new base::ListValue
;
316 alternative_service_list
->Append(alternative_service_dict
);
317 server_pref_dict
->SetWithoutPathExpansion("alternative_service",
318 alternative_service_list
);
320 // Set up ServerNetworkStats for www.google.com:65536.
321 base::DictionaryValue
* stats
= new base::DictionaryValue
;
322 stats
->SetInteger("srtt", 10);
323 server_pref_dict
->SetWithoutPathExpansion("network_stats", stats
);
325 // Set the server preference for www.google.com:65536.
326 base::DictionaryValue
* servers_dict
= new base::DictionaryValue
;
327 servers_dict
->SetWithoutPathExpansion("www.google.com:65536",
330 base::DictionaryValue
* http_server_properties_dict
=
331 new base::DictionaryValue
;
332 HttpServerPropertiesManager::SetVersion(http_server_properties_dict
, -1);
333 http_server_properties_dict
->SetWithoutPathExpansion("servers", servers_dict
);
336 pref_service_
.SetManagedPref(kTestHttpServerProperties
,
337 http_server_properties_dict
);
339 base::RunLoop().RunUntilIdle();
340 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
342 // Verify that nothing is set.
343 EXPECT_FALSE(http_server_props_manager_
->SupportsRequestPriority(
344 HostPortPair::FromString("www.google.com:65536")));
346 HasAlternativeService(HostPortPair::FromString("www.google.com:65536")));
347 const ServerNetworkStats
* stats1
=
348 http_server_props_manager_
->GetServerNetworkStats(
349 HostPortPair::FromString("www.google.com:65536"));
350 EXPECT_EQ(NULL
, stats1
);
353 TEST_F(HttpServerPropertiesManagerTest
, BadCachedAltProtocolPort
) {
355 // The prefs are automaticalls updated in the case corruption is detected.
357 ExpectScheduleUpdatePrefsOnNetworkThread();
359 base::DictionaryValue
* server_pref_dict
= new base::DictionaryValue
;
361 // Set supports_spdy for www.google.com:80.
362 server_pref_dict
->SetBoolean("supports_spdy", true);
364 // Set up alternative_service for www.google.com:80.
365 base::DictionaryValue
* alternative_service_dict
= new base::DictionaryValue
;
366 alternative_service_dict
->SetString("protocol_str", "npn-h2");
367 alternative_service_dict
->SetInteger("port", 65536);
368 base::ListValue
* alternative_service_list
= new base::ListValue
;
369 alternative_service_list
->Append(alternative_service_dict
);
370 server_pref_dict
->SetWithoutPathExpansion("alternative_service",
371 alternative_service_list
);
373 // Set the server preference for www.google.com:80.
374 base::DictionaryValue
* servers_dict
= new base::DictionaryValue
;
375 servers_dict
->SetWithoutPathExpansion("www.google.com:80", server_pref_dict
);
377 base::DictionaryValue
* http_server_properties_dict
=
378 new base::DictionaryValue
;
379 HttpServerPropertiesManager::SetVersion(http_server_properties_dict
, -1);
380 http_server_properties_dict
->SetWithoutPathExpansion("servers", servers_dict
);
383 pref_service_
.SetManagedPref(kTestHttpServerProperties
,
384 http_server_properties_dict
);
386 base::RunLoop().RunUntilIdle();
387 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
389 // Verify alternative service is not set.
391 HasAlternativeService(HostPortPair::FromString("www.google.com:80")));
394 TEST_F(HttpServerPropertiesManagerTest
, SupportsSpdy
) {
396 ExpectScheduleUpdatePrefsOnNetworkThread();
398 // Post an update task to the network thread. SetSupportsSpdy calls
399 // ScheduleUpdatePrefsOnNetworkThread.
401 // Add mail.google.com:443 as a supporting spdy server.
402 HostPortPair
spdy_server_mail("mail.google.com", 443);
404 http_server_props_manager_
->SupportsRequestPriority(spdy_server_mail
));
405 http_server_props_manager_
->SetSupportsSpdy(spdy_server_mail
, true);
406 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
407 http_server_props_manager_
->SetSupportsSpdy(spdy_server_mail
, true);
410 base::RunLoop().RunUntilIdle();
413 http_server_props_manager_
->SupportsRequestPriority(spdy_server_mail
));
414 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
417 TEST_F(HttpServerPropertiesManagerTest
, SetSpdySetting
) {
419 ExpectScheduleUpdatePrefsOnNetworkThread();
421 // Add SpdySetting for mail.google.com:443.
422 HostPortPair
spdy_server_mail("mail.google.com", 443);
423 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
424 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
425 const uint32 value1
= 31337;
426 http_server_props_manager_
->SetSpdySetting(
427 spdy_server_mail
, id1
, flags1
, value1
);
430 base::RunLoop().RunUntilIdle();
432 const SettingsMap
& settings_map1_ret
=
433 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
434 ASSERT_EQ(1U, settings_map1_ret
.size());
435 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
436 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
437 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
438 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
439 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
441 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
444 TEST_F(HttpServerPropertiesManagerTest
, ClearSpdySetting
) {
445 ExpectPrefsUpdateRepeatedly();
446 ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
448 // Add SpdySetting for mail.google.com:443.
449 HostPortPair
spdy_server_mail("mail.google.com", 443);
450 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
451 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
452 const uint32 value1
= 31337;
453 http_server_props_manager_
->SetSpdySetting(
454 spdy_server_mail
, id1
, flags1
, value1
);
457 base::RunLoop().RunUntilIdle();
459 const SettingsMap
& settings_map1_ret
=
460 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
461 ASSERT_EQ(1U, settings_map1_ret
.size());
462 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
463 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
464 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
465 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
466 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
468 // Clear SpdySetting for mail.google.com:443.
469 http_server_props_manager_
->ClearSpdySettings(spdy_server_mail
);
472 base::RunLoop().RunUntilIdle();
474 // Verify that there are no entries in the settings map for
475 // mail.google.com:443.
476 const SettingsMap
& settings_map2_ret
=
477 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
478 ASSERT_EQ(0U, settings_map2_ret
.size());
480 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
483 TEST_F(HttpServerPropertiesManagerTest
, ClearAllSpdySetting
) {
484 ExpectPrefsUpdateRepeatedly();
485 ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
487 // Add SpdySetting for mail.google.com:443.
488 HostPortPair
spdy_server_mail("mail.google.com", 443);
489 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
490 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
491 const uint32 value1
= 31337;
492 http_server_props_manager_
->SetSpdySetting(
493 spdy_server_mail
, id1
, flags1
, value1
);
496 base::RunLoop().RunUntilIdle();
498 const SettingsMap
& settings_map1_ret
=
499 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
500 ASSERT_EQ(1U, settings_map1_ret
.size());
501 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
502 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
503 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
504 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
505 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
507 // Clear All SpdySettings.
508 http_server_props_manager_
->ClearAllSpdySettings();
511 base::RunLoop().RunUntilIdle();
513 // Verify that there are no entries in the settings map.
514 const SpdySettingsMap
& spdy_settings_map2_ret
=
515 http_server_props_manager_
->spdy_settings_map();
516 ASSERT_EQ(0U, spdy_settings_map2_ret
.size());
518 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
521 TEST_F(HttpServerPropertiesManagerTest
, GetAlternativeServices
) {
523 ExpectScheduleUpdatePrefsOnNetworkThread();
525 HostPortPair
spdy_server_mail("mail.google.com", 80);
526 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
527 const AlternativeService
alternative_service(NPN_HTTP_2
, "mail.google.com",
529 http_server_props_manager_
->SetAlternativeService(
530 spdy_server_mail
, alternative_service
, 1.0, one_day_from_now_
);
531 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
532 http_server_props_manager_
->SetAlternativeService(
533 spdy_server_mail
, alternative_service
, 1.0, one_day_from_now_
);
536 base::RunLoop().RunUntilIdle();
537 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
539 AlternativeServiceVector alternative_service_vector
=
540 http_server_props_manager_
->GetAlternativeServices(spdy_server_mail
);
541 ASSERT_EQ(1u, alternative_service_vector
.size());
542 EXPECT_EQ(alternative_service
, alternative_service_vector
[0]);
545 TEST_F(HttpServerPropertiesManagerTest
, SetAlternativeServices
) {
547 ExpectScheduleUpdatePrefsOnNetworkThread();
549 HostPortPair
spdy_server_mail("mail.google.com", 80);
550 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
551 AlternativeServiceInfoVector alternative_service_info_vector
;
552 const AlternativeService
alternative_service1(NPN_HTTP_2
, "mail.google.com",
554 alternative_service_info_vector
.push_back(
555 AlternativeServiceInfo(alternative_service1
, 1.0, one_day_from_now_
));
556 const AlternativeService
alternative_service2(QUIC
, "mail.google.com", 1234);
557 alternative_service_info_vector
.push_back(
558 AlternativeServiceInfo(alternative_service2
, 1.0, one_day_from_now_
));
559 http_server_props_manager_
->SetAlternativeServices(
560 spdy_server_mail
, alternative_service_info_vector
);
561 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
562 http_server_props_manager_
->SetAlternativeServices(
563 spdy_server_mail
, alternative_service_info_vector
);
566 base::RunLoop().RunUntilIdle();
567 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
569 AlternativeServiceVector alternative_service_vector
=
570 http_server_props_manager_
->GetAlternativeServices(spdy_server_mail
);
571 ASSERT_EQ(2u, alternative_service_vector
.size());
572 EXPECT_EQ(alternative_service1
, alternative_service_vector
[0]);
573 EXPECT_EQ(alternative_service2
, alternative_service_vector
[1]);
576 TEST_F(HttpServerPropertiesManagerTest
, SetAlternativeServicesEmpty
) {
577 HostPortPair
spdy_server_mail("mail.google.com", 80);
578 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
579 const AlternativeService
alternative_service(NPN_HTTP_2
, "mail.google.com",
581 http_server_props_manager_
->SetAlternativeServices(
582 spdy_server_mail
, AlternativeServiceInfoVector());
583 // ExpectScheduleUpdatePrefsOnNetworkThread() should not be called.
586 base::RunLoop().RunUntilIdle();
587 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
589 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
592 TEST_F(HttpServerPropertiesManagerTest
, ClearAlternativeServices
) {
594 ExpectScheduleUpdatePrefsOnNetworkThread();
596 HostPortPair
spdy_server_mail("mail.google.com", 80);
597 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
598 AlternativeService
alternative_service(NPN_HTTP_2
, "mail.google.com", 443);
599 http_server_props_manager_
->SetAlternativeService(
600 spdy_server_mail
, alternative_service
, 1.0, one_day_from_now_
);
601 ExpectScheduleUpdatePrefsOnNetworkThread();
602 http_server_props_manager_
->ClearAlternativeServices(spdy_server_mail
);
603 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
604 http_server_props_manager_
->ClearAlternativeServices(spdy_server_mail
);
607 base::RunLoop().RunUntilIdle();
608 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
610 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
613 TEST_F(HttpServerPropertiesManagerTest
, ConfirmAlternativeService
) {
616 HostPortPair
spdy_server_mail("mail.google.com", 80);
617 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
618 AlternativeService
alternative_service(NPN_HTTP_2
, "mail.google.com", 443);
620 ExpectScheduleUpdatePrefsOnNetworkThread();
621 http_server_props_manager_
->SetAlternativeService(
622 spdy_server_mail
, alternative_service
, 1.0, one_day_from_now_
);
624 EXPECT_FALSE(http_server_props_manager_
->IsAlternativeServiceBroken(
625 alternative_service
));
626 EXPECT_FALSE(http_server_props_manager_
->WasAlternativeServiceRecentlyBroken(
627 alternative_service
));
629 ExpectScheduleUpdatePrefsOnNetworkThread();
630 http_server_props_manager_
->MarkAlternativeServiceBroken(alternative_service
);
631 EXPECT_TRUE(http_server_props_manager_
->IsAlternativeServiceBroken(
632 alternative_service
));
633 EXPECT_TRUE(http_server_props_manager_
->WasAlternativeServiceRecentlyBroken(
634 alternative_service
));
636 ExpectScheduleUpdatePrefsOnNetworkThread();
637 http_server_props_manager_
->ConfirmAlternativeService(alternative_service
);
638 EXPECT_FALSE(http_server_props_manager_
->IsAlternativeServiceBroken(
639 alternative_service
));
640 EXPECT_FALSE(http_server_props_manager_
->WasAlternativeServiceRecentlyBroken(
641 alternative_service
));
642 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
643 http_server_props_manager_
->ConfirmAlternativeService(alternative_service
);
644 EXPECT_FALSE(http_server_props_manager_
->IsAlternativeServiceBroken(
645 alternative_service
));
646 EXPECT_FALSE(http_server_props_manager_
->WasAlternativeServiceRecentlyBroken(
647 alternative_service
));
650 base::RunLoop().RunUntilIdle();
651 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
653 EXPECT_FALSE(http_server_props_manager_
->IsAlternativeServiceBroken(
654 alternative_service
));
655 EXPECT_FALSE(http_server_props_manager_
->WasAlternativeServiceRecentlyBroken(
656 alternative_service
));
659 TEST_F(HttpServerPropertiesManagerTest
, SupportsQuic
) {
661 ExpectScheduleUpdatePrefsOnNetworkThread();
663 IPAddressNumber address
;
664 EXPECT_FALSE(http_server_props_manager_
->GetSupportsQuic(&address
));
666 IPAddressNumber actual_address
;
667 CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address
));
668 http_server_props_manager_
->SetSupportsQuic(true, actual_address
);
669 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
670 http_server_props_manager_
->SetSupportsQuic(true, actual_address
);
673 base::RunLoop().RunUntilIdle();
674 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
676 EXPECT_TRUE(http_server_props_manager_
->GetSupportsQuic(&address
));
677 EXPECT_EQ(actual_address
, address
);
680 TEST_F(HttpServerPropertiesManagerTest
, ServerNetworkStats
) {
682 ExpectScheduleUpdatePrefsOnNetworkThread();
684 HostPortPair
mail_server("mail.google.com", 80);
685 const ServerNetworkStats
* stats
=
686 http_server_props_manager_
->GetServerNetworkStats(mail_server
);
687 EXPECT_EQ(NULL
, stats
);
688 ServerNetworkStats stats1
;
689 stats1
.srtt
= base::TimeDelta::FromMicroseconds(10);
690 http_server_props_manager_
->SetServerNetworkStats(mail_server
, stats1
);
691 // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
692 http_server_props_manager_
->SetServerNetworkStats(mail_server
, stats1
);
695 base::RunLoop().RunUntilIdle();
696 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
698 const ServerNetworkStats
* stats2
=
699 http_server_props_manager_
->GetServerNetworkStats(mail_server
);
700 EXPECT_EQ(10, stats2
->srtt
.ToInternalValue());
703 TEST_F(HttpServerPropertiesManagerTest
, Clear
) {
705 ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
707 HostPortPair
spdy_server_mail("mail.google.com", 443);
708 http_server_props_manager_
->SetSupportsSpdy(spdy_server_mail
, true);
709 AlternativeService
alternative_service(NPN_HTTP_2
, "mail.google.com", 1234);
710 http_server_props_manager_
->SetAlternativeService(
711 spdy_server_mail
, alternative_service
, 1.0, one_day_from_now_
);
712 IPAddressNumber actual_address
;
713 CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address
));
714 http_server_props_manager_
->SetSupportsQuic(true, actual_address
);
715 ServerNetworkStats stats
;
716 stats
.srtt
= base::TimeDelta::FromMicroseconds(10);
717 http_server_props_manager_
->SetServerNetworkStats(spdy_server_mail
, stats
);
719 const SpdySettingsIds id1
= SETTINGS_UPLOAD_BANDWIDTH
;
720 const SpdySettingsFlags flags1
= SETTINGS_FLAG_PLEASE_PERSIST
;
721 const uint32 value1
= 31337;
722 http_server_props_manager_
->SetSpdySetting(
723 spdy_server_mail
, id1
, flags1
, value1
);
726 base::RunLoop().RunUntilIdle();
729 http_server_props_manager_
->SupportsRequestPriority(spdy_server_mail
));
730 EXPECT_TRUE(HasAlternativeService(spdy_server_mail
));
731 IPAddressNumber address
;
732 EXPECT_TRUE(http_server_props_manager_
->GetSupportsQuic(&address
));
733 EXPECT_EQ(actual_address
, address
);
734 const ServerNetworkStats
* stats1
=
735 http_server_props_manager_
->GetServerNetworkStats(spdy_server_mail
);
736 EXPECT_EQ(10, stats1
->srtt
.ToInternalValue());
738 // Check SPDY settings values.
739 const SettingsMap
& settings_map1_ret
=
740 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
741 ASSERT_EQ(1U, settings_map1_ret
.size());
742 SettingsMap::const_iterator it1_ret
= settings_map1_ret
.find(id1
);
743 EXPECT_TRUE(it1_ret
!= settings_map1_ret
.end());
744 SettingsFlagsAndValue flags_and_value1_ret
= it1_ret
->second
;
745 EXPECT_EQ(SETTINGS_FLAG_PERSISTED
, flags_and_value1_ret
.first
);
746 EXPECT_EQ(value1
, flags_and_value1_ret
.second
);
748 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
752 // Clear http server data, time out if we do not get a completion callback.
753 http_server_props_manager_
->Clear(base::MessageLoop::QuitClosure());
754 base::RunLoop().Run();
757 http_server_props_manager_
->SupportsRequestPriority(spdy_server_mail
));
758 EXPECT_FALSE(HasAlternativeService(spdy_server_mail
));
759 EXPECT_FALSE(http_server_props_manager_
->GetSupportsQuic(&address
));
760 const ServerNetworkStats
* stats2
=
761 http_server_props_manager_
->GetServerNetworkStats(spdy_server_mail
);
762 EXPECT_EQ(NULL
, stats2
);
764 const SettingsMap
& settings_map2_ret
=
765 http_server_props_manager_
->GetSpdySettings(spdy_server_mail
);
766 EXPECT_EQ(0U, settings_map2_ret
.size());
768 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
771 // https://crbug.com/444956: Add 200 alternative_service servers followed by
772 // supports_quic and verify we have read supports_quic from prefs.
773 TEST_F(HttpServerPropertiesManagerTest
, BadSupportsQuic
) {
776 base::DictionaryValue
* servers_dict
= new base::DictionaryValue
;
778 for (int i
= 0; i
< 200; ++i
) {
779 // Set up alternative_service for www.google.com:i.
780 base::DictionaryValue
* alternative_service_dict
= new base::DictionaryValue
;
781 alternative_service_dict
->SetString("protocol_str", "quic");
782 alternative_service_dict
->SetInteger("port", i
);
783 base::ListValue
* alternative_service_list
= new base::ListValue
;
784 alternative_service_list
->Append(alternative_service_dict
);
785 base::DictionaryValue
* server_pref_dict
= new base::DictionaryValue
;
786 server_pref_dict
->SetWithoutPathExpansion("alternative_service",
787 alternative_service_list
);
788 servers_dict
->SetWithoutPathExpansion(StringPrintf("www.google.com:%d", i
),
792 // Set the preference for mail.google.com server.
793 base::DictionaryValue
* server_pref_dict1
= new base::DictionaryValue
;
795 // Set the server preference for mail.google.com:80.
796 servers_dict
->SetWithoutPathExpansion("mail.google.com:80",
799 base::DictionaryValue
* http_server_properties_dict
=
800 new base::DictionaryValue
;
801 HttpServerPropertiesManager::SetVersion(http_server_properties_dict
, -1);
802 http_server_properties_dict
->SetWithoutPathExpansion("servers", servers_dict
);
804 // Set up SupportsQuic for 127.0.0.1
805 base::DictionaryValue
* supports_quic
= new base::DictionaryValue
;
806 supports_quic
->SetBoolean("used_quic", true);
807 supports_quic
->SetString("address", "127.0.0.1");
808 http_server_properties_dict
->SetWithoutPathExpansion("supports_quic",
812 pref_service_
.SetManagedPref(kTestHttpServerProperties
,
813 http_server_properties_dict
);
815 base::RunLoop().RunUntilIdle();
816 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
818 // Verify alternative service.
819 for (int i
= 0; i
< 200; ++i
) {
820 std::string server
= StringPrintf("www.google.com:%d", i
);
821 AlternativeServiceVector alternative_service_vector
=
822 http_server_props_manager_
->GetAlternativeServices(
823 HostPortPair::FromString(server
));
824 ASSERT_EQ(1u, alternative_service_vector
.size());
825 EXPECT_EQ(QUIC
, alternative_service_vector
[0].protocol
);
826 EXPECT_EQ(i
, alternative_service_vector
[0].port
);
829 // Verify SupportsQuic.
830 IPAddressNumber address
;
831 ASSERT_TRUE(http_server_props_manager_
->GetSupportsQuic(&address
));
832 EXPECT_EQ("127.0.0.1", IPAddressToString(address
));
835 TEST_F(HttpServerPropertiesManagerTest
, UpdateCacheWithPrefs
) {
836 ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly();
838 const HostPortPair
server_www("www.google.com", 80);
839 const HostPortPair
server_mail("mail.google.com", 80);
841 // Set alternate protocol.
842 AlternativeServiceInfoVector alternative_service_info_vector
;
843 AlternativeService
www_alternative_service1(NPN_HTTP_2
, "", 443);
844 base::Time expiration1
= base::Time::FromDoubleT(4200000001.0);
845 alternative_service_info_vector
.push_back(
846 AlternativeServiceInfo(www_alternative_service1
, 1.0, expiration1
));
847 AlternativeService
www_alternative_service2(NPN_HTTP_2
, "www.google.com",
849 base::Time expiration2
= base::Time::FromDoubleT(4200000002.0);
850 alternative_service_info_vector
.push_back(
851 AlternativeServiceInfo(www_alternative_service2
, 0.7, expiration2
));
852 http_server_props_manager_
->SetAlternativeServices(
853 server_www
, alternative_service_info_vector
);
855 AlternativeService
mail_alternative_service(NPN_SPDY_3_1
, "foo.google.com",
857 base::Time expiration3
= base::Time::FromDoubleT(4200000003.0);
858 http_server_props_manager_
->SetAlternativeService(
859 server_mail
, mail_alternative_service
, 0.2, expiration3
);
861 // Set ServerNetworkStats.
862 ServerNetworkStats stats
;
863 stats
.srtt
= base::TimeDelta::FromInternalValue(42);
864 http_server_props_manager_
->SetServerNetworkStats(server_mail
, stats
);
867 IPAddressNumber actual_address
;
868 CHECK(ParseIPLiteralToNumber("127.0.0.1", &actual_address
));
869 http_server_props_manager_
->SetSupportsQuic(true, actual_address
);
874 http_server_props_manager_
->ScheduleUpdateCacheOnPrefThread();
875 base::RunLoop().RunUntilIdle();
877 // Verify preferences.
878 const char expected_json
[] =
879 "{\"servers\":{\"mail.google.com:80\":{\"alternative_service\":[{"
880 "\"expiration\":4200000003.0,\"host\":\"foo.google.com\",\"port\":444,"
881 "\"probability\":0.2,\"protocol_str\":\"npn-spdy/3.1\"}],"
882 "\"network_stats\":{\"srtt\":42}},\"www.google.com:80\":{"
883 "\"alternative_service\":[{\"expiration\":4200000001.0,\"port\":443,"
884 "\"probability\":1.0,\"protocol_str\":\"npn-h2\"},{\"expiration\":"
885 "4200000002.0,\"host\":\"www.google.com\",\"port\":1234,\"probability\":"
886 "0.7,\"protocol_str\":\"npn-h2\"}]}},\"supports_quic\":{\"address\":"
887 "\"127.0.0.1\",\"used_quic\":true},\"version\":3}";
889 const base::Value
* http_server_properties
=
890 pref_service_
.GetUserPref(kTestHttpServerProperties
);
891 ASSERT_NE(nullptr, http_server_properties
);
892 std::string preferences_json
;
894 base::JSONWriter::Write(*http_server_properties
, &preferences_json
));
895 EXPECT_EQ(expected_json
, preferences_json
);
898 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdateCache0
) {
899 // Post an update task to the UI thread.
900 http_server_props_manager_
->ScheduleUpdateCacheOnPrefThread();
901 // Shutdown comes before the task is executed.
902 http_server_props_manager_
->ShutdownOnPrefThread();
903 http_server_props_manager_
.reset();
904 // Run the task after shutdown and deletion.
905 base::RunLoop().RunUntilIdle();
908 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdateCache1
) {
909 // Post an update task.
910 http_server_props_manager_
->ScheduleUpdateCacheOnPrefThread();
911 // Shutdown comes before the task is executed.
912 http_server_props_manager_
->ShutdownOnPrefThread();
913 // Run the task after shutdown, but before deletion.
914 base::RunLoop().RunUntilIdle();
915 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
916 http_server_props_manager_
.reset();
917 base::RunLoop().RunUntilIdle();
920 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdateCache2
) {
921 http_server_props_manager_
->UpdateCacheFromPrefsOnUIConcrete();
922 // Shutdown comes before the task is executed.
923 http_server_props_manager_
->ShutdownOnPrefThread();
924 // Run the task after shutdown, but before deletion.
925 base::RunLoop().RunUntilIdle();
926 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
927 http_server_props_manager_
.reset();
928 base::RunLoop().RunUntilIdle();
932 // Tests for shutdown when updating prefs.
934 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdatePrefs0
) {
935 // Post an update task to the IO thread.
936 http_server_props_manager_
->ScheduleUpdatePrefsOnNetworkThread();
937 // Shutdown comes before the task is executed.
938 http_server_props_manager_
->ShutdownOnPrefThread();
939 http_server_props_manager_
.reset();
940 // Run the task after shutdown and deletion.
941 base::RunLoop().RunUntilIdle();
944 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdatePrefs1
) {
946 // Post an update task.
947 http_server_props_manager_
->ScheduleUpdatePrefsOnNetworkThread();
948 // Shutdown comes before the task is executed.
949 http_server_props_manager_
->ShutdownOnPrefThread();
950 // Run the task after shutdown, but before deletion.
951 base::RunLoop().RunUntilIdle();
952 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
953 http_server_props_manager_
.reset();
954 base::RunLoop().RunUntilIdle();
957 TEST_F(HttpServerPropertiesManagerTest
, ShutdownWithPendingUpdatePrefs2
) {
958 // This posts a task to the UI thread.
959 http_server_props_manager_
->UpdatePrefsFromCacheOnNetworkThreadConcrete(
961 // Shutdown comes before the task is executed.
962 http_server_props_manager_
->ShutdownOnPrefThread();
963 // Run the task after shutdown, but before deletion.
964 base::RunLoop().RunUntilIdle();
965 Mock::VerifyAndClearExpectations(http_server_props_manager_
.get());
966 http_server_props_manager_
.reset();
967 base::RunLoop().RunUntilIdle();