Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / chrome / browser / sync / glue / sync_backend_host_impl_unittest.cc
blob01a587fb4c9954582d05b40a54d9c9db349c1cd3
1 // Copyright 2013 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 "chrome/browser/sync/glue/sync_backend_host_impl.h"
7 #include <cstddef>
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/test/test_timeouts.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h"
17 #include "chrome/test/base/testing_browser_process.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "chrome/test/base/testing_profile_manager.h"
20 #include "components/invalidation/impl/invalidator_storage.h"
21 #include "components/invalidation/impl/profile_invalidation_provider.h"
22 #include "components/invalidation/public/invalidator_state.h"
23 #include "components/invalidation/public/object_id_invalidation_map.h"
24 #include "components/sync_driver/device_info.h"
25 #include "components/sync_driver/sync_frontend.h"
26 #include "components/sync_driver/sync_prefs.h"
27 #include "components/syncable_prefs/pref_service_syncable.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "content/public/test/test_utils.h"
31 #include "google/cacheinvalidation/include/types.h"
32 #include "google_apis/gaia/gaia_constants.h"
33 #include "net/url_request/test_url_fetcher_factory.h"
34 #include "sync/internal_api/public/base/model_type.h"
35 #include "sync/internal_api/public/engine/model_safe_worker.h"
36 #include "sync/internal_api/public/http_bridge_network_resources.h"
37 #include "sync/internal_api/public/network_resources.h"
38 #include "sync/internal_api/public/sessions/commit_counters.h"
39 #include "sync/internal_api/public/sessions/status_counters.h"
40 #include "sync/internal_api/public/sessions/update_counters.h"
41 #include "sync/internal_api/public/sync_manager_factory.h"
42 #include "sync/internal_api/public/test/fake_sync_manager.h"
43 #include "sync/internal_api/public/util/experiments.h"
44 #include "sync/protocol/encryption.pb.h"
45 #include "sync/protocol/sync_protocol_error.h"
46 #include "sync/test/callback_counter.h"
47 #include "sync/util/test_unrecoverable_error_handler.h"
48 #include "testing/gmock/include/gmock/gmock.h"
49 #include "testing/gtest/include/gtest/gtest.h"
50 #include "url/gurl.h"
52 using content::BrowserThread;
53 using syncer::FakeSyncManager;
54 using syncer::SyncManager;
55 using ::testing::InvokeWithoutArgs;
56 using ::testing::StrictMock;
57 using ::testing::_;
59 namespace browser_sync {
61 namespace {
63 const char kTestProfileName[] = "test-profile";
65 static const base::FilePath::CharType kTestSyncDir[] =
66 FILE_PATH_LITERAL("sync-test");
68 ACTION_P(Signal, event) {
69 event->Signal();
72 void QuitMessageLoop() {
73 base::MessageLoop::current()->Quit();
76 class MockSyncFrontend : public sync_driver::SyncFrontend {
77 public:
78 virtual ~MockSyncFrontend() {}
80 MOCK_METHOD4(
81 OnBackendInitialized,
82 void(const syncer::WeakHandle<syncer::JsBackend>&,
83 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&,
84 const std::string&,
85 bool));
86 MOCK_METHOD0(OnSyncCycleCompleted, void());
87 MOCK_METHOD1(OnConnectionStatusChange,
88 void(syncer::ConnectionStatus status));
89 MOCK_METHOD0(OnClearServerDataSucceeded, void());
90 MOCK_METHOD0(OnClearServerDataFailed, void());
91 MOCK_METHOD2(OnPassphraseRequired,
92 void(syncer::PassphraseRequiredReason,
93 const sync_pb::EncryptedData&));
94 MOCK_METHOD0(OnPassphraseAccepted, void());
95 MOCK_METHOD2(OnEncryptedTypesChanged,
96 void(syncer::ModelTypeSet, bool));
97 MOCK_METHOD0(OnEncryptionComplete, void());
98 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
99 MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&));
100 MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated,
101 void(syncer::ModelType, const syncer::CommitCounters&));
102 MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated,
103 void(syncer::ModelType, const syncer::UpdateCounters&));
104 MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated,
105 void(syncer::ModelType, const syncer::StatusCounters&));
106 MOCK_METHOD1(OnExperimentsChanged,
107 void(const syncer::Experiments&));
108 MOCK_METHOD1(OnActionableError,
109 void(const syncer::SyncProtocolError& sync_error));
110 MOCK_METHOD0(OnSyncConfigureRetry, void());
111 MOCK_METHOD1(
112 OnLocalSetPassphraseEncryption,
113 void(const syncer::SyncEncryptionHandler::NigoriState& nigori_state));
116 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
117 public:
118 explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager)
119 : SyncManagerFactory(NORMAL),
120 fake_manager_(fake_manager) {
121 *fake_manager_ = NULL;
123 ~FakeSyncManagerFactory() override {}
125 // SyncManagerFactory implementation. Called on the sync thread.
126 scoped_ptr<SyncManager> CreateSyncManager(std::string name) override {
127 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
128 progress_marker_types_,
129 configure_fail_types_);
130 return scoped_ptr<SyncManager>(*fake_manager_);
133 void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
134 initial_sync_ended_types_ = types;
137 void set_progress_marker_types(syncer::ModelTypeSet types) {
138 progress_marker_types_ = types;
141 void set_configure_fail_types(syncer::ModelTypeSet types) {
142 configure_fail_types_ = types;
145 private:
146 syncer::ModelTypeSet initial_sync_ended_types_;
147 syncer::ModelTypeSet progress_marker_types_;
148 syncer::ModelTypeSet configure_fail_types_;
149 FakeSyncManager** fake_manager_;
152 class SyncBackendHostTest : public testing::Test {
153 protected:
154 SyncBackendHostTest()
155 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
156 profile_manager_(TestingBrowserProcess::GetGlobal()),
157 fake_manager_(NULL) {}
159 ~SyncBackendHostTest() override {}
161 void SetUp() override {
162 ASSERT_TRUE(profile_manager_.SetUp());
163 profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
164 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
165 backend_.reset(new SyncBackendHostImpl(
166 profile_->GetDebugName(), profile_,
167 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
168 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
169 profile_)
170 ->GetInvalidationService(),
171 sync_prefs_->AsWeakPtr(), base::FilePath(kTestSyncDir)));
172 credentials_.email = "user@example.com";
173 credentials_.sync_token = "sync_token";
174 credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope);
176 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
178 // These types are always implicitly enabled.
179 enabled_types_.PutAll(syncer::ControlTypes());
181 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
182 // Registrar removing them if it can't find their model workers.
183 enabled_types_.Put(syncer::BOOKMARKS);
184 enabled_types_.Put(syncer::PREFERENCES);
185 enabled_types_.Put(syncer::SESSIONS);
186 enabled_types_.Put(syncer::SEARCH_ENGINES);
187 enabled_types_.Put(syncer::AUTOFILL);
189 network_resources_.reset(new syncer::HttpBridgeNetworkResources());
192 void TearDown() override {
193 if (backend_) {
194 backend_->StopSyncingForShutdown();
195 backend_->Shutdown(syncer::STOP_SYNC);
197 backend_.reset();
198 sync_prefs_.reset();
199 profile_ = NULL;
200 profile_manager_.DeleteTestingProfile(kTestProfileName);
201 // Pump messages posted by the sync thread (which may end up
202 // posting on the IO thread).
203 base::RunLoop().RunUntilIdle();
204 content::RunAllPendingInMessageLoop(BrowserThread::IO);
205 // Pump any messages posted by the IO thread.
206 base::RunLoop().RunUntilIdle();
209 // Synchronously initializes the backend.
210 void InitializeBackend(bool expect_success) {
211 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)).
212 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
213 backend_->Initialize(
214 &mock_frontend_, scoped_ptr<base::Thread>(),
215 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
216 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
217 syncer::WeakHandle<syncer::JsEventHandler>(), GURL(std::string()),
218 std::string(), credentials_, true, fake_manager_factory_.Pass(),
219 MakeWeakHandle(test_unrecoverable_error_handler_.GetWeakPtr()),
220 base::Closure(), network_resources_.get(), saved_nigori_state_.Pass());
221 base::RunLoop run_loop;
222 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
223 run_loop.QuitClosure(),
224 TestTimeouts::action_timeout());
225 run_loop.Run();
226 // |fake_manager_factory_|'s fake_manager() is set on the sync
227 // thread, but we can rely on the message loop barriers to
228 // guarantee that we see the updated value.
229 DCHECK(fake_manager_);
232 // Synchronously configures the backend's datatypes.
233 syncer::ModelTypeSet ConfigureDataTypes(
234 syncer::ModelTypeSet types_to_add,
235 syncer::ModelTypeSet types_to_remove,
236 syncer::ModelTypeSet types_to_unapply) {
237 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
238 config_state_map;
239 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
240 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
241 types_to_add,
242 &config_state_map);
243 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
244 sync_driver::BackendDataTypeConfigurer::DISABLED,
245 types_to_remove, &config_state_map);
246 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
247 sync_driver::BackendDataTypeConfigurer::UNREADY,
248 types_to_unapply, &config_state_map);
250 types_to_add.PutAll(syncer::ControlTypes());
251 syncer::ModelTypeSet ready_types = backend_->ConfigureDataTypes(
252 syncer::CONFIGURE_REASON_RECONFIGURATION, config_state_map,
253 base::Bind(&SyncBackendHostTest::DownloadReady, base::Unretained(this)),
254 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
255 base::Unretained(this)));
256 base::RunLoop run_loop;
257 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
258 run_loop.QuitClosure(),
259 TestTimeouts::action_timeout());
260 run_loop.Run();
261 return ready_types;
264 void IssueRefreshRequest(syncer::ModelTypeSet types) {
265 DCHECK_CURRENTLY_ON(BrowserThread::UI);
267 content::NotificationService::current()->Notify(
268 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
269 content::Source<Profile>(profile_),
270 content::Details<syncer::ModelTypeSet>(&types));
273 protected:
274 void DownloadReady(syncer::ModelTypeSet succeeded_types,
275 syncer::ModelTypeSet failed_types) {
276 base::MessageLoop::current()->Quit();
279 void OnDownloadRetry() {
280 NOTIMPLEMENTED();
283 content::TestBrowserThreadBundle thread_bundle_;
284 StrictMock<MockSyncFrontend> mock_frontend_;
285 syncer::SyncCredentials credentials_;
286 TestingProfileManager profile_manager_;
287 TestingProfile* profile_;
288 syncer::TestUnrecoverableErrorHandler test_unrecoverable_error_handler_;
289 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
290 scoped_ptr<SyncBackendHostImpl> backend_;
291 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
292 FakeSyncManager* fake_manager_;
293 syncer::ModelTypeSet enabled_types_;
294 scoped_ptr<syncer::NetworkResources> network_resources_;
295 scoped_ptr<syncer::SyncEncryptionHandler::NigoriState> saved_nigori_state_;
298 // Test basic initialization with no initial types (first time initialization).
299 // Only the nigori should be configured.
300 TEST_F(SyncBackendHostTest, InitShutdown) {
301 InitializeBackend(true);
302 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
303 syncer::ControlTypes()));
304 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
305 syncer::ControlTypes()));
306 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
307 syncer::ControlTypes()).Empty());
310 // Test first time sync scenario. All types should be properly configured.
311 TEST_F(SyncBackendHostTest, FirstTimeSync) {
312 InitializeBackend(true);
313 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
314 syncer::ControlTypes()));
315 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
316 syncer::ControlTypes()));
317 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
318 syncer::ControlTypes()).Empty());
320 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
321 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
322 syncer::ModelTypeSet());
323 // Nigori is always downloaded so won't be ready.
324 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
325 syncer::ControlTypes(),
326 syncer::ModelTypeSet(syncer::NIGORI))));
327 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
328 Difference(enabled_types_, syncer::ControlTypes())));
329 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
330 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
331 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
332 enabled_types_).Empty());
335 // Test the restart after setting up sync scenario. No enabled types should be
336 // downloaded or cleaned.
337 TEST_F(SyncBackendHostTest, Restart) {
338 sync_prefs_->SetSyncSetupCompleted();
339 syncer::ModelTypeSet all_but_nigori = enabled_types_;
340 fake_manager_factory_->set_progress_marker_types(enabled_types_);
341 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
342 InitializeBackend(true);
343 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
344 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
345 enabled_types_).Empty());
346 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
347 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
348 enabled_types_).Empty());
350 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
351 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
352 syncer::ModelTypeSet());
353 EXPECT_TRUE(ready_types.Equals(enabled_types_));
354 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
355 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
356 enabled_types_).Empty());
357 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
358 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
359 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
360 enabled_types_).Empty());
363 // Test a sync restart scenario where some types had never finished configuring.
364 // The partial types should be purged, then reconfigured properly.
365 TEST_F(SyncBackendHostTest, PartialTypes) {
366 sync_prefs_->SetSyncSetupCompleted();
367 // Set sync manager behavior before passing it down. All types have progress
368 // markers, but nigori and bookmarks are missing initial sync ended.
369 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
370 syncer::ModelTypeSet full_types =
371 Difference(enabled_types_, partial_types);
372 fake_manager_factory_->set_progress_marker_types(enabled_types_);
373 fake_manager_factory_->set_initial_sync_ended_types(full_types);
375 // Bringing up the backend should purge all partial types, then proceed to
376 // download the Nigori.
377 InitializeBackend(true);
378 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
379 syncer::ModelTypeSet(syncer::NIGORI)));
380 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
381 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
382 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
383 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
384 enabled_types_).Equals(
385 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
387 // Now do the actual configuration, which should download and apply bookmarks.
388 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
389 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
390 syncer::ModelTypeSet());
391 EXPECT_TRUE(ready_types.Equals(full_types));
392 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
393 enabled_types_).Empty());
394 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
395 partial_types));
396 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
397 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
398 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
399 enabled_types_).Empty());
402 // Test the behavior when we lose the sync db. Although we already have types
403 // enabled, we should re-download all of them because we lost their data.
404 TEST_F(SyncBackendHostTest, LostDB) {
405 sync_prefs_->SetSyncSetupCompleted();
406 // Initialization should fetch the Nigori node. Everything else should be
407 // left untouched.
408 InitializeBackend(true);
409 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
410 syncer::ModelTypeSet(syncer::ControlTypes())));
411 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
412 syncer::ModelTypeSet(syncer::ControlTypes())));
413 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
414 enabled_types_).Equals(
415 Difference(enabled_types_, syncer::ControlTypes())));
417 // The database was empty, so any cleaning is entirely optional. We want to
418 // reset this value before running the next part of the test, though.
419 fake_manager_->GetAndResetCleanedTypes();
421 // The actual configuration should redownload and apply all the enabled types.
422 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
423 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
424 syncer::ModelTypeSet());
425 // Nigori is always downloaded so won't be ready.
426 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
427 syncer::ControlTypes(),
428 syncer::ModelTypeSet(syncer::NIGORI))));
429 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
430 Difference(enabled_types_, syncer::ControlTypes())));
431 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
432 enabled_types_).Empty());
433 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
434 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
435 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
436 enabled_types_).Empty());
439 TEST_F(SyncBackendHostTest, DisableTypes) {
440 // Simulate first time sync.
441 InitializeBackend(true);
442 fake_manager_->GetAndResetCleanedTypes();
443 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
444 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
445 syncer::ModelTypeSet());
446 // Nigori is always downloaded so won't be ready.
447 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
448 syncer::ControlTypes(),
449 syncer::ModelTypeSet(syncer::NIGORI))));
450 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
451 enabled_types_));
452 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
453 enabled_types_).Empty());
454 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
455 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
456 enabled_types_).Empty());
458 // Then disable two datatypes.
459 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
460 syncer::SEARCH_ENGINES);
461 syncer::ModelTypeSet old_types = enabled_types_;
462 enabled_types_.RemoveAll(disabled_types);
463 ready_types = ConfigureDataTypes(
464 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
465 syncer::ModelTypeSet());
467 // Only those datatypes disabled should be cleaned. Nothing should be
468 // downloaded.
469 EXPECT_TRUE(ready_types.Equals(enabled_types_));
470 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
471 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
472 old_types).Equals(disabled_types));
473 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
474 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
475 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
476 enabled_types_).Empty());
479 TEST_F(SyncBackendHostTest, AddTypes) {
480 // Simulate first time sync.
481 InitializeBackend(true);
482 fake_manager_->GetAndResetCleanedTypes();
483 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
484 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
485 syncer::ModelTypeSet());
486 // Nigori is always downloaded so won't be ready.
487 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
488 syncer::ControlTypes(),
489 syncer::ModelTypeSet(syncer::NIGORI))));
490 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
491 enabled_types_));
492 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
493 enabled_types_).Empty());
494 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
495 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
496 enabled_types_).Empty());
498 // Then add two datatypes.
499 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
500 syncer::APPS);
501 enabled_types_.PutAll(new_types);
502 ready_types = ConfigureDataTypes(
503 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
504 syncer::ModelTypeSet());
506 // Only those datatypes added should be downloaded (plus nigori). Nothing
507 // should be cleaned aside from the disabled types.
508 new_types.Put(syncer::NIGORI);
509 EXPECT_TRUE(
510 ready_types.Equals(syncer::Difference(enabled_types_, new_types)));
511 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
512 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
513 enabled_types_).Empty());
514 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
515 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
516 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
517 enabled_types_).Empty());
520 // And and disable in the same configuration.
521 TEST_F(SyncBackendHostTest, AddDisableTypes) {
522 // Simulate first time sync.
523 InitializeBackend(true);
524 fake_manager_->GetAndResetCleanedTypes();
525 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
526 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
527 syncer::ModelTypeSet());
528 // Nigori is always downloaded so won't be ready.
529 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
530 syncer::ControlTypes(),
531 syncer::ModelTypeSet(syncer::NIGORI))));
532 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
533 enabled_types_));
534 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
535 enabled_types_).Empty());
536 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
537 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
538 enabled_types_).Empty());
540 // Then add two datatypes.
541 syncer::ModelTypeSet old_types = enabled_types_;
542 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
543 syncer::SEARCH_ENGINES);
544 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
545 syncer::APPS);
546 enabled_types_.PutAll(new_types);
547 enabled_types_.RemoveAll(disabled_types);
548 ready_types = ConfigureDataTypes(
549 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
550 syncer::ModelTypeSet());
552 // Only those datatypes added should be downloaded (plus nigori). Nothing
553 // should be cleaned aside from the disabled types.
554 new_types.Put(syncer::NIGORI);
555 EXPECT_TRUE(
556 ready_types.Equals(syncer::Difference(enabled_types_, new_types)));
557 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
558 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
559 old_types).Equals(disabled_types));
560 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
561 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
562 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
563 old_types).Equals(disabled_types));
566 // Test restarting the browser to newly supported datatypes. The new datatypes
567 // should be downloaded on the configuration after backend initialization.
568 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
569 sync_prefs_->SetSyncSetupCompleted();
570 // Set sync manager behavior before passing it down. All types have progress
571 // markers and initial sync ended except the new types.
572 syncer::ModelTypeSet old_types = enabled_types_;
573 fake_manager_factory_->set_progress_marker_types(old_types);
574 fake_manager_factory_->set_initial_sync_ended_types(old_types);
575 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
576 syncer::EXTENSION_SETTINGS);
577 enabled_types_.PutAll(new_types);
579 // Does nothing.
580 InitializeBackend(true);
581 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
582 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
583 old_types).Empty());
584 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
585 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
586 enabled_types_).Equals(new_types));
588 // Downloads and applies the new types (plus nigori).
589 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
590 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
591 syncer::ModelTypeSet());
593 new_types.Put(syncer::NIGORI);
594 EXPECT_TRUE(ready_types.Equals(
595 syncer::Difference(old_types, syncer::ModelTypeSet(syncer::NIGORI))));
596 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
597 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
598 enabled_types_).Empty());
599 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
600 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
601 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
602 enabled_types_).Empty());
605 // Test the newly supported types scenario, but with the presence of partial
606 // types as well. Both partial and newly supported types should be downloaded
607 // the configuration.
608 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
609 sync_prefs_->SetSyncSetupCompleted();
610 // Set sync manager behavior before passing it down. All types have progress
611 // markers and initial sync ended except the new types.
612 syncer::ModelTypeSet old_types = enabled_types_;
613 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
614 syncer::ModelTypeSet full_types =
615 Difference(enabled_types_, partial_types);
616 fake_manager_factory_->set_progress_marker_types(old_types);
617 fake_manager_factory_->set_initial_sync_ended_types(full_types);
618 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
619 syncer::EXTENSION_SETTINGS);
620 enabled_types_.PutAll(new_types);
622 // Purge the partial types. The nigori will be among the purged types, but
623 // the syncer will re-download it by the time the initialization is complete.
624 InitializeBackend(true);
625 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
626 syncer::ModelTypeSet(syncer::NIGORI)));
627 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
628 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
629 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
630 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
631 enabled_types_).Equals(Union(new_types, Difference(
632 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
634 // Downloads and applies the new types and partial types (which includes
635 // nigori anyways).
636 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
637 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
638 syncer::ModelTypeSet());
639 EXPECT_TRUE(ready_types.Equals(full_types));
640 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
641 Union(new_types, partial_types)));
642 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
643 enabled_types_).Empty());
644 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
645 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
646 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
647 enabled_types_).Empty());
650 // Verify that downloading control types only downloads those types that do
651 // not have initial sync ended set.
652 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
653 sync_prefs_->SetSyncSetupCompleted();
654 // Set sync manager behavior before passing it down. Experiments and device
655 // info are new types without progress markers or initial sync ended, while
656 // all other types have been fully downloaded and applied.
657 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI);
658 syncer::ModelTypeSet old_types =
659 Difference(enabled_types_, new_types);
660 fake_manager_factory_->set_progress_marker_types(old_types);
661 fake_manager_factory_->set_initial_sync_ended_types(old_types);
663 // Bringing up the backend should download the new types without downloading
664 // any old types.
665 InitializeBackend(true);
666 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
667 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
668 Difference(syncer::ModelTypeSet::All(),
669 enabled_types_)));
670 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
671 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
672 enabled_types_).Empty());
675 // Fail to download control types. It's believed that there is a server bug
676 // which can allow this to happen (crbug.com/164288). The sync backend host
677 // should detect this condition and fail to initialize the backend.
679 // The failure is "silent" in the sense that the GetUpdates request appears to
680 // be successful, but it returned no results. This means that the usual
681 // download retry logic will not be invoked.
682 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
683 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
684 InitializeBackend(false);
687 // Test that local refresh requests are delivered to sync.
688 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
689 InitializeBackend(true);
691 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
692 IssueRefreshRequest(set1);
693 fake_manager_->WaitForSyncThread();
694 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
696 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
697 IssueRefreshRequest(set2);
698 fake_manager_->WaitForSyncThread();
699 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
702 // Test that local invalidations issued before sync is initialized are ignored.
703 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
704 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
705 IssueRefreshRequest(set1);
707 InitializeBackend(true);
709 fake_manager_->WaitForSyncThread();
710 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
713 // Test that local invalidations issued while sync is shutting down are ignored.
714 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
715 InitializeBackend(true);
717 backend_->StopSyncingForShutdown();
719 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
720 IssueRefreshRequest(types);
721 fake_manager_->WaitForSyncThread();
722 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
724 backend_->Shutdown(syncer::STOP_SYNC);
725 backend_.reset();
728 // Test that configuration on signin sends the proper GU source.
729 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
730 InitializeBackend(true);
731 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
732 fake_manager_->GetAndResetConfigureReason());
735 // Test that configuration on restart sends the proper GU source.
736 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
737 sync_prefs_->SetSyncSetupCompleted();
738 fake_manager_factory_->set_progress_marker_types(enabled_types_);
739 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
740 InitializeBackend(true);
741 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
742 fake_manager_->GetAndResetConfigureReason());
745 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
746 // setup hasn't been completed. This test ensures that cleanup happens.
747 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
748 const char* nonsense = "slon";
749 base::FilePath temp_directory =
750 profile_->GetPath().Append(base::FilePath(kTestSyncDir));
751 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
752 ASSERT_TRUE(base::CreateDirectory(temp_directory));
753 ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense)));
755 InitializeBackend(true);
757 EXPECT_FALSE(base::PathExists(sync_file));
760 // If bookmarks encounter an error that results in disabling without purging
761 // (such as when the type is unready), and then is explicitly disabled, the
762 // SyncBackendHost needs to tell the manager to purge the type, even though
763 // it's already disabled (crbug.com/386778).
764 TEST_F(SyncBackendHostTest, DisableThenPurgeType) {
765 syncer::ModelTypeSet error_types(syncer::BOOKMARKS);
767 InitializeBackend(true);
769 // First enable the types.
770 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
771 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
772 syncer::ModelTypeSet());
774 // Nigori is always downloaded so won't be ready.
775 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
776 syncer::ControlTypes(),
777 syncer::ModelTypeSet(syncer::NIGORI))));
779 // Then mark the error types as unready (disables without purging).
780 ready_types = ConfigureDataTypes(
781 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
782 error_types);
783 EXPECT_TRUE(
784 ready_types.Equals(syncer::Difference(enabled_types_, error_types)));
785 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
786 error_types).Empty());
788 // Lastly explicitly disable the error types, which should result in a purge.
789 enabled_types_.RemoveAll(error_types);
790 ready_types = ConfigureDataTypes(
791 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
792 syncer::ModelTypeSet());
793 EXPECT_TRUE(
794 ready_types.Equals(syncer::Difference(enabled_types_, error_types)));
795 EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
796 error_types).Empty());
799 // Test that a call to ClearServerData is forwarded to the underlying
800 // SyncManager.
801 TEST_F(SyncBackendHostTest, ClearServerDataCallsAreForwarded) {
802 InitializeBackend(true);
803 syncer::CallbackCounter callback_counter;
804 backend_->ClearServerData(base::Bind(&syncer::CallbackCounter::Callback,
805 base::Unretained(&callback_counter)));
806 fake_manager_->WaitForSyncThread();
807 EXPECT_EQ(1, callback_counter.times_called());
810 // Ensure that redundant invalidations are ignored and that the most recent
811 // set of invalidation version is persisted across restarts.
812 TEST_F(SyncBackendHostTest, IgnoreOldInvalidations) {
813 // Set up some old persisted invalidations.
814 std::map<syncer::ModelType, int64> invalidation_versions;
815 invalidation_versions[syncer::BOOKMARKS] = 20;
816 sync_prefs_->UpdateInvalidationVersions(invalidation_versions);
817 InitializeBackend(true);
818 EXPECT_EQ(0, fake_manager_->GetInvalidationCount());
820 // Receiving an invalidation with an old version should do nothing.
821 syncer::ObjectIdInvalidationMap invalidation_map;
822 std::string notification_type;
823 syncer::RealModelTypeToNotificationType(syncer::BOOKMARKS,
824 &notification_type);
825 invalidation_map.Insert(syncer::Invalidation::Init(
826 invalidation::ObjectId(0, notification_type), 10, "payload"));
827 backend_->OnIncomingInvalidation(invalidation_map);
828 fake_manager_->WaitForSyncThread();
829 EXPECT_EQ(0, fake_manager_->GetInvalidationCount());
831 // Invalidations with new versions should be acted upon.
832 invalidation_map.Insert(syncer::Invalidation::Init(
833 invalidation::ObjectId(0, notification_type), 30, "payload"));
834 backend_->OnIncomingInvalidation(invalidation_map);
835 fake_manager_->WaitForSyncThread();
836 EXPECT_EQ(1, fake_manager_->GetInvalidationCount());
838 // Invalidation for new data types should be acted on.
839 syncer::RealModelTypeToNotificationType(syncer::SESSIONS, &notification_type);
840 invalidation_map.Insert(syncer::Invalidation::Init(
841 invalidation::ObjectId(0, notification_type), 10, "payload"));
842 backend_->OnIncomingInvalidation(invalidation_map);
843 fake_manager_->WaitForSyncThread();
844 EXPECT_EQ(2, fake_manager_->GetInvalidationCount());
846 // But redelivering that same invalidation should be ignored.
847 backend_->OnIncomingInvalidation(invalidation_map);
848 fake_manager_->WaitForSyncThread();
849 EXPECT_EQ(2, fake_manager_->GetInvalidationCount());
851 // If an invalidation with an unknown version is received, it should be
852 // acted on, but should not affect the persisted versions.
853 invalidation_map.Insert(syncer::Invalidation::InitUnknownVersion(
854 invalidation::ObjectId(0, notification_type)));
855 backend_->OnIncomingInvalidation(invalidation_map);
856 fake_manager_->WaitForSyncThread();
857 EXPECT_EQ(3, fake_manager_->GetInvalidationCount());
859 // Verify that the invalidation versions were updated in the prefs.
860 invalidation_versions[syncer::BOOKMARKS] = 30;
861 invalidation_versions[syncer::SESSIONS] = 10;
862 std::map<syncer::ModelType, int64> persisted_invalidation_versions;
863 sync_prefs_->GetInvalidationVersions(&persisted_invalidation_versions);
864 EXPECT_EQ(invalidation_versions.size(),
865 persisted_invalidation_versions.size());
866 for (auto iter : persisted_invalidation_versions) {
867 EXPECT_EQ(invalidation_versions[iter.first], iter.second);
871 } // namespace
873 } // namespace browser_sync