Home | History | Annotate | Download | only in glue
      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/sync_backend_registrar.h"
      6 
      7 #include "chrome/browser/sync/glue/ui_model_worker.h"
      8 #include "chrome/test/base/testing_profile.h"
      9 #include "components/sync_driver/change_processor_mock.h"
     10 #include "content/public/browser/browser_thread.h"
     11 #include "content/public/test/test_browser_thread_bundle.h"
     12 #include "sync/internal_api/public/base/model_type.h"
     13 #include "sync/internal_api/public/test/test_user_share.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace browser_sync {
     18 
     19 namespace {
     20 
     21 using ::testing::_;
     22 using ::testing::InSequence;
     23 using ::testing::Return;
     24 using ::testing::StrictMock;
     25 using content::BrowserThread;
     26 using syncer::FIRST_REAL_MODEL_TYPE;
     27 using syncer::AUTOFILL;
     28 using syncer::BOOKMARKS;
     29 using syncer::PREFERENCES;
     30 using syncer::THEMES;
     31 using syncer::NIGORI;
     32 using syncer::PASSWORDS;
     33 using syncer::MODEL_TYPE_COUNT;
     34 using syncer::ModelTypeSet;
     35 using syncer::ModelType;
     36 using syncer::ModelTypeFromInt;
     37 
     38 void TriggerChanges(SyncBackendRegistrar* registrar, ModelType type) {
     39   registrar->OnChangesApplied(type, 0, NULL,
     40                               syncer::ImmutableChangeRecordList());
     41   registrar->OnChangesComplete(type);
     42 }
     43 
     44 class SyncBackendRegistrarTest : public testing::Test {
     45  public:
     46   void TestNonUIDataTypeActivationAsync(ChangeProcessor* processor,
     47                                         base::WaitableEvent* done) {
     48     registrar_->ActivateDataType(AUTOFILL,
     49                                  syncer::GROUP_DB,
     50                                  processor,
     51                                  test_user_share_.user_share());
     52     syncer::ModelSafeRoutingInfo expected_routing_info;
     53     expected_routing_info[AUTOFILL] = syncer::GROUP_DB;
     54     ExpectRoutingInfo(registrar_.get(), expected_routing_info);
     55     ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet(AUTOFILL));
     56     TriggerChanges(registrar_.get(), AUTOFILL);
     57     done->Signal();
     58   }
     59 
     60  protected:
     61   SyncBackendRegistrarTest()
     62       : sync_thread_(NULL),
     63         thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD |
     64                        content::TestBrowserThreadBundle::REAL_FILE_THREAD |
     65                        content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
     66 
     67   virtual ~SyncBackendRegistrarTest() {}
     68 
     69   virtual void SetUp() {
     70     test_user_share_.SetUp();
     71     registrar_.reset(new SyncBackendRegistrar("test", &profile_,
     72                                               scoped_ptr<base::Thread>()));
     73     sync_thread_ = registrar_->sync_thread();
     74   }
     75 
     76   virtual void TearDown() {
     77     registrar_->RequestWorkerStopOnUIThread();
     78     test_user_share_.TearDown();
     79     sync_thread_->message_loop()->PostTask(
     80         FROM_HERE,
     81         base::Bind(&SyncBackendRegistrar::Shutdown,
     82                    base::Unretained(registrar_.release())));
     83     sync_thread_->message_loop()->RunUntilIdle();
     84   }
     85 
     86   void ExpectRoutingInfo(
     87       SyncBackendRegistrar* registrar,
     88       const syncer::ModelSafeRoutingInfo& expected_routing_info) {
     89     syncer::ModelSafeRoutingInfo routing_info;
     90     registrar->GetModelSafeRoutingInfo(&routing_info);
     91     EXPECT_EQ(expected_routing_info, routing_info);
     92   }
     93 
     94   void ExpectHasProcessorsForTypes(const SyncBackendRegistrar& registrar,
     95                                    ModelTypeSet types) {
     96     for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
     97       ModelType model_type = ModelTypeFromInt(i);
     98       EXPECT_EQ(types.Has(model_type),
     99                 registrar_->IsTypeActivatedForTest(model_type));
    100     }
    101   }
    102 
    103   syncer::TestUserShare test_user_share_;
    104   TestingProfile profile_;
    105   scoped_ptr<SyncBackendRegistrar> registrar_;
    106 
    107   base::Thread* sync_thread_;
    108   content::TestBrowserThreadBundle thread_bundle_;
    109 };
    110 
    111 TEST_F(SyncBackendRegistrarTest, ConstructorEmpty) {
    112   registrar_->SetInitialTypes(ModelTypeSet());
    113   EXPECT_FALSE(registrar_->IsNigoriEnabled());
    114   {
    115     std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers;
    116     registrar_->GetWorkers(&workers);
    117     EXPECT_EQ(4u, workers.size());
    118   }
    119   ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
    120   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    121 }
    122 
    123 TEST_F(SyncBackendRegistrarTest, ConstructorNonEmpty) {
    124   const ModelTypeSet initial_types(BOOKMARKS, NIGORI, PASSWORDS);
    125   registrar_->SetInitialTypes(initial_types);
    126   EXPECT_TRUE(registrar_->IsNigoriEnabled());
    127   {
    128     std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers;
    129     registrar_->GetWorkers(&workers);
    130     EXPECT_EQ(4u, workers.size());
    131   }
    132   {
    133     syncer::ModelSafeRoutingInfo expected_routing_info;
    134     expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
    135     expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
    136     // Passwords dropped because of no password store.
    137     ExpectRoutingInfo(registrar_.get(), expected_routing_info);
    138   }
    139   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    140 }
    141 
    142 TEST_F(SyncBackendRegistrarTest, ConfigureDataTypes) {
    143   registrar_->SetInitialTypes(ModelTypeSet());
    144 
    145   // Add.
    146   const ModelTypeSet types1(BOOKMARKS, NIGORI, AUTOFILL);
    147   EXPECT_TRUE(
    148       registrar_->ConfigureDataTypes(types1, ModelTypeSet()).Equals(types1));
    149   {
    150     syncer::ModelSafeRoutingInfo expected_routing_info;
    151     expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
    152     expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
    153     expected_routing_info[AUTOFILL] = syncer::GROUP_PASSIVE;
    154     ExpectRoutingInfo(registrar_.get(), expected_routing_info);
    155   }
    156   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    157   EXPECT_TRUE(types1.Equals(registrar_->GetLastConfiguredTypes()));
    158 
    159   // Add and remove.
    160   const ModelTypeSet types2(PREFERENCES, THEMES);
    161   EXPECT_TRUE(registrar_->ConfigureDataTypes(types2, types1).Equals(types2));
    162   {
    163     syncer::ModelSafeRoutingInfo expected_routing_info;
    164     expected_routing_info[PREFERENCES] = syncer::GROUP_PASSIVE;
    165     expected_routing_info[THEMES] = syncer::GROUP_PASSIVE;
    166     ExpectRoutingInfo(registrar_.get(), expected_routing_info);
    167   }
    168   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    169   EXPECT_TRUE(types2.Equals(registrar_->GetLastConfiguredTypes()));
    170 
    171   // Remove.
    172   EXPECT_TRUE(registrar_->ConfigureDataTypes(ModelTypeSet(), types2).Empty());
    173   ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
    174   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    175   EXPECT_TRUE(ModelTypeSet().Equals(registrar_->GetLastConfiguredTypes()));
    176 }
    177 
    178 TEST_F(SyncBackendRegistrarTest, ActivateDeactivateUIDataType) {
    179   InSequence in_sequence;
    180   registrar_->SetInitialTypes(ModelTypeSet());
    181 
    182   // Should do nothing.
    183   TriggerChanges(registrar_.get(), BOOKMARKS);
    184 
    185   StrictMock<ChangeProcessorMock> change_processor_mock;
    186   EXPECT_CALL(change_processor_mock, StartImpl());
    187   EXPECT_CALL(change_processor_mock, IsRunning())
    188       .WillRepeatedly(Return(true));
    189   EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
    190   EXPECT_CALL(change_processor_mock, IsRunning())
    191       .WillRepeatedly(Return(true));
    192   EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
    193   EXPECT_CALL(change_processor_mock, IsRunning())
    194       .WillRepeatedly(Return(false));
    195 
    196   const ModelTypeSet types(BOOKMARKS);
    197   EXPECT_TRUE(
    198       registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
    199   registrar_->ActivateDataType(BOOKMARKS, syncer::GROUP_UI,
    200                              &change_processor_mock,
    201                              test_user_share_.user_share());
    202   {
    203     syncer::ModelSafeRoutingInfo expected_routing_info;
    204     expected_routing_info[BOOKMARKS] = syncer::GROUP_UI;
    205     ExpectRoutingInfo(registrar_.get(), expected_routing_info);
    206   }
    207   ExpectHasProcessorsForTypes(*registrar_, types);
    208 
    209   TriggerChanges(registrar_.get(), BOOKMARKS);
    210 
    211   registrar_->DeactivateDataType(BOOKMARKS);
    212   ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
    213   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    214 
    215   // Should do nothing.
    216   TriggerChanges(registrar_.get(), BOOKMARKS);
    217 }
    218 
    219 TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) {
    220   InSequence in_sequence;
    221   registrar_->SetInitialTypes(ModelTypeSet());
    222 
    223   // Should do nothing.
    224   TriggerChanges(registrar_.get(), AUTOFILL);
    225 
    226   StrictMock<ChangeProcessorMock> change_processor_mock;
    227   EXPECT_CALL(change_processor_mock, StartImpl());
    228   EXPECT_CALL(change_processor_mock, IsRunning())
    229       .WillRepeatedly(Return(true));
    230   EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
    231   EXPECT_CALL(change_processor_mock, IsRunning())
    232       .WillRepeatedly(Return(true));
    233   EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
    234   EXPECT_CALL(change_processor_mock, IsRunning())
    235       .WillRepeatedly(Return(false));
    236 
    237   const ModelTypeSet types(AUTOFILL);
    238   EXPECT_TRUE(
    239       registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
    240 
    241   base::WaitableEvent done(false, false);
    242   BrowserThread::PostTask(
    243       BrowserThread::DB,
    244       FROM_HERE,
    245       base::Bind(&SyncBackendRegistrarTest::TestNonUIDataTypeActivationAsync,
    246                  base::Unretained(this),
    247                  &change_processor_mock,
    248                  &done));
    249   done.Wait();
    250 
    251   registrar_->DeactivateDataType(AUTOFILL);
    252   ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
    253   ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
    254 
    255   // Should do nothing.
    256   TriggerChanges(registrar_.get(), AUTOFILL);
    257 }
    258 
    259 }  // namespace
    260 
    261 }  // namespace browser_sync
    262