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