Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / data_type_manager_impl_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync/glue/data_type_manager_impl.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "components/sync_driver/backend_data_type_configurer.h"
11 #include "components/sync_driver/data_type_controller.h"
12 #include "components/sync_driver/data_type_encryption_handler.h"
13 #include "components/sync_driver/data_type_manager_observer.h"
14 #include "components/sync_driver/failed_data_types_handler.h"
15 #include "components/sync_driver/fake_data_type_controller.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "sync/internal_api/public/base/model_type.h"
18 #include "sync/internal_api/public/configure_reason.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace browser_sync {
23
24 using syncer::ModelType;
25 using syncer::ModelTypeSet;
26 using syncer::ModelTypeToString;
27 using syncer::BOOKMARKS;
28 using syncer::APPS;
29 using syncer::PASSWORDS;
30 using syncer::PREFERENCES;
31 using syncer::NIGORI;
32 using testing::_;
33 using testing::Mock;
34 using testing::ResultOf;
35
36 namespace {
37
38 // Used by SetConfigureDoneExpectation.
39 DataTypeManager::ConfigureStatus GetStatus(
40     const DataTypeManager::ConfigureResult& result) {
41   return result.status;
42 }
43
44 // Helper for unioning with priority types.
45 syncer::ModelTypeSet AddHighPriorityTypesTo(syncer::ModelTypeSet types) {
46   syncer::ModelTypeSet result = syncer::ControlTypes();
47   result.PutAll(types);
48   return result;
49 }
50
51 // Fake BackendDataTypeConfigurer implementation that simply stores away the
52 // callback passed into ConfigureDataTypes.
53 class FakeBackendDataTypeConfigurer : public BackendDataTypeConfigurer {
54  public:
55   FakeBackendDataTypeConfigurer() {}
56   virtual ~FakeBackendDataTypeConfigurer() {}
57
58   virtual void ConfigureDataTypes(
59       syncer::ConfigureReason reason,
60       const DataTypeConfigStateMap& config_state_map,
61       const base::Callback<void(ModelTypeSet,
62                                 ModelTypeSet)>& ready_task,
63       const base::Callback<void()>& retry_callback) OVERRIDE {
64     last_ready_task_ = ready_task;
65
66     if (!expected_configure_types_.Empty()) {
67       EXPECT_TRUE(
68           expected_configure_types_.Equals(
69               GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map)))
70           << syncer::ModelTypeSetToString(expected_configure_types_)
71           << " v.s. "
72           << syncer::ModelTypeSetToString(
73               GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map));
74     }
75   }
76
77   base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task() const {
78     return last_ready_task_;
79   }
80
81   void set_expected_configure_types(syncer::ModelTypeSet types) {
82     expected_configure_types_ = types;
83   }
84
85  private:
86   base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task_;
87   syncer::ModelTypeSet expected_configure_types_;
88 };
89
90 // Mock DataTypeManagerObserver implementation.
91 class DataTypeManagerObserverMock : public DataTypeManagerObserver {
92  public:
93   DataTypeManagerObserverMock() {}
94   virtual ~DataTypeManagerObserverMock() {}
95
96   MOCK_METHOD1(OnConfigureDone,
97                void(const browser_sync::DataTypeManager::ConfigureResult&));
98   MOCK_METHOD0(OnConfigureRetry, void());
99   MOCK_METHOD0(OnConfigureStart, void());
100 };
101
102 class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler {
103  public:
104   FakeDataTypeEncryptionHandler();
105   virtual ~FakeDataTypeEncryptionHandler();
106
107   virtual bool IsPassphraseRequired() const OVERRIDE;
108   virtual syncer::ModelTypeSet GetEncryptedDataTypes() const OVERRIDE;
109
110   void set_passphrase_required(bool passphrase_required) {
111     passphrase_required_ = passphrase_required;
112   }
113   void set_encrypted_types(syncer::ModelTypeSet encrypted_types) {
114     encrypted_types_ = encrypted_types;
115   }
116  private:
117   bool passphrase_required_;
118   syncer::ModelTypeSet encrypted_types_;
119 };
120
121 FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler()
122     : passphrase_required_(false) {}
123 FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {}
124
125 bool FakeDataTypeEncryptionHandler::IsPassphraseRequired() const {
126   return passphrase_required_;
127 }
128
129 syncer::ModelTypeSet
130 FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const {
131   return encrypted_types_;
132 }
133
134 } // namespace
135
136 class TestDataTypeManager : public DataTypeManagerImpl {
137  public:
138   TestDataTypeManager(
139       const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
140           debug_info_listener,
141       BackendDataTypeConfigurer* configurer,
142       const DataTypeController::TypeMap* controllers,
143       const DataTypeEncryptionHandler* encryption_handler,
144       DataTypeManagerObserver* observer,
145       FailedDataTypesHandler* failed_data_types_handler)
146       : DataTypeManagerImpl(debug_info_listener,
147                             controllers,
148                             encryption_handler,
149                             configurer,
150                             observer,
151                             failed_data_types_handler),
152         custom_priority_types_(syncer::ControlTypes()) {}
153
154   void set_priority_types(const syncer::ModelTypeSet& priority_types) {
155     custom_priority_types_ = priority_types;
156   }
157
158   DataTypeManager::ConfigureResult configure_result() const {
159     return configure_result_;
160   }
161
162   virtual void OnModelAssociationDone(
163       const DataTypeManager::ConfigureResult& result) OVERRIDE {
164     configure_result_ = result;
165     DataTypeManagerImpl::OnModelAssociationDone(result);
166   }
167
168  private:
169   virtual syncer::ModelTypeSet GetPriorityTypes() const OVERRIDE {
170     return custom_priority_types_;
171   }
172
173   syncer::ModelTypeSet custom_priority_types_;
174   DataTypeManager::ConfigureResult configure_result_;
175 };
176
177 // The actual test harness class, parametrized on nigori state (i.e., tests are
178 // run both configuring with nigori, and configuring without).
179 class SyncDataTypeManagerImplTest : public testing::Test {
180  public:
181   SyncDataTypeManagerImplTest()
182       : ui_thread_(content::BrowserThread::UI, &ui_loop_) {}
183
184   virtual ~SyncDataTypeManagerImplTest() {
185   }
186
187  protected:
188   virtual void SetUp() {
189    dtm_.reset(
190        new TestDataTypeManager(
191            syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
192            &configurer_,
193            &controllers_,
194            &encryption_handler_,
195            &observer_,
196            &failed_data_types_handler_));
197   }
198
199   void SetConfigureStartExpectation() {
200     EXPECT_CALL(observer_, OnConfigureStart());
201   }
202
203   void SetConfigureDoneExpectation(DataTypeManager::ConfigureStatus status) {
204     EXPECT_CALL(observer_, OnConfigureDone(ResultOf(&GetStatus, status)));
205   }
206
207   // Configure the given DTM with the given desired types.
208   void Configure(DataTypeManagerImpl* dtm,
209                  const syncer::ModelTypeSet& desired_types) {
210     dtm->Configure(desired_types, syncer::CONFIGURE_REASON_RECONFIGURATION);
211   }
212
213   // Finish downloading for the given DTM. Should be done only after
214   // a call to Configure().
215   void FinishDownload(const DataTypeManager& dtm,
216                       ModelTypeSet types_to_configure,
217                       ModelTypeSet failed_download_types) {
218     EXPECT_TRUE(DataTypeManager::DOWNLOAD_PENDING == dtm.state() ||
219                 DataTypeManager::CONFIGURING == dtm.state());
220     ASSERT_FALSE(configurer_.last_ready_task().is_null());
221     configurer_.last_ready_task().Run(
222         syncer::Difference(types_to_configure, failed_download_types),
223         failed_download_types);
224   }
225
226   // Adds a fake controller for the given type to |controllers_|.
227   // Should be called only before setting up the DTM.
228   void AddController(ModelType model_type) {
229     controllers_[model_type] = new FakeDataTypeController(model_type);
230   }
231
232   // Gets the fake controller for the given type, which should have
233   // been previously added via AddController().
234   scoped_refptr<FakeDataTypeController> GetController(
235       ModelType model_type) const {
236     DataTypeController::TypeMap::const_iterator it =
237         controllers_.find(model_type);
238     if (it == controllers_.end()) {
239       return NULL;
240     }
241     return make_scoped_refptr(
242         static_cast<FakeDataTypeController*>(it->second.get()));
243   }
244
245   void FailEncryptionFor(syncer::ModelTypeSet encrypted_types) {
246     encryption_handler_.set_passphrase_required(true);
247     encryption_handler_.set_encrypted_types(encrypted_types);
248   }
249
250   base::MessageLoopForUI ui_loop_;
251   content::TestBrowserThread ui_thread_;
252   DataTypeController::TypeMap controllers_;
253   FakeBackendDataTypeConfigurer configurer_;
254   DataTypeManagerObserverMock observer_;
255   scoped_ptr<TestDataTypeManager> dtm_;
256   FailedDataTypesHandler failed_data_types_handler_;
257   FakeDataTypeEncryptionHandler encryption_handler_;
258 };
259
260 // Set up a DTM with no controllers, configure it, finish downloading,
261 // and then stop it.
262 TEST_F(SyncDataTypeManagerImplTest, NoControllers) {
263   SetConfigureStartExpectation();
264   SetConfigureDoneExpectation(DataTypeManager::OK);
265
266   Configure(dtm_.get(), ModelTypeSet());
267   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
268
269   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
270   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
271
272   dtm_->Stop();
273   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
274 }
275
276 // Set up a DTM with a single controller, configure it, finish
277 // downloading, finish starting the controller, and then stop the DTM.
278 TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) {
279   AddController(BOOKMARKS);
280
281   SetConfigureStartExpectation();
282   SetConfigureDoneExpectation(DataTypeManager::OK);
283
284   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
285   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
286
287   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
288   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
289   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
290
291   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
292   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
293
294   dtm_->Stop();
295   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
296 }
297
298 // Set up a DTM with a single controller, configure it, but stop it
299 // before finishing the download.  It should still be safe to run the
300 // download callback even after the DTM is stopped and destroyed.
301 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) {
302   AddController(BOOKMARKS);
303
304   {
305     SetConfigureStartExpectation();
306     SetConfigureDoneExpectation(DataTypeManager::ABORTED);
307
308     Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
309     EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
310
311     dtm_->Stop();
312     EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
313   }
314
315   configurer_.last_ready_task().Run(ModelTypeSet(BOOKMARKS), ModelTypeSet());
316 }
317
318 // Set up a DTM with a single controller, configure it, finish
319 // downloading, but stop the DTM before the controller finishes
320 // starting up.  It should still be safe to finish starting up the
321 // controller even after the DTM is stopped and destroyed.
322 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) {
323   AddController(BOOKMARKS);
324
325   {
326     SetConfigureStartExpectation();
327     SetConfigureDoneExpectation(DataTypeManager::ABORTED);
328
329     Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
330     EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
331
332     FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
333     FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
334     EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
335
336     dtm_->Stop();
337     EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
338     dtm_.reset();
339   }
340
341   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
342 }
343
344 // Set up a DTM with a single controller, configure it, finish
345 // downloading, start the controller's model, but stop the DTM before
346 // the controller finishes starting up.  It should still be safe to
347 // finish starting up the controller even after the DTM is stopped and
348 // destroyed.
349 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileAssociating) {
350   AddController(BOOKMARKS);
351
352   {
353     SetConfigureStartExpectation();
354     SetConfigureDoneExpectation(DataTypeManager::ABORTED);
355
356     Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
357     EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
358
359     FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
360     FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
361     EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
362
363     dtm_->Stop();
364     EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
365     dtm_.reset();
366   }
367
368   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
369 }
370
371 // Set up a DTM with a single controller.  Then:
372 //
373 //   1) Configure.
374 //   2) Finish the download for step 1.
375 //   3) Finish starting the controller with the NEEDS_CRYPTO status.
376 //   4) Complete download for the reconfiguration without the controller.
377 //   5) Stop the DTM.
378 TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) {
379   AddController(PASSWORDS);
380
381   SetConfigureStartExpectation();
382   SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
383
384   const ModelTypeSet types(PASSWORDS);
385   dtm_->set_priority_types(AddHighPriorityTypesTo(types));
386
387   // Step 1.
388   Configure(dtm_.get(), types);
389   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
390
391   // Step 2.
392   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
393   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
394
395   // Step 3.
396   FailEncryptionFor(types);
397   GetController(PASSWORDS)->FinishStart(DataTypeController::NEEDS_CRYPTO);
398   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
399
400   // Step 4.
401   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
402   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
403
404   // Step 5.
405   dtm_->Stop();
406   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
407 }
408
409 // Set up a DTM with two controllers.  Then:
410 //
411 //   1) Configure with first controller.
412 //   2) Finish the download for step 1.
413 //   3) Finish starting the first controller.
414 //   4) Configure with both controllers.
415 //   5) Finish the download for step 4.
416 //   6) Finish starting the second controller.
417 //   7) Stop the DTM.
418 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) {
419   AddController(BOOKMARKS);
420   AddController(PREFERENCES);
421
422   SetConfigureStartExpectation();
423   SetConfigureDoneExpectation(DataTypeManager::OK);
424
425   // Step 1.
426   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
427   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
428
429   // Step 2.
430   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
431   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
432   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
433
434   // Step 3.
435   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
436   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
437
438   Mock::VerifyAndClearExpectations(&observer_);
439   SetConfigureStartExpectation();
440   SetConfigureDoneExpectation(DataTypeManager::OK);
441
442   // Step 4.
443   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
444   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
445
446   // Step 5.
447   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
448   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
449   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
450
451   // Step 6.
452   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
453   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
454
455   // Step 7.
456   dtm_->Stop();
457   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
458 }
459
460 // Set up a DTM with two controllers.  Then:
461 //
462 //   1) Configure with first controller.
463 //   2) Finish the download for step 1.
464 //   3) Finish starting the first controller.
465 //   4) Configure with second controller.
466 //   5) Finish the download for step 4.
467 //   6) Finish starting the second controller.
468 //   7) Stop the DTM.
469 TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) {
470   AddController(BOOKMARKS);
471   AddController(PREFERENCES);
472
473   SetConfigureStartExpectation();
474   SetConfigureDoneExpectation(DataTypeManager::OK);
475
476   // Step 1.
477   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
478   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
479
480   // Step 2.
481   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
482   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
483   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
484
485   // Step 3.
486   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
487   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
488
489   Mock::VerifyAndClearExpectations(&observer_);
490   SetConfigureStartExpectation();
491   SetConfigureDoneExpectation(DataTypeManager::OK);
492
493   // Step 4.
494   Configure(dtm_.get(), ModelTypeSet(PREFERENCES));
495   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
496
497   // Step 5.
498   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
499   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
500   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
501
502   // Step 6.
503   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
504   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
505
506   // Step 7.
507   dtm_->Stop();
508   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
509 }
510
511 // Set up a DTM with two controllers.  Then:
512 //
513 //   1) Configure with first controller.
514 //   2) Finish the download for step 1.
515 //   3) Configure with both controllers.
516 //   4) Finish starting the first controller.
517 //   5) Finish the download for step 3.
518 //   6) Finish starting the second controller.
519 //   7) Stop the DTM.
520 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileOneInFlight) {
521   AddController(BOOKMARKS);
522   AddController(PREFERENCES);
523
524   SetConfigureStartExpectation();
525   SetConfigureDoneExpectation(DataTypeManager::OK);
526
527   // Step 1.
528   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
529   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
530
531   // Step 2.
532   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
533   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
534   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
535
536   // Step 3.
537   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
538   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
539
540   // Step 4.
541   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
542   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
543
544   // Step 5.
545   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
546   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
547   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
548
549   // Step 6.
550   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
551   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
552
553   // Step 7.
554   dtm_->Stop();
555   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
556 }
557
558 // Set up a DTM with one controller.  Then configure, finish
559 // downloading, and start the controller with an unrecoverable error.
560 // The unrecoverable error should cause the DTM to stop.
561 TEST_F(SyncDataTypeManagerImplTest, OneFailingController) {
562   AddController(BOOKMARKS);
563
564   SetConfigureStartExpectation();
565   SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR);
566
567   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
568   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
569
570   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
571   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
572   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
573
574   GetController(BOOKMARKS)->FinishStart(
575       DataTypeController::UNRECOVERABLE_ERROR);
576   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
577 }
578
579 // Set up a DTM with two controllers.  Then:
580 //
581 //   1) Configure with both controllers.
582 //   2) Finish the download for step 1.
583 //   3) Finish starting the first controller successfully.
584 //   4) Finish starting the second controller with an unrecoverable error.
585 //
586 // The failure from step 4 should cause the DTM to stop.
587 TEST_F(SyncDataTypeManagerImplTest, SecondControllerFails) {
588   AddController(BOOKMARKS);
589   AddController(PREFERENCES);
590
591   SetConfigureStartExpectation();
592   SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR);
593
594   // Step 1.
595   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
596   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
597
598   // Step 2.
599   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
600   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
601   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
602
603   // Step 3.
604   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
605   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
606
607   // Step 4.
608   GetController(PREFERENCES)->FinishStart(
609       DataTypeController::UNRECOVERABLE_ERROR);
610   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
611 }
612
613 // Set up a DTM with two controllers.  Then:
614 //
615 //   1) Configure with both controllers.
616 //   2) Finish the download for step 1.
617 //   3) Finish starting the first controller successfully.
618 //   4) Finish starting the second controller with an association failure.
619 //   5) Finish the purge/reconfigure without the failed type.
620 //   6) Stop the DTM.
621 //
622 // The association failure from step 3 should be ignored.
623 //
624 // TODO(akalin): Check that the data type that failed association is
625 // recorded in the CONFIGURE_DONE notification.
626 TEST_F(SyncDataTypeManagerImplTest, OneControllerFailsAssociation) {
627   AddController(BOOKMARKS);
628   AddController(PREFERENCES);
629
630   SetConfigureStartExpectation();
631   SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
632
633   // Step 1.
634   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
635   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
636
637   // Step 2.
638   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
639   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
640   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
641
642   // Step 3.
643   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
644   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
645
646   // Step 4.
647   GetController(PREFERENCES)->FinishStart(
648       DataTypeController::ASSOCIATION_FAILED);
649   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
650
651   // Step 5.
652   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
653   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
654   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
655
656   // Step 6.
657   dtm_->Stop();
658   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
659 }
660
661 // Set up a DTM with two controllers.  Then:
662 //
663 //   1) Configure with first controller.
664 //   2) Configure with both controllers.
665 //   3) Finish the download for step 1.
666 //   4) Finish the download for step 2.
667 //   5) Finish starting both controllers.
668 //   6) Stop the DTM.
669 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) {
670   AddController(BOOKMARKS);
671   AddController(PREFERENCES);
672
673   SetConfigureStartExpectation();
674   SetConfigureDoneExpectation(DataTypeManager::OK);
675
676   // Step 1.
677   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
678   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
679
680   // Step 2.
681   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
682   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
683
684   // Step 3.
685   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
686   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
687
688   // Step 4.
689   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
690   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
691   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
692
693   // Step 5.
694   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
695   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
696   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
697   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
698
699   // Step 6.
700   dtm_->Stop();
701   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
702 }
703
704 // Set up a DTM with two controllers.  Then:
705 //
706 //   1) Configure with first controller.
707 //   2) Configure with both controllers.
708 //   3) Finish the download for step 1 with a failed data type.
709 //   4) Finish the download for step 2 successfully.
710 //   5) Finish starting both controllers.
711 //   6) Stop the DTM.
712 //
713 // The failure from step 3 should be ignored since there's a
714 // reconfigure pending from step 2.
715 TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) {
716   AddController(BOOKMARKS);
717   AddController(PREFERENCES);
718
719   SetConfigureStartExpectation();
720   SetConfigureDoneExpectation(DataTypeManager::OK);
721
722   // Step 1.
723   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
724   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
725   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
726
727   // Step 2.
728   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
729   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
730
731   // Step 3.
732   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
733   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
734   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
735
736   // Step 4.
737   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
738   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
739
740   // Step 5.
741   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
742   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
743   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
744   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
745
746   // Step 6.
747   dtm_->Stop();
748   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
749 }
750
751 // Tests a Purge then Configure.  This is similar to the sequence of
752 // operations that would be invoked by the BackendMigrator.
753 TEST_F(SyncDataTypeManagerImplTest, MigrateAll) {
754   AddController(BOOKMARKS);
755   dtm_->set_priority_types(AddHighPriorityTypesTo(ModelTypeSet(BOOKMARKS)));
756
757   SetConfigureStartExpectation();
758   SetConfigureDoneExpectation(DataTypeManager::OK);
759
760   // Initial setup.
761   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
762   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
763   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
764
765   // We've now configured bookmarks and (implicitly) the control types.
766   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
767   Mock::VerifyAndClearExpectations(&observer_);
768
769   // Pretend we were told to migrate all types.
770   ModelTypeSet to_migrate;
771   to_migrate.Put(BOOKMARKS);
772   to_migrate.PutAll(syncer::ControlTypes());
773
774   SetConfigureStartExpectation();
775   SetConfigureDoneExpectation(DataTypeManager::OK);
776   dtm_->PurgeForMigration(to_migrate,
777                           syncer::CONFIGURE_REASON_MIGRATION);
778   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
779
780   // The DTM will call ConfigureDataTypes(), even though it is unnecessary.
781   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
782   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
783   Mock::VerifyAndClearExpectations(&observer_);
784
785   // Re-enable the migrated types.
786   SetConfigureStartExpectation();
787   SetConfigureDoneExpectation(DataTypeManager::OK);
788   Configure(dtm_.get(), to_migrate);
789   FinishDownload(*dtm_, to_migrate, ModelTypeSet());
790   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
791   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
792 }
793
794 // Test receipt of a Configure request while a purge is in flight.
795 TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) {
796   AddController(BOOKMARKS);
797   AddController(PREFERENCES);
798
799   // Initial configure.
800   SetConfigureStartExpectation();
801   SetConfigureDoneExpectation(DataTypeManager::OK);
802   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS));
803   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
804   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
805   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
806   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
807   Mock::VerifyAndClearExpectations(&observer_);
808
809   // Purge the Nigori type.
810   SetConfigureStartExpectation();
811   dtm_->PurgeForMigration(ModelTypeSet(NIGORI),
812                           syncer::CONFIGURE_REASON_MIGRATION);
813   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
814   Mock::VerifyAndClearExpectations(&observer_);
815
816   // Before the backend configuration completes, ask for a different
817   // set of types.  This request asks for
818   // - BOOKMARKS: which is redundant because it was already enabled,
819   // - PREFERENCES: which is new and will need to be downloaded, and
820   // - NIGORI: (added implicitly because it is a control type) which
821   //   the DTM is part-way through purging.
822   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
823   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
824
825   // Invoke the callback we've been waiting for since we asked to purge NIGORI.
826   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
827   Mock::VerifyAndClearExpectations(&observer_);
828
829   SetConfigureDoneExpectation(DataTypeManager::OK);
830   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
831
832   // Now invoke the callback for the second configure request.
833   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
834   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet());
835   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
836
837   // Start the preferences controller.  We don't need to start controller for
838   // the NIGORI because it has none.  We don't need to start the controller for
839   // the BOOKMARKS because it was never stopped.
840   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
841   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
842 }
843
844 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) {
845   AddController(BOOKMARKS);
846   AddController(PREFERENCES);
847
848   dtm_->set_priority_types(
849       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
850
851   // Initial configure.
852   SetConfigureStartExpectation();
853   SetConfigureDoneExpectation(DataTypeManager::OK);
854
855   // Initially only PREFERENCES is configured.
856   configurer_.set_expected_configure_types(
857       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
858   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
859   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
860
861   // BOOKMARKS is configured after download of PREFERENCES finishes.
862   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
863   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
864   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
865
866   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
867   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
868   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
869
870   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
871   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
872 }
873
874 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationReconfigure) {
875   AddController(BOOKMARKS);
876   AddController(PREFERENCES);
877   AddController(APPS);
878
879   dtm_->set_priority_types(
880       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
881
882   // Initial configure.
883   SetConfigureStartExpectation();
884   SetConfigureDoneExpectation(DataTypeManager::OK);
885
886   // Reconfigure while associating PREFERENCES and downloading BOOKMARKS.
887   configurer_.set_expected_configure_types(
888       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
889   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
890   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
891
892   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
893   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
894   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
895
896   // Enable syncing for APPS.
897   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES, APPS));
898   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
899
900   // Reconfiguration starts after downloading and association of previous
901   // types finish.
902   configurer_.set_expected_configure_types(
903       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
904   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
905   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
906   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
907
908   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS, APPS));
909   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
910   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
911
912   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, APPS), ModelTypeSet());
913   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
914
915   // Skip calling FinishStart() for PREFENCES because it's already started in
916   // first configuration.
917   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
918   GetController(APPS)->FinishStart(DataTypeController::OK);
919   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
920 }
921
922 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationStop) {
923   AddController(BOOKMARKS);
924   AddController(PREFERENCES);
925
926   dtm_->set_priority_types(
927       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
928
929   // Initial configure.
930   SetConfigureStartExpectation();
931   SetConfigureDoneExpectation(DataTypeManager::ABORTED);
932
933   // Initially only PREFERENCES is configured.
934   configurer_.set_expected_configure_types(
935       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
936   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
937   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
938
939   // BOOKMARKS is configured after download of PREFERENCES finishes.
940   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
941   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
942   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
943
944   // PERFERENCES controller is associating while BOOKMARKS is downloading.
945   EXPECT_EQ(DataTypeController::ASSOCIATING,
946             GetController(PREFERENCES)->state());
947   EXPECT_EQ(DataTypeController::MODEL_LOADED,
948             GetController(BOOKMARKS)->state());
949
950   dtm_->Stop();
951   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
952   EXPECT_EQ(DataTypeController::NOT_RUNNING,
953             GetController(PREFERENCES)->state());
954   EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
955 }
956
957 TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationDownloadError) {
958   AddController(BOOKMARKS);
959   AddController(PREFERENCES);
960
961   dtm_->set_priority_types(
962       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
963
964   // Initial configure.
965   SetConfigureStartExpectation();
966   SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR);
967
968   // Initially only PREFERENCES is configured.
969   configurer_.set_expected_configure_types(
970       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
971   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
972   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
973
974   // BOOKMARKS is configured after download of PREFERENCES finishes.
975   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
976   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
977   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
978
979   // PERFERENCES controller is associating while BOOKMARKS is downloading.
980   EXPECT_EQ(DataTypeController::ASSOCIATING,
981             GetController(PREFERENCES)->state());
982   EXPECT_EQ(DataTypeController::MODEL_LOADED,
983             GetController(BOOKMARKS)->state());
984
985   // Make BOOKMARKS download fail.
986   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet(BOOKMARKS));
987   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
988   EXPECT_EQ(DataTypeController::NOT_RUNNING,
989             GetController(PREFERENCES)->state());
990   EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state());
991 }
992
993 TEST_F(SyncDataTypeManagerImplTest, HighPriorityAssociationFailure) {
994   AddController(PREFERENCES);   // Will fail.
995   AddController(BOOKMARKS);     // Will succeed.
996
997   dtm_->set_priority_types(
998       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
999
1000   // Initial configure.
1001   SetConfigureStartExpectation();
1002   SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
1003
1004   // Initially only PREFERENCES is configured.
1005   configurer_.set_expected_configure_types(
1006       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
1007   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
1008   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
1009
1010   // BOOKMARKS is configured after download of PREFERENCES finishes.
1011   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
1012   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
1013   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
1014
1015   // PERFERENCES controller is associating while BOOKMARKS is downloading.
1016   EXPECT_EQ(DataTypeController::ASSOCIATING,
1017             GetController(PREFERENCES)->state());
1018   EXPECT_EQ(DataTypeController::MODEL_LOADED,
1019             GetController(BOOKMARKS)->state());
1020
1021   // Make PREFERENCES association fail.
1022   GetController(PREFERENCES)->FinishStart(
1023       DataTypeController::ASSOCIATION_FAILED);
1024   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
1025
1026   // Reconfigure without PREFERENCES after the BOOKMARKS download completes,
1027   // then reconfigure with BOOKMARKS.
1028   configurer_.set_expected_configure_types(syncer::ControlTypes());
1029   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
1030   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
1031   FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet());
1032
1033   // Reconfigure with BOOKMARKS.
1034   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
1035   EXPECT_EQ(DataTypeController::ASSOCIATING,
1036             GetController(BOOKMARKS)->state());
1037   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
1038
1039   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
1040   EXPECT_EQ(DataTypeController::NOT_RUNNING,
1041             GetController(PREFERENCES)->state());
1042   EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state());
1043 }
1044
1045 TEST_F(SyncDataTypeManagerImplTest, LowPriorityAssociationFailure) {
1046   AddController(PREFERENCES);  // Will succeed.
1047   AddController(BOOKMARKS);    // Will fail.
1048
1049   dtm_->set_priority_types(
1050       AddHighPriorityTypesTo(syncer::ModelTypeSet(PREFERENCES)));
1051
1052   // Initial configure.
1053   SetConfigureStartExpectation();
1054   SetConfigureDoneExpectation(DataTypeManager::PARTIAL_SUCCESS);
1055
1056   // Initially only PREFERENCES is configured.
1057   configurer_.set_expected_configure_types(
1058       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
1059   Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES));
1060   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
1061
1062   // BOOKMARKS is configured after download of PREFERENCES finishes.
1063   configurer_.set_expected_configure_types(ModelTypeSet(BOOKMARKS));
1064   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
1065   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state());
1066
1067   // PERFERENCES controller is associating while BOOKMARKS is downloading.
1068   EXPECT_EQ(DataTypeController::ASSOCIATING,
1069             GetController(PREFERENCES)->state());
1070   EXPECT_EQ(DataTypeController::MODEL_LOADED,
1071             GetController(BOOKMARKS)->state());
1072
1073   // BOOKMARKS finishes downloading and PREFERENCES finishes associating.
1074   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
1075   GetController(PREFERENCES)->FinishStart(DataTypeController::OK);
1076   EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state());
1077
1078   // Make BOOKMARKS association fail, which triggers reconfigure with only
1079   // PREFERENCES.
1080   configurer_.set_expected_configure_types(
1081       AddHighPriorityTypesTo(ModelTypeSet(PREFERENCES)));
1082   GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED);
1083   EXPECT_EQ(DataTypeController::NOT_RUNNING,
1084             GetController(BOOKMARKS)->state());
1085   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm_->state());
1086
1087   // Finish configuration with only PREFERENCES.
1088   configurer_.set_expected_configure_types(ModelTypeSet());
1089   FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet());
1090   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state());
1091   EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state());
1092   EXPECT_EQ(DataTypeController::NOT_RUNNING,
1093             GetController(BOOKMARKS)->state());
1094 }
1095
1096 TEST_F(SyncDataTypeManagerImplTest, FilterDesiredTypes) {
1097   AddController(BOOKMARKS);
1098
1099   ModelTypeSet types(BOOKMARKS, APPS);
1100   dtm_->set_priority_types(AddHighPriorityTypesTo(types));
1101
1102   SetConfigureStartExpectation();
1103   SetConfigureDoneExpectation(DataTypeManager::OK);
1104
1105   syncer::ModelTypeSet expected_types = syncer::ControlTypes();
1106   expected_types.Put(BOOKMARKS);
1107   // APPS is filtered out because there's no controller for it.
1108   configurer_.set_expected_configure_types(expected_types);
1109   Configure(dtm_.get(), types);
1110   FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet());
1111   GetController(BOOKMARKS)->FinishStart(DataTypeController::OK);
1112
1113   dtm_->Stop();
1114   EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state());
1115 }
1116
1117 }  // namespace browser_sync