Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2011 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 <set>
      8 
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/message_loop.h"
     11 #include "base/stl_util-inl.h"
     12 #include "base/task.h"
     13 #include "chrome/browser/sync/glue/data_type_controller.h"
     14 #include "chrome/browser/sync/glue/data_type_controller_mock.h"
     15 #include "chrome/browser/sync/glue/sync_backend_host_mock.h"
     16 #include "chrome/browser/sync/profile_sync_test_util.h"
     17 #include "chrome/browser/sync/syncable/model_type.h"
     18 #include "content/browser/browser_thread.h"
     19 #include "content/common/notification_details.h"
     20 #include "content/common/notification_observer_mock.h"
     21 #include "content/common/notification_registrar.h"
     22 #include "content/common/notification_service.h"
     23 #include "content/common/notification_type.h"
     24 #include "testing/gmock/include/gmock/gmock.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 
     27 using browser_sync::DataTypeManager;
     28 using browser_sync::DataTypeManagerImpl;
     29 using browser_sync::DataTypeController;
     30 using browser_sync::DataTypeControllerMock;
     31 using browser_sync::SyncBackendHostMock;
     32 using testing::_;
     33 using testing::AtLeast;
     34 using testing::DoAll;
     35 using testing::DoDefault;
     36 using testing::InSequence;
     37 using testing::Invoke;
     38 using testing::InvokeWithoutArgs;
     39 using testing::InvokeWithoutArgs;
     40 using testing::Mock;
     41 using testing::Property;
     42 using testing::Pointee;
     43 using testing::Return;
     44 using testing::SaveArg;
     45 
     46 ACTION_P(InvokeCallback, callback_result) {
     47   arg0->Run(callback_result, FROM_HERE);
     48   delete arg0;
     49 }
     50 
     51 ACTION_P2(InvokeCallbackPointer, callback, argument) {
     52   callback->Run(argument, FROM_HERE);
     53   delete callback;
     54 }
     55 
     56 DataTypeManager::ConfigureResult GetResult(
     57     const NotificationDetails& details) {
     58   DataTypeManager::ConfigureResultWithErrorLocation* result_with_location =
     59       Details<DataTypeManager::ConfigureResultWithErrorLocation>(
     60       details).ptr();
     61   return result_with_location->result;
     62 }
     63 
     64 class DataTypeManagerImpl2Test : public testing::Test {
     65  public:
     66   DataTypeManagerImpl2Test()
     67       : ui_thread_(BrowserThread::UI, &message_loop_) {}
     68 
     69   virtual ~DataTypeManagerImpl2Test() {
     70   }
     71 
     72  protected:
     73   virtual void SetUp() {
     74     registrar_.Add(&observer_,
     75                    NotificationType::SYNC_CONFIGURE_START,
     76                    NotificationService::AllSources());
     77     registrar_.Add(&observer_,
     78                    NotificationType::SYNC_CONFIGURE_DONE,
     79                    NotificationService::AllSources());
     80   }
     81 
     82   DataTypeControllerMock* MakeBookmarkDTC() {
     83     DataTypeControllerMock* dtc = new DataTypeControllerMock();
     84     EXPECT_CALL(*dtc, enabled()).WillRepeatedly(Return(true));
     85     EXPECT_CALL(*dtc, type()).WillRepeatedly(Return(syncable::BOOKMARKS));
     86     EXPECT_CALL(*dtc, name()).WillRepeatedly(Return("bookmark"));
     87     return dtc;
     88   }
     89 
     90   DataTypeControllerMock* MakePreferenceDTC() {
     91     DataTypeControllerMock* dtc = new DataTypeControllerMock();
     92     EXPECT_CALL(*dtc, enabled()).WillRepeatedly(Return(true));
     93     EXPECT_CALL(*dtc, type()).WillRepeatedly(Return(syncable::PREFERENCES));
     94     EXPECT_CALL(*dtc, name()).WillRepeatedly(Return("preference"));
     95     return dtc;
     96   }
     97 
     98   DataTypeControllerMock* MakePasswordDTC() {
     99     DataTypeControllerMock* dtc = new DataTypeControllerMock();
    100     SetPasswordDTCExpectations(dtc);
    101     return dtc;
    102   }
    103 
    104   void SetPasswordDTCExpectations(DataTypeControllerMock* dtc) {
    105     EXPECT_CALL(*dtc, enabled()).WillRepeatedly(Return(true));
    106     EXPECT_CALL(*dtc, type()).WillRepeatedly(Return(syncable::PASSWORDS));
    107     EXPECT_CALL(*dtc, name()).WillRepeatedly(Return("passwords"));
    108   }
    109 
    110   void SetStartStopExpectations(DataTypeControllerMock* mock_dtc) {
    111     InSequence seq;
    112     EXPECT_CALL(*mock_dtc, state()).
    113         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    114     EXPECT_CALL(*mock_dtc, Start(_)).
    115         WillOnce(InvokeCallback((DataTypeController::OK)));
    116     EXPECT_CALL(*mock_dtc, state()).
    117         WillRepeatedly(Return(DataTypeController::RUNNING));
    118     EXPECT_CALL(*mock_dtc, Stop()).Times(1);
    119     EXPECT_CALL(*mock_dtc, state()).
    120         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    121   }
    122 
    123   void SetBusyStartStopExpectations(DataTypeControllerMock* mock_dtc,
    124                                     DataTypeController::State busy_state) {
    125     InSequence seq;
    126     EXPECT_CALL(*mock_dtc, state()).
    127         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    128     EXPECT_CALL(*mock_dtc, Start(_)).
    129         WillOnce(InvokeCallback((DataTypeController::OK)));
    130     EXPECT_CALL(*mock_dtc, state()).
    131         WillRepeatedly(Return(busy_state));
    132     EXPECT_CALL(*mock_dtc, Stop()).Times(1);
    133     EXPECT_CALL(*mock_dtc, state()).
    134         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    135   }
    136 
    137   void SetNotUsedExpectations(DataTypeControllerMock* mock_dtc) {
    138     EXPECT_CALL(*mock_dtc, Start(_)).Times(0);
    139     EXPECT_CALL(*mock_dtc, Stop()).Times(0);
    140     EXPECT_CALL(*mock_dtc, state()).
    141         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    142   }
    143 
    144   void SetConfigureStartExpectation() {
    145     EXPECT_CALL(
    146         observer_,
    147         Observe(NotificationType(NotificationType::SYNC_CONFIGURE_START),
    148                 _, _));
    149   }
    150 
    151 
    152   void SetConfigureDoneExpectation(DataTypeManager::ConfigureResult result) {
    153     EXPECT_CALL(
    154         observer_,
    155         Observe(NotificationType(NotificationType::SYNC_CONFIGURE_DONE), _,
    156         ::testing::ResultOf(&GetResult, result)));
    157   }
    158 
    159   MessageLoopForUI message_loop_;
    160   BrowserThread ui_thread_;
    161   DataTypeController::TypeMap controllers_;
    162   SyncBackendHostMock backend_;
    163   NotificationObserverMock observer_;
    164   NotificationRegistrar registrar_;
    165   std::set<syncable::ModelType> types_;
    166 };
    167 
    168 TEST_F(DataTypeManagerImpl2Test, NoControllers) {
    169   DataTypeManagerImpl dtm(&backend_, controllers_);
    170   SetConfigureStartExpectation();
    171   SetConfigureDoneExpectation(DataTypeManager::OK);
    172   dtm.Configure(types_);
    173   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    174   dtm.Stop();
    175   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    176 }
    177 
    178 TEST_F(DataTypeManagerImpl2Test, ConfigureOne) {
    179   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    180   SetStartStopExpectations(bookmark_dtc);
    181   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    182   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    183   DataTypeManagerImpl dtm(&backend_, controllers_);
    184   types_.insert(syncable::BOOKMARKS);
    185   SetConfigureStartExpectation();
    186   SetConfigureDoneExpectation(DataTypeManager::OK);
    187   dtm.Configure(types_);
    188   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    189   dtm.Stop();
    190   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    191 }
    192 
    193 TEST_F(DataTypeManagerImpl2Test, ConfigureOneStopWhileStarting) {
    194   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    195   SetBusyStartStopExpectations(bookmark_dtc,
    196                                DataTypeController::MODEL_STARTING);
    197   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    198   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    199   DataTypeManagerImpl dtm(&backend_, controllers_);
    200   types_.insert(syncable::BOOKMARKS);
    201   SetConfigureStartExpectation();
    202   SetConfigureDoneExpectation(DataTypeManager::OK);
    203   dtm.Configure(types_);
    204   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    205   dtm.Stop();
    206   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    207 }
    208 
    209 TEST_F(DataTypeManagerImpl2Test, ConfigureOneStopWhileAssociating) {
    210   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    211   SetBusyStartStopExpectations(bookmark_dtc, DataTypeController::ASSOCIATING);
    212   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    213   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    214   DataTypeManagerImpl dtm(&backend_, controllers_);
    215   types_.insert(syncable::BOOKMARKS);
    216   SetConfigureStartExpectation();
    217   SetConfigureDoneExpectation(DataTypeManager::OK);
    218   dtm.Configure(types_);
    219   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    220   dtm.Stop();
    221   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    222 }
    223 
    224 TEST_F(DataTypeManagerImpl2Test, OneWaitingForCrypto) {
    225   DataTypeControllerMock* password_dtc = MakePasswordDTC();
    226   EXPECT_CALL(*password_dtc, state()).Times(AtLeast(2)).
    227       WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    228   EXPECT_CALL(*password_dtc, Start(_)).
    229       WillOnce(InvokeCallback((DataTypeController::NEEDS_CRYPTO)));
    230 
    231   controllers_[syncable::PASSWORDS] = password_dtc;
    232   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    233 
    234   DataTypeManagerImpl dtm(&backend_, controllers_);
    235   types_.insert(syncable::PASSWORDS);
    236   SetConfigureStartExpectation();
    237 
    238   dtm.Configure(types_);
    239   EXPECT_EQ(DataTypeManager::BLOCKED, dtm.state());
    240 
    241   Mock::VerifyAndClearExpectations(&backend_);
    242   Mock::VerifyAndClearExpectations(&observer_);
    243   Mock::VerifyAndClearExpectations(password_dtc);
    244 
    245   SetConfigureDoneExpectation(DataTypeManager::OK);
    246   SetPasswordDTCExpectations(password_dtc);
    247   EXPECT_CALL(*password_dtc, state()).
    248       WillOnce(Return(DataTypeController::NOT_RUNNING)).
    249       WillRepeatedly(Return(DataTypeController::RUNNING));
    250   EXPECT_CALL(*password_dtc, Start(_)).
    251       WillOnce(InvokeCallback((DataTypeController::OK)));
    252   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    253   dtm.Configure(types_);
    254 
    255   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    256   EXPECT_CALL(*password_dtc, Stop()).Times(1);
    257   dtm.Stop();
    258   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    259 }
    260 
    261 TEST_F(DataTypeManagerImpl2Test, ConfigureOneThenAnother) {
    262   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    263   SetStartStopExpectations(bookmark_dtc);
    264   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    265   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    266   SetStartStopExpectations(preference_dtc);
    267   controllers_[syncable::PREFERENCES] = preference_dtc;
    268 
    269   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(2);
    270   DataTypeManagerImpl dtm(&backend_, controllers_);
    271   types_.insert(syncable::BOOKMARKS);
    272 
    273   SetConfigureStartExpectation();
    274   SetConfigureDoneExpectation(DataTypeManager::OK);
    275   dtm.Configure(types_);
    276   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    277 
    278   types_.insert(syncable::PREFERENCES);
    279   SetConfigureStartExpectation();
    280   SetConfigureDoneExpectation(DataTypeManager::OK);
    281   dtm.Configure(types_);
    282   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    283 
    284   dtm.Stop();
    285   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    286 }
    287 
    288 TEST_F(DataTypeManagerImpl2Test, ConfigureOneThenSwitch) {
    289   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    290   SetStartStopExpectations(bookmark_dtc);
    291   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    292   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    293   SetStartStopExpectations(preference_dtc);
    294   controllers_[syncable::PREFERENCES] = preference_dtc;
    295 
    296   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(2);
    297   DataTypeManagerImpl dtm(&backend_, controllers_);
    298   types_.insert(syncable::BOOKMARKS);
    299 
    300   SetConfigureStartExpectation();
    301   SetConfigureDoneExpectation(DataTypeManager::OK);
    302   dtm.Configure(types_);
    303   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    304 
    305   types_.clear();
    306   types_.insert(syncable::PREFERENCES);
    307   SetConfigureStartExpectation();
    308   SetConfigureDoneExpectation(DataTypeManager::OK);
    309   dtm.Configure(types_);
    310   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    311 
    312   dtm.Stop();
    313   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    314 }
    315 
    316 void DoConfigureDataTypes(
    317     const DataTypeController::TypeMap& data_type_controllers,
    318     const syncable::ModelTypeSet& types,
    319     CancelableTask* ready_task) {
    320   ready_task->Run();
    321   delete ready_task;
    322 }
    323 
    324 void QuitMessageLoop() {
    325   MessageLoop::current()->Quit();
    326 }
    327 
    328 TEST_F(DataTypeManagerImpl2Test, ConfigureWhileOneInFlight) {
    329   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    330   // Save the callback here so we can interrupt startup.
    331   DataTypeController::StartCallback* callback;
    332   {
    333     InSequence seq;
    334     EXPECT_CALL(*bookmark_dtc, state()).
    335         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    336     EXPECT_CALL(*bookmark_dtc, Start(_)).
    337         WillOnce(SaveArg<0>(&callback));
    338     EXPECT_CALL(*bookmark_dtc, state()).
    339         WillRepeatedly(Return(DataTypeController::RUNNING));
    340     EXPECT_CALL(*bookmark_dtc, Stop()).Times(1);
    341     EXPECT_CALL(*bookmark_dtc, state()).
    342         WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    343   }
    344   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    345 
    346   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    347   SetStartStopExpectations(preference_dtc);
    348   controllers_[syncable::PREFERENCES] = preference_dtc;
    349 
    350   DataTypeManagerImpl dtm(&backend_, controllers_);
    351   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _))
    352     .WillOnce(Invoke(DoConfigureDataTypes))
    353     .WillOnce(DoAll(Invoke(DoConfigureDataTypes),
    354      InvokeWithoutArgs(QuitMessageLoop)));
    355 
    356   types_.insert(syncable::BOOKMARKS);
    357 
    358   SetConfigureStartExpectation();
    359   SetConfigureDoneExpectation(DataTypeManager::OK);
    360   dtm.Configure(types_);
    361 
    362   // At this point, the bookmarks dtc should be in flight.  Add
    363   // preferences and continue starting bookmarks.
    364   types_.insert(syncable::PREFERENCES);
    365   dtm.Configure(types_);
    366   callback->Run(DataTypeController::OK, FROM_HERE);
    367   delete callback;
    368 
    369   MessageLoop::current()->Run();
    370 
    371   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    372 
    373   dtm.Stop();
    374   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    375 }
    376 
    377 TEST_F(DataTypeManagerImpl2Test, OneFailingController) {
    378   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    379   EXPECT_CALL(*bookmark_dtc, Start(_)).
    380       WillOnce(InvokeCallback((DataTypeController::ASSOCIATION_FAILED)));
    381   EXPECT_CALL(*bookmark_dtc, Stop()).Times(0);
    382   EXPECT_CALL(*bookmark_dtc, state()).
    383       WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    384   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    385 
    386   DataTypeManagerImpl dtm(&backend_, controllers_);
    387   SetConfigureStartExpectation();
    388   SetConfigureDoneExpectation(DataTypeManager::ASSOCIATION_FAILED);
    389   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    390 
    391   types_.insert(syncable::BOOKMARKS);
    392   dtm.Configure(types_);
    393   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    394 }
    395 
    396 TEST_F(DataTypeManagerImpl2Test, StopWhileInFlight) {
    397   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    398   SetStartStopExpectations(bookmark_dtc);
    399   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    400 
    401   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    402   // Save the callback here so we can interrupt startup.
    403   DataTypeController::StartCallback* callback;
    404   EXPECT_CALL(*preference_dtc, Start(_)).
    405       WillOnce(SaveArg<0>(&callback));
    406   EXPECT_CALL(*preference_dtc, state()).
    407       WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    408   controllers_[syncable::PREFERENCES] = preference_dtc;
    409 
    410   DataTypeManagerImpl dtm(&backend_, controllers_);
    411   SetConfigureStartExpectation();
    412   SetConfigureDoneExpectation(DataTypeManager::ABORTED);
    413   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    414 
    415   types_.insert(syncable::BOOKMARKS);
    416   types_.insert(syncable::PREFERENCES);
    417   dtm.Configure(types_);
    418   // Configure should stop in the CONFIGURING state because we are
    419   // waiting for the preferences callback to be invoked.
    420   EXPECT_EQ(DataTypeManager::CONFIGURING, dtm.state());
    421 
    422   // Call stop before the preference callback is invoked.
    423   EXPECT_CALL(*preference_dtc, Stop()).
    424       WillOnce(InvokeCallbackPointer(callback, DataTypeController::ABORTED));
    425   dtm.Stop();
    426   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    427 }
    428 
    429 TEST_F(DataTypeManagerImpl2Test, SecondControllerFails) {
    430   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    431   SetStartStopExpectations(bookmark_dtc);
    432   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    433 
    434   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    435   EXPECT_CALL(*preference_dtc, Start(_)).
    436       WillOnce(InvokeCallback((DataTypeController::ASSOCIATION_FAILED)));
    437   EXPECT_CALL(*preference_dtc, Stop()).Times(0);
    438   EXPECT_CALL(*preference_dtc, state()).
    439       WillRepeatedly(Return(DataTypeController::NOT_RUNNING));
    440   controllers_[syncable::PREFERENCES] = preference_dtc;
    441 
    442   DataTypeManagerImpl dtm(&backend_, controllers_);
    443   SetConfigureStartExpectation();
    444   SetConfigureDoneExpectation(DataTypeManager::ASSOCIATION_FAILED);
    445   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).Times(1);
    446 
    447   types_.insert(syncable::BOOKMARKS);
    448   types_.insert(syncable::PREFERENCES);
    449   dtm.Configure(types_);
    450   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    451 }
    452 
    453 TEST_F(DataTypeManagerImpl2Test, ConfigureWhileDownloadPending) {
    454   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    455   SetStartStopExpectations(bookmark_dtc);
    456   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    457 
    458   DataTypeControllerMock* preference_dtc = MakePreferenceDTC();
    459   SetStartStopExpectations(preference_dtc);
    460   controllers_[syncable::PREFERENCES] = preference_dtc;
    461 
    462   DataTypeManagerImpl dtm(&backend_, controllers_);
    463   SetConfigureStartExpectation();
    464   SetConfigureDoneExpectation(DataTypeManager::OK);
    465   CancelableTask* task;
    466   // Grab the task the first time this is called so we can configure
    467   // before it is finished.
    468   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).
    469       WillOnce(SaveArg<2>(&task)).
    470       WillOnce(DoDefault());
    471 
    472   types_.insert(syncable::BOOKMARKS);
    473   dtm.Configure(types_);
    474   // Configure should stop in the DOWNLOAD_PENDING state because we
    475   // are waiting for the download ready task to be run.
    476   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm.state());
    477 
    478   types_.insert(syncable::PREFERENCES);
    479   dtm.Configure(types_);
    480 
    481   // Running the task will queue a restart task to the message loop, and
    482   // eventually get us configured.
    483   task->Run();
    484   delete task;
    485   MessageLoop::current()->RunAllPending();
    486   EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
    487 
    488   dtm.Stop();
    489   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    490 }
    491 
    492 TEST_F(DataTypeManagerImpl2Test, StopWhileDownloadPending) {
    493   DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
    494   SetNotUsedExpectations(bookmark_dtc);
    495   controllers_[syncable::BOOKMARKS] = bookmark_dtc;
    496 
    497   DataTypeManagerImpl dtm(&backend_, controllers_);
    498   SetConfigureStartExpectation();
    499   SetConfigureDoneExpectation(DataTypeManager::ABORTED);
    500   CancelableTask* task;
    501   // Grab the task the first time this is called so we can stop
    502   // before it is finished.
    503   EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _)).
    504       WillOnce(SaveArg<2>(&task));
    505 
    506   types_.insert(syncable::BOOKMARKS);
    507   dtm.Configure(types_);
    508   // Configure should stop in the DOWNLOAD_PENDING state because we
    509   // are waiting for the download ready task to be run.
    510   EXPECT_EQ(DataTypeManager::DOWNLOAD_PENDING, dtm.state());
    511 
    512   dtm.Stop();
    513   EXPECT_EQ(DataTypeManager::STOPPED, dtm.state());
    514 
    515   // It should be perfectly safe to run this task even though the DTM
    516   // has been stopped.
    517   task->Run();
    518   delete task;
    519 }
    520