Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / sync / glue / sync_backend_host_impl_unittest.cc
blob4c09eea87d04a137ef42848e83a98becfb949e06
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(
127 const std::string& /* name */) override {
128 *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_,
129 progress_marker_types_,
130 configure_fail_types_);
131 return scoped_ptr<SyncManager>(*fake_manager_);
134 void set_initial_sync_ended_types(syncer::ModelTypeSet types) {
135 initial_sync_ended_types_ = types;
138 void set_progress_marker_types(syncer::ModelTypeSet types) {
139 progress_marker_types_ = types;
142 void set_configure_fail_types(syncer::ModelTypeSet types) {
143 configure_fail_types_ = types;
146 private:
147 syncer::ModelTypeSet initial_sync_ended_types_;
148 syncer::ModelTypeSet progress_marker_types_;
149 syncer::ModelTypeSet configure_fail_types_;
150 FakeSyncManager** fake_manager_;
153 class SyncBackendHostTest : public testing::Test {
154 protected:
155 SyncBackendHostTest()
156 : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD),
157 profile_manager_(TestingBrowserProcess::GetGlobal()),
158 fake_manager_(NULL) {}
160 ~SyncBackendHostTest() override {}
162 void SetUp() override {
163 ASSERT_TRUE(profile_manager_.SetUp());
164 profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
165 sync_prefs_.reset(new sync_driver::SyncPrefs(profile_->GetPrefs()));
166 backend_.reset(new SyncBackendHostImpl(
167 profile_->GetDebugName(), profile_,
168 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
169 invalidation::ProfileInvalidationProviderFactory::GetForProfile(
170 profile_)
171 ->GetInvalidationService(),
172 sync_prefs_->AsWeakPtr(), base::FilePath(kTestSyncDir)));
173 credentials_.email = "user@example.com";
174 credentials_.sync_token = "sync_token";
175 credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope);
177 fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_));
179 // These types are always implicitly enabled.
180 enabled_types_.PutAll(syncer::ControlTypes());
182 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
183 // Registrar removing them if it can't find their model workers.
184 enabled_types_.Put(syncer::BOOKMARKS);
185 enabled_types_.Put(syncer::PREFERENCES);
186 enabled_types_.Put(syncer::SESSIONS);
187 enabled_types_.Put(syncer::SEARCH_ENGINES);
188 enabled_types_.Put(syncer::AUTOFILL);
190 network_resources_.reset(new syncer::HttpBridgeNetworkResources());
193 void TearDown() override {
194 if (backend_) {
195 backend_->StopSyncingForShutdown();
196 backend_->Shutdown(syncer::STOP_SYNC);
198 backend_.reset();
199 sync_prefs_.reset();
200 profile_ = NULL;
201 profile_manager_.DeleteTestingProfile(kTestProfileName);
202 // Pump messages posted by the sync thread (which may end up
203 // posting on the IO thread).
204 base::RunLoop().RunUntilIdle();
205 content::RunAllPendingInMessageLoop(BrowserThread::IO);
206 // Pump any messages posted by the IO thread.
207 base::RunLoop().RunUntilIdle();
210 // Synchronously initializes the backend.
211 void InitializeBackend(bool expect_success) {
212 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)).
213 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
214 backend_->Initialize(
215 &mock_frontend_, scoped_ptr<base::Thread>(),
216 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
217 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
218 syncer::WeakHandle<syncer::JsEventHandler>(), GURL(std::string()),
219 std::string(), credentials_, true, fake_manager_factory_.Pass(),
220 MakeWeakHandle(test_unrecoverable_error_handler_.GetWeakPtr()),
221 base::Closure(), network_resources_.get(), saved_nigori_state_.Pass());
222 base::RunLoop run_loop;
223 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
224 run_loop.QuitClosure(),
225 TestTimeouts::action_timeout());
226 run_loop.Run();
227 // |fake_manager_factory_|'s fake_manager() is set on the sync
228 // thread, but we can rely on the message loop barriers to
229 // guarantee that we see the updated value.
230 DCHECK(fake_manager_);
233 // Synchronously configures the backend's datatypes.
234 syncer::ModelTypeSet ConfigureDataTypes(
235 syncer::ModelTypeSet types_to_add,
236 syncer::ModelTypeSet types_to_remove,
237 syncer::ModelTypeSet types_to_unapply) {
238 sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap
239 config_state_map;
240 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
241 sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE,
242 types_to_add,
243 &config_state_map);
244 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
245 sync_driver::BackendDataTypeConfigurer::DISABLED,
246 types_to_remove, &config_state_map);
247 sync_driver::BackendDataTypeConfigurer::SetDataTypesState(
248 sync_driver::BackendDataTypeConfigurer::UNREADY,
249 types_to_unapply, &config_state_map);
251 types_to_add.PutAll(syncer::ControlTypes());
252 syncer::ModelTypeSet ready_types = backend_->ConfigureDataTypes(
253 syncer::CONFIGURE_REASON_RECONFIGURATION, config_state_map,
254 base::Bind(&SyncBackendHostTest::DownloadReady, base::Unretained(this)),
255 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
256 base::Unretained(this)));
257 base::RunLoop run_loop;
258 BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
259 run_loop.QuitClosure(),
260 TestTimeouts::action_timeout());
261 run_loop.Run();
262 return ready_types;
265 void IssueRefreshRequest(syncer::ModelTypeSet types) {
266 DCHECK_CURRENTLY_ON(BrowserThread::UI);
268 content::NotificationService::current()->Notify(
269 chrome::NOTIFICATION_SYNC_REFRESH_LOCAL,
270 content::Source<Profile>(profile_),
271 content::Details<syncer::ModelTypeSet>(&types));
274 protected:
275 void DownloadReady(syncer::ModelTypeSet succeeded_types,
276 syncer::ModelTypeSet failed_types) {
277 base::MessageLoop::current()->Quit();
280 void OnDownloadRetry() {
281 NOTIMPLEMENTED();
284 content::TestBrowserThreadBundle thread_bundle_;
285 StrictMock<MockSyncFrontend> mock_frontend_;
286 syncer::SyncCredentials credentials_;
287 TestingProfileManager profile_manager_;
288 TestingProfile* profile_;
289 syncer::TestUnrecoverableErrorHandler test_unrecoverable_error_handler_;
290 scoped_ptr<sync_driver::SyncPrefs> sync_prefs_;
291 scoped_ptr<SyncBackendHostImpl> backend_;
292 scoped_ptr<FakeSyncManagerFactory> fake_manager_factory_;
293 FakeSyncManager* fake_manager_;
294 syncer::ModelTypeSet enabled_types_;
295 scoped_ptr<syncer::NetworkResources> network_resources_;
296 scoped_ptr<syncer::SyncEncryptionHandler::NigoriState> saved_nigori_state_;
299 // Test basic initialization with no initial types (first time initialization).
300 // Only the nigori should be configured.
301 TEST_F(SyncBackendHostTest, InitShutdown) {
302 InitializeBackend(true);
303 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
304 syncer::ControlTypes()));
305 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
306 syncer::ControlTypes()));
307 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
308 syncer::ControlTypes()).Empty());
311 // Test first time sync scenario. All types should be properly configured.
312 TEST_F(SyncBackendHostTest, FirstTimeSync) {
313 InitializeBackend(true);
314 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
315 syncer::ControlTypes()));
316 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
317 syncer::ControlTypes()));
318 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
319 syncer::ControlTypes()).Empty());
321 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
322 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
323 syncer::ModelTypeSet());
324 // Nigori is always downloaded so won't be ready.
325 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
326 syncer::ControlTypes(),
327 syncer::ModelTypeSet(syncer::NIGORI))));
328 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
329 Difference(enabled_types_, syncer::ControlTypes())));
330 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
331 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
332 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
333 enabled_types_).Empty());
336 // Test the restart after setting up sync scenario. No enabled types should be
337 // downloaded or cleaned.
338 TEST_F(SyncBackendHostTest, Restart) {
339 sync_prefs_->SetSyncSetupCompleted();
340 syncer::ModelTypeSet all_but_nigori = enabled_types_;
341 fake_manager_factory_->set_progress_marker_types(enabled_types_);
342 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
343 InitializeBackend(true);
344 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
345 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
346 enabled_types_).Empty());
347 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
348 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
349 enabled_types_).Empty());
351 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
352 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
353 syncer::ModelTypeSet());
354 EXPECT_TRUE(ready_types.Equals(enabled_types_));
355 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
356 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
357 enabled_types_).Empty());
358 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
359 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
360 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
361 enabled_types_).Empty());
364 // Test a sync restart scenario where some types had never finished configuring.
365 // The partial types should be purged, then reconfigured properly.
366 TEST_F(SyncBackendHostTest, PartialTypes) {
367 sync_prefs_->SetSyncSetupCompleted();
368 // Set sync manager behavior before passing it down. All types have progress
369 // markers, but nigori and bookmarks are missing initial sync ended.
370 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
371 syncer::ModelTypeSet full_types =
372 Difference(enabled_types_, partial_types);
373 fake_manager_factory_->set_progress_marker_types(enabled_types_);
374 fake_manager_factory_->set_initial_sync_ended_types(full_types);
376 // Bringing up the backend should purge all partial types, then proceed to
377 // download the Nigori.
378 InitializeBackend(true);
379 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
380 syncer::ModelTypeSet(syncer::NIGORI)));
381 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
382 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
383 Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
384 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
385 enabled_types_).Equals(
386 Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))));
388 // Now do the actual configuration, which should download and apply bookmarks.
389 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
390 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
391 syncer::ModelTypeSet());
392 EXPECT_TRUE(ready_types.Equals(full_types));
393 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
394 enabled_types_).Empty());
395 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
396 partial_types));
397 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
398 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
399 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
400 enabled_types_).Empty());
403 // Test the behavior when we lose the sync db. Although we already have types
404 // enabled, we should re-download all of them because we lost their data.
405 TEST_F(SyncBackendHostTest, LostDB) {
406 sync_prefs_->SetSyncSetupCompleted();
407 // Initialization should fetch the Nigori node. Everything else should be
408 // left untouched.
409 InitializeBackend(true);
410 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
411 syncer::ModelTypeSet(syncer::ControlTypes())));
412 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
413 syncer::ModelTypeSet(syncer::ControlTypes())));
414 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
415 enabled_types_).Equals(
416 Difference(enabled_types_, syncer::ControlTypes())));
418 // The database was empty, so any cleaning is entirely optional. We want to
419 // reset this value before running the next part of the test, though.
420 fake_manager_->GetAndResetCleanedTypes();
422 // The actual configuration should redownload and apply all the enabled types.
423 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
424 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
425 syncer::ModelTypeSet());
426 // Nigori is always downloaded so won't be ready.
427 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
428 syncer::ControlTypes(),
429 syncer::ModelTypeSet(syncer::NIGORI))));
430 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
431 Difference(enabled_types_, syncer::ControlTypes())));
432 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
433 enabled_types_).Empty());
434 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
435 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
436 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
437 enabled_types_).Empty());
440 TEST_F(SyncBackendHostTest, DisableTypes) {
441 // Simulate first time sync.
442 InitializeBackend(true);
443 fake_manager_->GetAndResetCleanedTypes();
444 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
445 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
446 syncer::ModelTypeSet());
447 // Nigori is always downloaded so won't be ready.
448 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
449 syncer::ControlTypes(),
450 syncer::ModelTypeSet(syncer::NIGORI))));
451 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
452 enabled_types_));
453 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
454 enabled_types_).Empty());
455 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
456 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
457 enabled_types_).Empty());
459 // Then disable two datatypes.
460 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
461 syncer::SEARCH_ENGINES);
462 syncer::ModelTypeSet old_types = enabled_types_;
463 enabled_types_.RemoveAll(disabled_types);
464 ready_types = ConfigureDataTypes(
465 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
466 syncer::ModelTypeSet());
468 // Only those datatypes disabled should be cleaned. Nothing should be
469 // downloaded.
470 EXPECT_TRUE(ready_types.Equals(enabled_types_));
471 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
472 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
473 old_types).Equals(disabled_types));
474 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
475 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
476 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
477 enabled_types_).Empty());
480 TEST_F(SyncBackendHostTest, AddTypes) {
481 // Simulate first time sync.
482 InitializeBackend(true);
483 fake_manager_->GetAndResetCleanedTypes();
484 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
485 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
486 syncer::ModelTypeSet());
487 // Nigori is always downloaded so won't be ready.
488 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
489 syncer::ControlTypes(),
490 syncer::ModelTypeSet(syncer::NIGORI))));
491 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
492 enabled_types_));
493 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
494 enabled_types_).Empty());
495 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
496 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
497 enabled_types_).Empty());
499 // Then add two datatypes.
500 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
501 syncer::APPS);
502 enabled_types_.PutAll(new_types);
503 ready_types = ConfigureDataTypes(
504 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
505 syncer::ModelTypeSet());
507 // Only those datatypes added should be downloaded (plus nigori). Nothing
508 // should be cleaned aside from the disabled types.
509 new_types.Put(syncer::NIGORI);
510 EXPECT_TRUE(
511 ready_types.Equals(syncer::Difference(enabled_types_, new_types)));
512 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
513 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
514 enabled_types_).Empty());
515 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
516 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
517 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
518 enabled_types_).Empty());
521 // And and disable in the same configuration.
522 TEST_F(SyncBackendHostTest, AddDisableTypes) {
523 // Simulate first time sync.
524 InitializeBackend(true);
525 fake_manager_->GetAndResetCleanedTypes();
526 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
527 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
528 syncer::ModelTypeSet());
529 // Nigori is always downloaded so won't be ready.
530 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
531 syncer::ControlTypes(),
532 syncer::ModelTypeSet(syncer::NIGORI))));
533 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
534 enabled_types_));
535 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
536 enabled_types_).Empty());
537 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
538 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
539 enabled_types_).Empty());
541 // Then add two datatypes.
542 syncer::ModelTypeSet old_types = enabled_types_;
543 syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS,
544 syncer::SEARCH_ENGINES);
545 syncer::ModelTypeSet new_types(syncer::EXTENSIONS,
546 syncer::APPS);
547 enabled_types_.PutAll(new_types);
548 enabled_types_.RemoveAll(disabled_types);
549 ready_types = ConfigureDataTypes(
550 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
551 syncer::ModelTypeSet());
553 // Only those datatypes added should be downloaded (plus nigori). Nothing
554 // should be cleaned aside from the disabled types.
555 new_types.Put(syncer::NIGORI);
556 EXPECT_TRUE(
557 ready_types.Equals(syncer::Difference(enabled_types_, new_types)));
558 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
559 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
560 old_types).Equals(disabled_types));
561 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
562 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
563 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
564 old_types).Equals(disabled_types));
567 // Test restarting the browser to newly supported datatypes. The new datatypes
568 // should be downloaded on the configuration after backend initialization.
569 TEST_F(SyncBackendHostTest, NewlySupportedTypes) {
570 sync_prefs_->SetSyncSetupCompleted();
571 // Set sync manager behavior before passing it down. All types have progress
572 // markers and initial sync ended except the new types.
573 syncer::ModelTypeSet old_types = enabled_types_;
574 fake_manager_factory_->set_progress_marker_types(old_types);
575 fake_manager_factory_->set_initial_sync_ended_types(old_types);
576 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
577 syncer::EXTENSION_SETTINGS);
578 enabled_types_.PutAll(new_types);
580 // Does nothing.
581 InitializeBackend(true);
582 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
583 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
584 old_types).Empty());
585 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(old_types));
586 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
587 enabled_types_).Equals(new_types));
589 // Downloads and applies the new types (plus nigori).
590 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
591 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
592 syncer::ModelTypeSet());
594 new_types.Put(syncer::NIGORI);
595 EXPECT_TRUE(ready_types.Equals(
596 syncer::Difference(old_types, syncer::ModelTypeSet(syncer::NIGORI))));
597 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
598 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
599 enabled_types_).Empty());
600 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
601 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
602 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
603 enabled_types_).Empty());
606 // Test the newly supported types scenario, but with the presence of partial
607 // types as well. Both partial and newly supported types should be downloaded
608 // the configuration.
609 TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) {
610 sync_prefs_->SetSyncSetupCompleted();
611 // Set sync manager behavior before passing it down. All types have progress
612 // markers and initial sync ended except the new types.
613 syncer::ModelTypeSet old_types = enabled_types_;
614 syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS);
615 syncer::ModelTypeSet full_types =
616 Difference(enabled_types_, partial_types);
617 fake_manager_factory_->set_progress_marker_types(old_types);
618 fake_manager_factory_->set_initial_sync_ended_types(full_types);
619 syncer::ModelTypeSet new_types(syncer::APP_SETTINGS,
620 syncer::EXTENSION_SETTINGS);
621 enabled_types_.PutAll(new_types);
623 // Purge the partial types. The nigori will be among the purged types, but
624 // the syncer will re-download it by the time the initialization is complete.
625 InitializeBackend(true);
626 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
627 syncer::ModelTypeSet(syncer::NIGORI)));
628 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types));
629 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(
630 syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI))));
631 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
632 enabled_types_).Equals(Union(new_types, Difference(
633 partial_types, syncer::ModelTypeSet(syncer::NIGORI)))));
635 // Downloads and applies the new types and partial types (which includes
636 // nigori anyways).
637 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
638 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
639 syncer::ModelTypeSet());
640 EXPECT_TRUE(ready_types.Equals(full_types));
641 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
642 Union(new_types, partial_types)));
643 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
644 enabled_types_).Empty());
645 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
646 EXPECT_TRUE(fake_manager_->GetAndResetEnabledTypes().Equals(enabled_types_));
647 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
648 enabled_types_).Empty());
651 // Verify that downloading control types only downloads those types that do
652 // not have initial sync ended set.
653 TEST_F(SyncBackendHostTest, DownloadControlTypes) {
654 sync_prefs_->SetSyncSetupCompleted();
655 // Set sync manager behavior before passing it down. Experiments and device
656 // info are new types without progress markers or initial sync ended, while
657 // all other types have been fully downloaded and applied.
658 syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI);
659 syncer::ModelTypeSet old_types =
660 Difference(enabled_types_, new_types);
661 fake_manager_factory_->set_progress_marker_types(old_types);
662 fake_manager_factory_->set_initial_sync_ended_types(old_types);
664 // Bringing up the backend should download the new types without downloading
665 // any old types.
666 InitializeBackend(true);
667 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(new_types));
668 EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().Equals(
669 Difference(syncer::ModelTypeSet::All(),
670 enabled_types_)));
671 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
672 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
673 enabled_types_).Empty());
676 // Fail to download control types. It's believed that there is a server bug
677 // which can allow this to happen (crbug.com/164288). The sync backend host
678 // should detect this condition and fail to initialize the backend.
680 // The failure is "silent" in the sense that the GetUpdates request appears to
681 // be successful, but it returned no results. This means that the usual
682 // download retry logic will not be invoked.
683 TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) {
684 fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All());
685 InitializeBackend(false);
688 // Test that local refresh requests are delivered to sync.
689 TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) {
690 InitializeBackend(true);
692 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
693 IssueRefreshRequest(set1);
694 fake_manager_->WaitForSyncThread();
695 EXPECT_TRUE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
697 syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS);
698 IssueRefreshRequest(set2);
699 fake_manager_->WaitForSyncThread();
700 EXPECT_TRUE(set2.Equals(fake_manager_->GetLastRefreshRequestTypes()));
703 // Test that local invalidations issued before sync is initialized are ignored.
704 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestEarly) {
705 syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All();
706 IssueRefreshRequest(set1);
708 InitializeBackend(true);
710 fake_manager_->WaitForSyncThread();
711 EXPECT_FALSE(set1.Equals(fake_manager_->GetLastRefreshRequestTypes()));
714 // Test that local invalidations issued while sync is shutting down are ignored.
715 TEST_F(SyncBackendHostTest, AttemptForwardLocalRefreshRequestLate) {
716 InitializeBackend(true);
718 backend_->StopSyncingForShutdown();
720 syncer::ModelTypeSet types = syncer::ModelTypeSet::All();
721 IssueRefreshRequest(types);
722 fake_manager_->WaitForSyncThread();
723 EXPECT_FALSE(types.Equals(fake_manager_->GetLastRefreshRequestTypes()));
725 backend_->Shutdown(syncer::STOP_SYNC);
726 backend_.reset();
729 // Test that configuration on signin sends the proper GU source.
730 TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) {
731 InitializeBackend(true);
732 EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT,
733 fake_manager_->GetAndResetConfigureReason());
736 // Test that configuration on restart sends the proper GU source.
737 TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) {
738 sync_prefs_->SetSyncSetupCompleted();
739 fake_manager_factory_->set_progress_marker_types(enabled_types_);
740 fake_manager_factory_->set_initial_sync_ended_types(enabled_types_);
741 InitializeBackend(true);
742 EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE,
743 fake_manager_->GetAndResetConfigureReason());
746 // It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync
747 // setup hasn't been completed. This test ensures that cleanup happens.
748 TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) {
749 const char* nonsense = "slon";
750 base::FilePath temp_directory =
751 profile_->GetPath().Append(base::FilePath(kTestSyncDir));
752 base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3");
753 ASSERT_TRUE(base::CreateDirectory(temp_directory));
754 ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense)));
756 InitializeBackend(true);
758 EXPECT_FALSE(base::PathExists(sync_file));
761 // If bookmarks encounter an error that results in disabling without purging
762 // (such as when the type is unready), and then is explicitly disabled, the
763 // SyncBackendHost needs to tell the manager to purge the type, even though
764 // it's already disabled (crbug.com/386778).
765 TEST_F(SyncBackendHostTest, DisableThenPurgeType) {
766 syncer::ModelTypeSet error_types(syncer::BOOKMARKS);
768 InitializeBackend(true);
770 // First enable the types.
771 syncer::ModelTypeSet ready_types = ConfigureDataTypes(
772 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
773 syncer::ModelTypeSet());
775 // Nigori is always downloaded so won't be ready.
776 EXPECT_TRUE(ready_types.Equals(syncer::Difference(
777 syncer::ControlTypes(),
778 syncer::ModelTypeSet(syncer::NIGORI))));
780 // Then mark the error types as unready (disables without purging).
781 ready_types = ConfigureDataTypes(
782 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
783 error_types);
784 EXPECT_TRUE(
785 ready_types.Equals(syncer::Difference(enabled_types_, error_types)));
786 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
787 error_types).Empty());
789 // Lastly explicitly disable the error types, which should result in a purge.
790 enabled_types_.RemoveAll(error_types);
791 ready_types = ConfigureDataTypes(
792 enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_),
793 syncer::ModelTypeSet());
794 EXPECT_TRUE(
795 ready_types.Equals(syncer::Difference(enabled_types_, error_types)));
796 EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
797 error_types).Empty());
800 // Test that a call to ClearServerData is forwarded to the underlying
801 // SyncManager.
802 TEST_F(SyncBackendHostTest, ClearServerDataCallsAreForwarded) {
803 InitializeBackend(true);
804 syncer::CallbackCounter callback_counter;
805 backend_->ClearServerData(base::Bind(&syncer::CallbackCounter::Callback,
806 base::Unretained(&callback_counter)));
807 fake_manager_->WaitForSyncThread();
808 EXPECT_EQ(1, callback_counter.times_called());
811 // Ensure that redundant invalidations are ignored and that the most recent
812 // set of invalidation version is persisted across restarts.
813 TEST_F(SyncBackendHostTest, IgnoreOldInvalidations) {
814 // Set up some old persisted invalidations.
815 std::map<syncer::ModelType, int64> invalidation_versions;
816 invalidation_versions[syncer::BOOKMARKS] = 20;
817 sync_prefs_->UpdateInvalidationVersions(invalidation_versions);
818 InitializeBackend(true);
819 EXPECT_EQ(0, fake_manager_->GetInvalidationCount());
821 // Receiving an invalidation with an old version should do nothing.
822 syncer::ObjectIdInvalidationMap invalidation_map;
823 std::string notification_type;
824 syncer::RealModelTypeToNotificationType(syncer::BOOKMARKS,
825 &notification_type);
826 invalidation_map.Insert(syncer::Invalidation::Init(
827 invalidation::ObjectId(0, notification_type), 10, "payload"));
828 backend_->OnIncomingInvalidation(invalidation_map);
829 fake_manager_->WaitForSyncThread();
830 EXPECT_EQ(0, fake_manager_->GetInvalidationCount());
832 // Invalidations with new versions should be acted upon.
833 invalidation_map.Insert(syncer::Invalidation::Init(
834 invalidation::ObjectId(0, notification_type), 30, "payload"));
835 backend_->OnIncomingInvalidation(invalidation_map);
836 fake_manager_->WaitForSyncThread();
837 EXPECT_EQ(1, fake_manager_->GetInvalidationCount());
839 // Invalidation for new data types should be acted on.
840 syncer::RealModelTypeToNotificationType(syncer::SESSIONS, &notification_type);
841 invalidation_map.Insert(syncer::Invalidation::Init(
842 invalidation::ObjectId(0, notification_type), 10, "payload"));
843 backend_->OnIncomingInvalidation(invalidation_map);
844 fake_manager_->WaitForSyncThread();
845 EXPECT_EQ(2, fake_manager_->GetInvalidationCount());
847 // But redelivering that same invalidation should be ignored.
848 backend_->OnIncomingInvalidation(invalidation_map);
849 fake_manager_->WaitForSyncThread();
850 EXPECT_EQ(2, fake_manager_->GetInvalidationCount());
852 // If an invalidation with an unknown version is received, it should be
853 // acted on, but should not affect the persisted versions.
854 invalidation_map.Insert(syncer::Invalidation::InitUnknownVersion(
855 invalidation::ObjectId(0, notification_type)));
856 backend_->OnIncomingInvalidation(invalidation_map);
857 fake_manager_->WaitForSyncThread();
858 EXPECT_EQ(3, fake_manager_->GetInvalidationCount());
860 // Verify that the invalidation versions were updated in the prefs.
861 invalidation_versions[syncer::BOOKMARKS] = 30;
862 invalidation_versions[syncer::SESSIONS] = 10;
863 std::map<syncer::ModelType, int64> persisted_invalidation_versions;
864 sync_prefs_->GetInvalidationVersions(&persisted_invalidation_versions);
865 EXPECT_EQ(invalidation_versions.size(),
866 persisted_invalidation_versions.size());
867 for (auto iter : persisted_invalidation_versions) {
868 EXPECT_EQ(invalidation_versions[iter.first], iter.second);
872 } // namespace
874 } // namespace browser_sync