OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "chrome/browser/signin/signin_manager.h" | 9 #include "chrome/browser/signin/signin_manager.h" |
10 #include "chrome/browser/signin/signin_manager_factory.h" | 10 #include "chrome/browser/signin/signin_manager_factory.h" |
11 #include "chrome/browser/signin/token_service.h" | 11 #include "chrome/browser/signin/token_service.h" |
12 #include "chrome/browser/signin/token_service_factory.h" | 12 #include "chrome/browser/signin/token_service_factory.h" |
13 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" | 13 #include "chrome/browser/sync/glue/bookmark_data_type_controller.h" |
14 #include "chrome/browser/sync/glue/data_type_controller.h" | 14 #include "chrome/browser/sync/glue/data_type_controller.h" |
15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h" | 15 #include "chrome/browser/sync/profile_sync_components_factory_mock.h" |
16 #include "chrome/browser/sync/test_profile_sync_service.h" | 16 #include "chrome/browser/sync/test_profile_sync_service.h" |
17 #include "chrome/common/chrome_version_info.h" | 17 #include "chrome/common/chrome_version_info.h" |
18 #include "chrome/common/net/gaia/gaia_constants.h" | 18 #include "chrome/common/net/gaia/gaia_constants.h" |
19 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
20 #include "chrome/test/base/testing_pref_service.h" | 20 #include "chrome/test/base/testing_pref_service.h" |
21 #include "chrome/test/base/testing_profile.h" | 21 #include "chrome/test/base/testing_profile.h" |
22 #include "content/public/common/content_client.h" | 22 #include "content/public/common/content_client.h" |
23 #include "content/public/test/test_browser_thread.h" | 23 #include "content/public/test/test_browser_thread.h" |
24 #include "google/cacheinvalidation/include/types.h" | |
24 #include "sync/js/js_arg_list.h" | 25 #include "sync/js/js_arg_list.h" |
25 #include "sync/js/js_event_details.h" | 26 #include "sync/js/js_event_details.h" |
26 #include "sync/js/js_test_util.h" | 27 #include "sync/js/js_test_util.h" |
28 #include "sync/notifier/mock_sync_notifier_observer.h" | |
27 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
29 #include "webkit/glue/webkit_glue.h" | 31 #include "webkit/glue/webkit_glue.h" |
30 | 32 |
31 // TODO(akalin): Add tests here that exercise the whole | 33 // TODO(akalin): Add tests here that exercise the whole |
32 // ProfileSyncService/SyncBackendHost stack while mocking out as | 34 // ProfileSyncService/SyncBackendHost stack while mocking out as |
33 // little as possible. | 35 // little as possible. |
34 | 36 |
35 namespace browser_sync { | 37 namespace browser_sync { |
36 | 38 |
37 namespace { | 39 namespace { |
38 | 40 |
39 using content::BrowserThread; | 41 using content::BrowserThread; |
40 using testing::_; | 42 using testing::_; |
41 using testing::AtLeast; | 43 using testing::AtLeast; |
42 using testing::AtMost; | 44 using testing::AtMost; |
45 using testing::Mock; | |
43 using testing::Return; | 46 using testing::Return; |
44 using testing::StrictMock; | 47 using testing::StrictMock; |
45 | 48 |
46 class ProfileSyncServiceTest : public testing::Test { | 49 class ProfileSyncServiceTest : public testing::Test { |
47 protected: | 50 protected: |
48 ProfileSyncServiceTest() | 51 ProfileSyncServiceTest() |
49 : ui_thread_(BrowserThread::UI, &ui_loop_), | 52 : ui_thread_(BrowserThread::UI, &ui_loop_), |
50 db_thread_(BrowserThread::DB), | 53 db_thread_(BrowserThread::DB), |
51 file_thread_(BrowserThread::FILE), | 54 file_thread_(BrowserThread::FILE), |
52 io_thread_(BrowserThread::IO) {} | 55 io_thread_(BrowserThread::IO) {} |
(...skipping 22 matching lines...) Expand all Loading... | |
75 io_thread_.Stop(); | 78 io_thread_.Stop(); |
76 file_thread_.Stop(); | 79 file_thread_.Stop(); |
77 // Ensure that the sync objects destruct to avoid memory leaks. | 80 // Ensure that the sync objects destruct to avoid memory leaks. |
78 ui_loop_.RunAllPending(); | 81 ui_loop_.RunAllPending(); |
79 } | 82 } |
80 | 83 |
81 // TODO(akalin): Refactor the StartSyncService*() functions below. | 84 // TODO(akalin): Refactor the StartSyncService*() functions below. |
82 | 85 |
83 void StartSyncService() { | 86 void StartSyncService() { |
84 StartSyncServiceAndSetInitialSyncEnded( | 87 StartSyncServiceAndSetInitialSyncEnded( |
85 true, true, false, true, true, syncer::STORAGE_IN_MEMORY); | 88 true, true, false, true, syncer::STORAGE_IN_MEMORY); |
86 } | 89 } |
87 | 90 |
88 void StartSyncServiceAndSetInitialSyncEnded( | 91 void StartSyncServiceAndSetInitialSyncEnded( |
89 bool set_initial_sync_ended, | 92 bool set_initial_sync_ended, |
90 bool issue_auth_token, | 93 bool issue_auth_token, |
91 bool synchronous_sync_configuration, | 94 bool synchronous_sync_configuration, |
92 bool sync_setup_completed, | 95 bool sync_setup_completed, |
93 bool expect_create_dtm, | |
94 syncer::StorageOption storage_option) { | 96 syncer::StorageOption storage_option) { |
95 if (!service_.get()) { | 97 if (!service_.get()) { |
96 SigninManager* signin = | 98 SigninManager* signin = |
97 SigninManagerFactory::GetForProfile(profile_.get()); | 99 SigninManagerFactory::GetForProfile(profile_.get()); |
98 signin->SetAuthenticatedUsername("test"); | 100 signin->SetAuthenticatedUsername("test"); |
99 ProfileSyncComponentsFactoryMock* factory = | 101 ProfileSyncComponentsFactoryMock* factory = |
100 new ProfileSyncComponentsFactoryMock(); | 102 new ProfileSyncComponentsFactoryMock(); |
101 service_.reset(new TestProfileSyncService( | 103 service_.reset(new TestProfileSyncService( |
102 factory, | 104 factory, |
103 profile_.get(), | 105 profile_.get(), |
104 signin, | 106 signin, |
105 ProfileSyncService::AUTO_START, | 107 ProfileSyncService::AUTO_START, |
106 true, | 108 true, |
107 base::Closure())); | 109 base::Closure())); |
108 if (!set_initial_sync_ended) | 110 if (!set_initial_sync_ended) |
109 service_->dont_set_initial_sync_ended_on_init(); | 111 service_->dont_set_initial_sync_ended_on_init(); |
110 if (synchronous_sync_configuration) | 112 if (synchronous_sync_configuration) |
111 service_->set_synchronous_sync_configuration(); | 113 service_->set_synchronous_sync_configuration(); |
112 service_->set_storage_option(storage_option); | 114 service_->set_storage_option(storage_option); |
113 if (!sync_setup_completed) | 115 if (!sync_setup_completed) |
114 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); | 116 profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false); |
115 | 117 |
116 if (expect_create_dtm) { | 118 // Register the bookmark data type. |
117 // Register the bookmark data type. | 119 ON_CALL(*factory, CreateDataTypeManager(_, _)). |
118 EXPECT_CALL(*factory, CreateDataTypeManager(_, _)). | 120 WillByDefault(ReturnNewDataTypeManager()); |
119 WillOnce(ReturnNewDataTypeManager()); | |
120 } else { | |
121 EXPECT_CALL(*factory, CreateDataTypeManager(_, _)). | |
122 Times(0); | |
123 } | |
124 | 121 |
125 if (issue_auth_token) { | 122 if (issue_auth_token) { |
126 IssueTestTokens(); | 123 IssueTestTokens(); |
127 } | 124 } |
128 service_->Initialize(); | 125 service_->Initialize(); |
129 } | 126 } |
130 } | 127 } |
131 | 128 |
132 void IssueTestTokens() { | 129 void IssueTestTokens() { |
133 TokenService* token_service = | 130 TokenService* token_service = |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 EXPECT_TRUE(service_->GetBackendForTest() != NULL); | 242 EXPECT_TRUE(service_->GetBackendForTest() != NULL); |
246 | 243 |
247 syncer::JsController* js_controller = service_->GetJsController(); | 244 syncer::JsController* js_controller = service_->GetJsController(); |
248 StrictMock<syncer::MockJsEventHandler> event_handler; | 245 StrictMock<syncer::MockJsEventHandler> event_handler; |
249 js_controller->AddJsEventHandler(&event_handler); | 246 js_controller->AddJsEventHandler(&event_handler); |
250 js_controller->RemoveJsEventHandler(&event_handler); | 247 js_controller->RemoveJsEventHandler(&event_handler); |
251 } | 248 } |
252 | 249 |
253 TEST_F(ProfileSyncServiceTest, | 250 TEST_F(ProfileSyncServiceTest, |
254 JsControllerHandlersDelayedBackendInitialization) { | 251 JsControllerHandlersDelayedBackendInitialization) { |
255 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, true, | 252 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, |
256 syncer::STORAGE_IN_MEMORY); | 253 syncer::STORAGE_IN_MEMORY); |
257 | 254 |
258 StrictMock<syncer::MockJsEventHandler> event_handler; | 255 StrictMock<syncer::MockJsEventHandler> event_handler; |
259 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); | 256 EXPECT_CALL(event_handler, HandleJsEvent(_, _)).Times(AtLeast(1)); |
260 | 257 |
261 EXPECT_EQ(NULL, service_->GetBackendForTest()); | 258 EXPECT_EQ(NULL, service_->GetBackendForTest()); |
262 EXPECT_FALSE(service_->sync_initialized()); | 259 EXPECT_FALSE(service_->sync_initialized()); |
263 | 260 |
264 syncer::JsController* js_controller = service_->GetJsController(); | 261 syncer::JsController* js_controller = service_->GetJsController(); |
265 js_controller->AddJsEventHandler(&event_handler); | 262 js_controller->AddJsEventHandler(&event_handler); |
(...skipping 21 matching lines...) Expand all Loading... | |
287 reply_handler.AsWeakHandle()); | 284 reply_handler.AsWeakHandle()); |
288 } | 285 } |
289 | 286 |
290 // This forces the sync thread to process the message and reply. | 287 // This forces the sync thread to process the message and reply. |
291 service_.reset(); | 288 service_.reset(); |
292 ui_loop_.RunAllPending(); | 289 ui_loop_.RunAllPending(); |
293 } | 290 } |
294 | 291 |
295 TEST_F(ProfileSyncServiceTest, | 292 TEST_F(ProfileSyncServiceTest, |
296 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { | 293 JsControllerProcessJsMessageBasicDelayedBackendInitialization) { |
297 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, true, | 294 StartSyncServiceAndSetInitialSyncEnded(true, false, false, true, |
298 syncer::STORAGE_IN_MEMORY); | 295 syncer::STORAGE_IN_MEMORY); |
299 | 296 |
300 StrictMock<syncer::MockJsReplyHandler> reply_handler; | 297 StrictMock<syncer::MockJsReplyHandler> reply_handler; |
301 | 298 |
302 ListValue arg_list1; | 299 ListValue arg_list1; |
303 arg_list1.Append(Value::CreateBooleanValue(false)); | 300 arg_list1.Append(Value::CreateBooleanValue(false)); |
304 syncer::JsArgList args1(&arg_list1); | 301 syncer::JsArgList args1(&arg_list1); |
305 EXPECT_CALL(reply_handler, | 302 EXPECT_CALL(reply_handler, |
306 HandleJsReply("getNotificationState", HasArgs(args1))); | 303 HandleJsReply("getNotificationState", HasArgs(args1))); |
307 | 304 |
(...skipping 22 matching lines...) Expand all Loading... | |
330 FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); | 327 FilePath sync_file2 = temp_directory.AppendASCII("SyncData.sqlite3"); |
331 FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); | 328 FilePath sync_file3 = temp_directory.AppendASCII("nonsense_file"); |
332 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); | 329 ASSERT_TRUE(file_util::CreateDirectory(temp_directory)); |
333 ASSERT_NE(-1, | 330 ASSERT_NE(-1, |
334 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); | 331 file_util::WriteFile(sync_file1, nonsense1, strlen(nonsense1))); |
335 ASSERT_NE(-1, | 332 ASSERT_NE(-1, |
336 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); | 333 file_util::WriteFile(sync_file2, nonsense2, strlen(nonsense2))); |
337 ASSERT_NE(-1, | 334 ASSERT_NE(-1, |
338 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); | 335 file_util::WriteFile(sync_file3, nonsense3, strlen(nonsense3))); |
339 | 336 |
340 StartSyncServiceAndSetInitialSyncEnded(false, false, true, false, true, | 337 StartSyncServiceAndSetInitialSyncEnded(false, false, true, false, |
341 syncer::STORAGE_ON_DISK); | 338 syncer::STORAGE_ON_DISK); |
342 EXPECT_FALSE(service_->HasSyncSetupCompleted()); | 339 EXPECT_FALSE(service_->HasSyncSetupCompleted()); |
343 EXPECT_FALSE(service_->sync_initialized()); | 340 EXPECT_FALSE(service_->sync_initialized()); |
344 | 341 |
345 // Since we're doing synchronous initialization, backend should be | 342 // Since we're doing synchronous initialization, backend should be |
346 // initialized by this call. | 343 // initialized by this call. |
347 IssueTestTokens(); | 344 IssueTestTokens(); |
348 | 345 |
349 // Stop the service so we can read the new Sync Data files that were | 346 // Stop the service so we can read the new Sync Data files that were |
350 // created. | 347 // created. |
351 service_.reset(); | 348 service_.reset(); |
352 | 349 |
353 // This file should have been deleted when the whole directory was nuked. | 350 // This file should have been deleted when the whole directory was nuked. |
354 ASSERT_FALSE(file_util::PathExists(sync_file3)); | 351 ASSERT_FALSE(file_util::PathExists(sync_file3)); |
355 ASSERT_FALSE(file_util::PathExists(sync_file1)); | 352 ASSERT_FALSE(file_util::PathExists(sync_file1)); |
356 | 353 |
357 // This will still exist, but the text should have changed. | 354 // This will still exist, but the text should have changed. |
358 ASSERT_TRUE(file_util::PathExists(sync_file2)); | 355 ASSERT_TRUE(file_util::PathExists(sync_file2)); |
359 std::string file2text; | 356 std::string file2text; |
360 ASSERT_TRUE(file_util::ReadFileToString(sync_file2, &file2text)); | 357 ASSERT_TRUE(file_util::ReadFileToString(sync_file2, &file2text)); |
361 ASSERT_NE(file2text.compare(nonsense2), 0); | 358 ASSERT_NE(file2text.compare(nonsense2), 0); |
362 } | 359 } |
363 | 360 |
364 // Simulates a scenario where a database is corrupted and it is impossible to | 361 // Simulates a scenario where a database is corrupted and it is impossible to |
365 // recreate it. This test is useful mainly when it is run under valgrind. Its | 362 // recreate it. This test is useful mainly when it is run under valgrind. Its |
366 // expectations are not very interesting. | 363 // expectations are not very interesting. |
367 TEST_F(ProfileSyncServiceTest, FailToOpenDatabase) { | 364 TEST_F(ProfileSyncServiceTest, FailToOpenDatabase) { |
368 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, false, | 365 StartSyncServiceAndSetInitialSyncEnded(false, true, true, true, |
369 syncer::STORAGE_INVALID); | 366 syncer::STORAGE_INVALID); |
370 | 367 |
371 // The backend is not ready. Ensure the PSS knows this. | 368 // The backend is not ready. Ensure the PSS knows this. |
372 EXPECT_FALSE(service_->sync_initialized()); | 369 EXPECT_FALSE(service_->sync_initialized()); |
373 } | 370 } |
374 | 371 |
372 // Register for some IDs with the ProfileSyncService and trigger some | |
373 // invalidation messages. They should be received by the observer. | |
374 // Then unregister and trigger the invalidation messages again. Those | |
375 // shouldn't be received by the observer. | |
376 TEST_F(ProfileSyncServiceTest, UpdateRegisteredInvalidationIds) { | |
377 StartSyncService(); | |
378 | |
379 syncer::ObjectIdSet ids; | |
380 ids.insert(invalidation::ObjectId(1, "id1")); | |
381 ids.insert(invalidation::ObjectId(2, "id2")); | |
382 const syncer::ObjectIdPayloadMap& payloads = | |
383 syncer::ObjectIdSetToPayloadMap(ids, "payload"); | |
384 | |
385 StrictMock<syncer::MockSyncNotifierObserver> observer; | |
386 EXPECT_CALL(observer, OnNotificationsEnabled()); | |
387 EXPECT_CALL(observer, OnNotificationsDisabled( | |
388 syncer::TRANSIENT_NOTIFICATION_ERROR)); | |
389 EXPECT_CALL(observer, OnIncomingNotification( | |
390 payloads, syncer::REMOTE_NOTIFICATION)); | |
391 | |
392 service_->UpdateRegisteredInvalidationIds(&observer, ids); | |
393 | |
394 SyncBackendHostForProfileSyncTest* const backend = | |
395 service_->GetBackendForTest(); | |
396 | |
397 backend->EmitOnNotificationsEnabled(); | |
398 backend->EmitOnNotificationsDisabled(syncer::TRANSIENT_NOTIFICATION_ERROR); | |
399 backend->EmitOnIncomingNotification(payloads, syncer::REMOTE_NOTIFICATION); | |
msw
2012/08/03 05:14:21
nit: It seems odd to test emitting notifications a
| |
400 | |
401 Mock::VerifyAndClearExpectations(&observer); | |
402 | |
403 service_->UpdateRegisteredInvalidationIds(&observer, syncer::ObjectIdSet()); | |
404 | |
405 backend->EmitOnNotificationsEnabled(); | |
406 backend->EmitOnNotificationsDisabled(syncer::TRANSIENT_NOTIFICATION_ERROR); | |
407 backend->EmitOnIncomingNotification(payloads, syncer::REMOTE_NOTIFICATION); | |
408 } | |
409 | |
410 // Register for some IDs with the ProfileSyncService, restart sync, | |
411 // and trigger some invalidation messages. They should still be | |
412 // received by the observer. | |
413 TEST_F(ProfileSyncServiceTest, UpdateRegisteredInvalidationIdsPersistence) { | |
414 StartSyncService(); | |
415 | |
416 StrictMock<syncer::MockSyncNotifierObserver> observer; | |
417 EXPECT_CALL(observer, OnNotificationsEnabled()); | |
msw
2012/08/03 05:14:21
Perhaps I'm confused, but this test doesn't appear
| |
418 | |
419 syncer::ObjectIdSet ids; | |
420 ids.insert(invalidation::ObjectId(3, "id3")); | |
421 service_->UpdateRegisteredInvalidationIds(&observer, ids); | |
422 | |
423 service_->StopAndSuppress(); | |
424 service_->UnsuppressAndStart(); | |
425 | |
426 service_->GetBackendForTest()->EmitOnNotificationsEnabled(); | |
427 } | |
428 | |
375 } // namespace | 429 } // namespace |
376 } // namespace browser_sync | 430 } // namespace browser_sync |
OLD | NEW |