Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / net / http_server_properties_manager_unittest.cc
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.
4
5 #include "chrome/browser/net/http_server_properties_manager.h"
6
7 #include "base/basictypes.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/values.h"
12 #include "chrome/common/pref_names.h"
13 #include "content/public/test/test_browser_thread.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "url/gurl.h"
17
18 namespace chrome_browser_net {
19
20 namespace {
21
22 using ::testing::_;
23 using ::testing::Invoke;
24 using ::testing::Mock;
25 using ::testing::StrictMock;
26 using content::BrowserThread;
27
28 class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
29  public:
30   explicit TestingHttpServerPropertiesManager(PrefService* pref_service)
31       : HttpServerPropertiesManager(pref_service) {
32     InitializeOnIOThread();
33   }
34
35   virtual ~TestingHttpServerPropertiesManager() {
36   }
37
38   // Make these methods public for testing.
39   using HttpServerPropertiesManager::ScheduleUpdateCacheOnUI;
40   using HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO;
41
42   // Post tasks without a delay during tests.
43   virtual void StartPrefsUpdateTimerOnIO(base::TimeDelta delay) OVERRIDE {
44     HttpServerPropertiesManager::StartPrefsUpdateTimerOnIO(
45         base::TimeDelta());
46   }
47
48   void UpdateCacheFromPrefsOnUIConcrete() {
49     HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI();
50   }
51
52   // Post tasks without a delay during tests.
53   virtual void StartCacheUpdateTimerOnUI(base::TimeDelta delay) OVERRIDE {
54     HttpServerPropertiesManager::StartCacheUpdateTimerOnUI(
55         base::TimeDelta());
56   }
57
58   void UpdatePrefsFromCacheOnIOConcrete(const base::Closure& callback) {
59     HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO(callback);
60   }
61
62   MOCK_METHOD0(UpdateCacheFromPrefsOnUI, void());
63   MOCK_METHOD1(UpdatePrefsFromCacheOnIO, void(const base::Closure&));
64   MOCK_METHOD5(UpdateCacheFromPrefsOnIO,
65                void(std::vector<std::string>* spdy_servers,
66                     net::SpdySettingsMap* spdy_settings_map,
67                     net::AlternateProtocolMap* alternate_protocol_map,
68                     net::AlternateProtocolExperiment experiment,
69                     bool detected_corrupted_prefs));
70   MOCK_METHOD3(UpdatePrefsOnUI,
71                void(base::ListValue* spdy_server_list,
72                     net::SpdySettingsMap* spdy_settings_map,
73                     net::AlternateProtocolMap* alternate_protocol_map));
74
75  private:
76   DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
77 };
78
79 class HttpServerPropertiesManagerTest : public testing::Test {
80  protected:
81   HttpServerPropertiesManagerTest()
82       : ui_thread_(BrowserThread::UI, &loop_),
83         io_thread_(BrowserThread::IO, &loop_) {
84   }
85
86   virtual void SetUp() OVERRIDE {
87     pref_service_.registry()->RegisterDictionaryPref(
88         prefs::kHttpServerProperties);
89     http_server_props_manager_.reset(
90         new StrictMock<TestingHttpServerPropertiesManager>(&pref_service_));
91     ExpectCacheUpdate();
92     loop_.RunUntilIdle();
93   }
94
95   virtual void TearDown() OVERRIDE {
96     if (http_server_props_manager_.get())
97       http_server_props_manager_->ShutdownOnUIThread();
98     loop_.RunUntilIdle();
99     // Delete |http_server_props_manager_| while |io_thread_| is mapping IO to
100     // |loop_|.
101     http_server_props_manager_.reset();
102   }
103
104   void ExpectCacheUpdate() {
105     EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefsOnUI())
106         .WillOnce(
107             Invoke(http_server_props_manager_.get(),
108                    &TestingHttpServerPropertiesManager::
109                    UpdateCacheFromPrefsOnUIConcrete));
110   }
111
112   void ExpectPrefsUpdate() {
113     EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCacheOnIO(_))
114         .WillOnce(
115             Invoke(http_server_props_manager_.get(),
116                    &TestingHttpServerPropertiesManager::
117                    UpdatePrefsFromCacheOnIOConcrete));
118   }
119
120   void ExpectPrefsUpdateRepeatedly() {
121     EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCacheOnIO(_))
122         .WillRepeatedly(
123             Invoke(http_server_props_manager_.get(),
124                    &TestingHttpServerPropertiesManager::
125                    UpdatePrefsFromCacheOnIOConcrete));
126   }
127
128   base::MessageLoop loop_;
129   TestingPrefServiceSimple pref_service_;
130   scoped_ptr<TestingHttpServerPropertiesManager> http_server_props_manager_;
131
132  private:
133   content::TestBrowserThread ui_thread_;
134   content::TestBrowserThread io_thread_;
135
136   DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
137 };
138
139 TEST_F(HttpServerPropertiesManagerTest,
140        SingleUpdateForTwoSpdyServerPrefChanges) {
141   ExpectCacheUpdate();
142
143   // Set up the prefs for www.google.com:80 and mail.google.com:80 and then set
144   // it twice. Only expect a single cache update.
145
146   base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
147
148   // Set supports_spdy for www.google.com:80.
149   server_pref_dict->SetBoolean("supports_spdy", true);
150
151   // Set up alternate_protocol for www.google.com:80.
152   base::DictionaryValue* alternate_protocol = new base::DictionaryValue;
153   alternate_protocol->SetInteger("port", 443);
154   alternate_protocol->SetString("protocol_str", "npn-spdy/3");
155   server_pref_dict->SetWithoutPathExpansion(
156       "alternate_protocol", alternate_protocol);
157
158   // Set the server preference for www.google.com:80.
159   base::DictionaryValue* servers_dict = new base::DictionaryValue;
160   servers_dict->SetWithoutPathExpansion(
161       "www.google.com:80", server_pref_dict);
162
163   // Set the preference for mail.google.com server.
164   base::DictionaryValue* server_pref_dict1 = new base::DictionaryValue;
165
166   // Set supports_spdy for mail.google.com:80
167   server_pref_dict1->SetBoolean("supports_spdy", true);
168
169   // Set up alternate_protocol for mail.google.com:80
170   base::DictionaryValue* alternate_protocol1 = new base::DictionaryValue;
171   alternate_protocol1->SetInteger("port", 444);
172   alternate_protocol1->SetString("protocol_str", "npn-spdy/3.1");
173
174   server_pref_dict1->SetWithoutPathExpansion(
175       "alternate_protocol", alternate_protocol1);
176
177   // Set the server preference for mail.google.com:80.
178   servers_dict->SetWithoutPathExpansion(
179       "mail.google.com:80", server_pref_dict1);
180
181   base::DictionaryValue* http_server_properties_dict =
182       new base::DictionaryValue;
183   HttpServerPropertiesManager::SetVersion(http_server_properties_dict, -1);
184   http_server_properties_dict->SetWithoutPathExpansion("servers", servers_dict);
185
186   // Set the same value for kHttpServerProperties multiple times.
187   pref_service_.SetManagedPref(prefs::kHttpServerProperties,
188                                http_server_properties_dict);
189   base::DictionaryValue* http_server_properties_dict2 =
190       http_server_properties_dict->DeepCopy();
191   pref_service_.SetManagedPref(prefs::kHttpServerProperties,
192                                http_server_properties_dict2);
193
194   loop_.RunUntilIdle();
195   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
196
197   // Verify SupportsSpdy.
198   EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(
199       net::HostPortPair::FromString("www.google.com:80")));
200   EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(
201       net::HostPortPair::FromString("mail.google.com:80")));
202   EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(
203       net::HostPortPair::FromString("foo.google.com:1337")));
204
205   // Verify AlternateProtocol.
206   ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(
207       net::HostPortPair::FromString("www.google.com:80")));
208   ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(
209       net::HostPortPair::FromString("mail.google.com:80")));
210   net::PortAlternateProtocolPair port_alternate_protocol =
211       http_server_props_manager_->GetAlternateProtocol(
212           net::HostPortPair::FromString("www.google.com:80"));
213   EXPECT_EQ(443, port_alternate_protocol.port);
214   EXPECT_EQ(net::NPN_SPDY_3, port_alternate_protocol.protocol);
215   port_alternate_protocol =
216       http_server_props_manager_->GetAlternateProtocol(
217           net::HostPortPair::FromString("mail.google.com:80"));
218   EXPECT_EQ(444, port_alternate_protocol.port);
219   EXPECT_EQ(net::NPN_SPDY_3_1, port_alternate_protocol.protocol);
220 }
221
222 TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
223   ExpectPrefsUpdate();
224
225   // Post an update task to the IO thread. SetSupportsSpdy calls
226   // ScheduleUpdatePrefsOnIO.
227
228   // Add mail.google.com:443 as a supporting spdy server.
229   net::HostPortPair spdy_server_mail("mail.google.com", 443);
230   EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
231   http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true);
232
233   // Run the task.
234   loop_.RunUntilIdle();
235
236   EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
237   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
238 }
239
240 TEST_F(HttpServerPropertiesManagerTest, SetSpdySetting) {
241   ExpectPrefsUpdate();
242
243   // Add SpdySetting for mail.google.com:443.
244   net::HostPortPair spdy_server_mail("mail.google.com", 443);
245   const net::SpdySettingsIds id1 = net::SETTINGS_UPLOAD_BANDWIDTH;
246   const net::SpdySettingsFlags flags1 = net::SETTINGS_FLAG_PLEASE_PERSIST;
247   const uint32 value1 = 31337;
248   http_server_props_manager_->SetSpdySetting(
249       spdy_server_mail, id1, flags1, value1);
250
251   // Run the task.
252   loop_.RunUntilIdle();
253
254   const net::SettingsMap& settings_map1_ret =
255       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
256   ASSERT_EQ(1U, settings_map1_ret.size());
257   net::SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1);
258   EXPECT_TRUE(it1_ret != settings_map1_ret.end());
259   net::SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second;
260   EXPECT_EQ(net::SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first);
261   EXPECT_EQ(value1, flags_and_value1_ret.second);
262
263   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
264 }
265
266 TEST_F(HttpServerPropertiesManagerTest, ClearSpdySetting) {
267   ExpectPrefsUpdateRepeatedly();
268
269   // Add SpdySetting for mail.google.com:443.
270   net::HostPortPair spdy_server_mail("mail.google.com", 443);
271   const net::SpdySettingsIds id1 = net::SETTINGS_UPLOAD_BANDWIDTH;
272   const net::SpdySettingsFlags flags1 = net::SETTINGS_FLAG_PLEASE_PERSIST;
273   const uint32 value1 = 31337;
274   http_server_props_manager_->SetSpdySetting(
275       spdy_server_mail, id1, flags1, value1);
276
277   // Run the task.
278   loop_.RunUntilIdle();
279
280   const net::SettingsMap& settings_map1_ret =
281       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
282   ASSERT_EQ(1U, settings_map1_ret.size());
283   net::SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1);
284   EXPECT_TRUE(it1_ret != settings_map1_ret.end());
285   net::SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second;
286   EXPECT_EQ(net::SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first);
287   EXPECT_EQ(value1, flags_and_value1_ret.second);
288
289   // Clear SpdySetting for mail.google.com:443.
290   http_server_props_manager_->ClearSpdySettings(spdy_server_mail);
291
292   // Run the task.
293   loop_.RunUntilIdle();
294
295   // Verify that there are no entries in the settings map for
296   // mail.google.com:443.
297   const net::SettingsMap& settings_map2_ret =
298       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
299   ASSERT_EQ(0U, settings_map2_ret.size());
300
301   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
302 }
303
304 TEST_F(HttpServerPropertiesManagerTest, ClearAllSpdySetting) {
305   ExpectPrefsUpdateRepeatedly();
306
307   // Add SpdySetting for mail.google.com:443.
308   net::HostPortPair spdy_server_mail("mail.google.com", 443);
309   const net::SpdySettingsIds id1 = net::SETTINGS_UPLOAD_BANDWIDTH;
310   const net::SpdySettingsFlags flags1 = net::SETTINGS_FLAG_PLEASE_PERSIST;
311   const uint32 value1 = 31337;
312   http_server_props_manager_->SetSpdySetting(
313       spdy_server_mail, id1, flags1, value1);
314
315   // Run the task.
316   loop_.RunUntilIdle();
317
318   const net::SettingsMap& settings_map1_ret =
319       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
320   ASSERT_EQ(1U, settings_map1_ret.size());
321   net::SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1);
322   EXPECT_TRUE(it1_ret != settings_map1_ret.end());
323   net::SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second;
324   EXPECT_EQ(net::SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first);
325   EXPECT_EQ(value1, flags_and_value1_ret.second);
326
327   // Clear All SpdySettings.
328   http_server_props_manager_->ClearAllSpdySettings();
329
330   // Run the task.
331   loop_.RunUntilIdle();
332
333   // Verify that there are no entries in the settings map.
334   const net::SpdySettingsMap& spdy_settings_map2_ret =
335       http_server_props_manager_->spdy_settings_map();
336   ASSERT_EQ(0U, spdy_settings_map2_ret.size());
337
338   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
339 }
340
341 TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) {
342   ExpectPrefsUpdate();
343
344   net::HostPortPair spdy_server_mail("mail.google.com", 80);
345   EXPECT_FALSE(
346       http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
347   http_server_props_manager_->SetAlternateProtocol(
348       spdy_server_mail, 443, net::NPN_SPDY_3);
349
350   // Run the task.
351   loop_.RunUntilIdle();
352   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
353
354   ASSERT_TRUE(
355       http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
356   net::PortAlternateProtocolPair port_alternate_protocol =
357       http_server_props_manager_->GetAlternateProtocol(spdy_server_mail);
358   EXPECT_EQ(443, port_alternate_protocol.port);
359   EXPECT_EQ(net::NPN_SPDY_3, port_alternate_protocol.protocol);
360 }
361
362 TEST_F(HttpServerPropertiesManagerTest, Clear) {
363   ExpectPrefsUpdate();
364
365   net::HostPortPair spdy_server_mail("mail.google.com", 443);
366   http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true);
367   http_server_props_manager_->SetAlternateProtocol(
368       spdy_server_mail, 443, net::NPN_SPDY_3);
369
370   const net::SpdySettingsIds id1 = net::SETTINGS_UPLOAD_BANDWIDTH;
371   const net::SpdySettingsFlags flags1 = net::SETTINGS_FLAG_PLEASE_PERSIST;
372   const uint32 value1 = 31337;
373   http_server_props_manager_->SetSpdySetting(
374       spdy_server_mail, id1, flags1, value1);
375
376   // Run the task.
377   loop_.RunUntilIdle();
378
379   EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
380   EXPECT_TRUE(
381       http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
382
383   // Check SPDY settings values.
384   const net::SettingsMap& settings_map1_ret =
385       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
386   ASSERT_EQ(1U, settings_map1_ret.size());
387   net::SettingsMap::const_iterator it1_ret = settings_map1_ret.find(id1);
388   EXPECT_TRUE(it1_ret != settings_map1_ret.end());
389   net::SettingsFlagsAndValue flags_and_value1_ret = it1_ret->second;
390   EXPECT_EQ(net::SETTINGS_FLAG_PERSISTED, flags_and_value1_ret.first);
391   EXPECT_EQ(value1, flags_and_value1_ret.second);
392
393   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
394
395   ExpectPrefsUpdate();
396
397   // Clear http server data, time out if we do not get a completion callback.
398   http_server_props_manager_->Clear(base::MessageLoop::QuitClosure());
399   loop_.Run();
400
401   EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
402   EXPECT_FALSE(
403       http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
404
405   const net::SettingsMap& settings_map2_ret =
406       http_server_props_manager_->GetSpdySettings(spdy_server_mail);
407   EXPECT_EQ(0U, settings_map2_ret.size());
408
409   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
410 }
411
412 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
413   // Post an update task to the UI thread.
414   http_server_props_manager_->ScheduleUpdateCacheOnUI();
415   // Shutdown comes before the task is executed.
416   http_server_props_manager_->ShutdownOnUIThread();
417   http_server_props_manager_.reset();
418   // Run the task after shutdown and deletion.
419   loop_.RunUntilIdle();
420 }
421
422 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
423   // Post an update task.
424   http_server_props_manager_->ScheduleUpdateCacheOnUI();
425   // Shutdown comes before the task is executed.
426   http_server_props_manager_->ShutdownOnUIThread();
427   // Run the task after shutdown, but before deletion.
428   loop_.RunUntilIdle();
429   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
430   http_server_props_manager_.reset();
431   loop_.RunUntilIdle();
432 }
433
434 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
435   http_server_props_manager_->UpdateCacheFromPrefsOnUIConcrete();
436   // Shutdown comes before the task is executed.
437   http_server_props_manager_->ShutdownOnUIThread();
438   // Run the task after shutdown, but before deletion.
439   loop_.RunUntilIdle();
440   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
441   http_server_props_manager_.reset();
442   loop_.RunUntilIdle();
443 }
444
445 //
446 // Tests for shutdown when updating prefs.
447 //
448 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
449   // Post an update task to the IO thread.
450   http_server_props_manager_->ScheduleUpdatePrefsOnIO();
451   // Shutdown comes before the task is executed.
452   http_server_props_manager_->ShutdownOnUIThread();
453   http_server_props_manager_.reset();
454   // Run the task after shutdown and deletion.
455   loop_.RunUntilIdle();
456 }
457
458 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
459   ExpectPrefsUpdate();
460   // Post an update task.
461   http_server_props_manager_->ScheduleUpdatePrefsOnIO();
462   // Shutdown comes before the task is executed.
463   http_server_props_manager_->ShutdownOnUIThread();
464   // Run the task after shutdown, but before deletion.
465   loop_.RunUntilIdle();
466   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
467   http_server_props_manager_.reset();
468   loop_.RunUntilIdle();
469 }
470
471 TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) {
472   // This posts a task to the UI thread.
473   http_server_props_manager_->UpdatePrefsFromCacheOnIOConcrete(base::Closure());
474   // Shutdown comes before the task is executed.
475   http_server_props_manager_->ShutdownOnUIThread();
476   // Run the task after shutdown, but before deletion.
477   loop_.RunUntilIdle();
478   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
479   http_server_props_manager_.reset();
480   loop_.RunUntilIdle();
481 }
482
483 }  // namespace
484
485 }  // namespace chrome_browser_net