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.
5 #include "chrome/browser/sync/glue/sync_backend_registrar.h"
7 #include "chrome/browser/sync/glue/change_processor_mock.h"
8 #include "chrome/browser/sync/glue/ui_model_worker.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "content/public/test/test_browser_thread.h"
11 #include "sync/internal_api/public/base/model_type.h"
12 #include "sync/internal_api/public/test/test_user_share.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace browser_sync {
21 using ::testing::InSequence;
22 using ::testing::Return;
23 using ::testing::StrictMock;
24 using content::BrowserThread;
25 using syncer::FIRST_REAL_MODEL_TYPE;
26 using syncer::AUTOFILL;
27 using syncer::BOOKMARKS;
28 using syncer::PREFERENCES;
31 using syncer::PASSWORDS;
32 using syncer::MODEL_TYPE_COUNT;
33 using syncer::ModelTypeSet;
34 using syncer::ModelType;
35 using syncer::ModelTypeFromInt;
37 void TriggerChanges(SyncBackendRegistrar* registrar, ModelType type) {
38 registrar->OnChangesApplied(type, 0, NULL,
39 syncer::ImmutableChangeRecordList());
40 registrar->OnChangesComplete(type);
43 class SyncBackendRegistrarTest : public testing::Test {
45 void TestNonUIDataTypeActivationAsync(ChangeProcessor* processor,
46 base::WaitableEvent* done) {
47 registrar_->ActivateDataType(AUTOFILL,
50 test_user_share_.user_share());
51 syncer::ModelSafeRoutingInfo expected_routing_info;
52 expected_routing_info[AUTOFILL] = syncer::GROUP_DB;
53 ExpectRoutingInfo(registrar_.get(), expected_routing_info);
54 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet(AUTOFILL));
55 TriggerChanges(registrar_.get(), AUTOFILL);
60 SyncBackendRegistrarTest() :
62 ui_thread_(BrowserThread::UI, &ui_loop_),
63 db_thread_(BrowserThread::DB),
64 file_thread_(BrowserThread::FILE),
65 io_thread_(BrowserThread::IO) {}
67 virtual ~SyncBackendRegistrarTest() {}
69 virtual void SetUp() {
73 test_user_share_.SetUp();
74 registrar_.reset(new SyncBackendRegistrar("test", &profile_,
75 scoped_ptr<base::Thread>()));
76 sync_thread_ = registrar_->sync_thread();
79 virtual void TearDown() {
80 registrar_->RequestWorkerStopOnUIThread();
81 test_user_share_.TearDown();
82 sync_thread_->message_loop()->PostTask(
84 base::Bind(&SyncBackendRegistrar::Shutdown,
85 base::Unretained(registrar_.release())));
86 sync_thread_->message_loop()->RunUntilIdle();
92 void ExpectRoutingInfo(
93 SyncBackendRegistrar* registrar,
94 const syncer::ModelSafeRoutingInfo& expected_routing_info) {
95 syncer::ModelSafeRoutingInfo routing_info;
96 registrar->GetModelSafeRoutingInfo(&routing_info);
97 EXPECT_EQ(expected_routing_info, routing_info);
100 void ExpectHasProcessorsForTypes(const SyncBackendRegistrar& registrar,
101 ModelTypeSet types) {
102 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
103 ModelType model_type = ModelTypeFromInt(i);
104 EXPECT_EQ(types.Has(model_type),
105 registrar_->IsTypeActivatedForTest(model_type));
109 base::MessageLoop ui_loop_;
110 syncer::TestUserShare test_user_share_;
111 TestingProfile profile_;
112 scoped_ptr<SyncBackendRegistrar> registrar_;
114 base::Thread* sync_thread_;
115 content::TestBrowserThread ui_thread_;
116 content::TestBrowserThread db_thread_;
117 content::TestBrowserThread file_thread_;
118 content::TestBrowserThread io_thread_;
121 TEST_F(SyncBackendRegistrarTest, ConstructorEmpty) {
122 registrar_->SetInitialTypes(ModelTypeSet());
123 EXPECT_FALSE(registrar_->IsNigoriEnabled());
125 std::vector<syncer::ModelSafeWorker*> workers;
126 registrar_->GetWorkers(&workers);
127 EXPECT_EQ(4u, workers.size());
129 ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
130 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
133 TEST_F(SyncBackendRegistrarTest, ConstructorNonEmpty) {
134 const ModelTypeSet initial_types(BOOKMARKS, NIGORI, PASSWORDS);
135 registrar_->SetInitialTypes(initial_types);
136 EXPECT_TRUE(registrar_->IsNigoriEnabled());
138 std::vector<syncer::ModelSafeWorker*> workers;
139 registrar_->GetWorkers(&workers);
140 EXPECT_EQ(4u, workers.size());
143 syncer::ModelSafeRoutingInfo expected_routing_info;
144 expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
145 expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
146 // Passwords dropped because of no password store.
147 ExpectRoutingInfo(registrar_.get(), expected_routing_info);
149 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
152 TEST_F(SyncBackendRegistrarTest, ConfigureDataTypes) {
153 registrar_->SetInitialTypes(ModelTypeSet());
156 const ModelTypeSet types1(BOOKMARKS, NIGORI, AUTOFILL);
158 registrar_->ConfigureDataTypes(types1, ModelTypeSet()).Equals(types1));
160 syncer::ModelSafeRoutingInfo expected_routing_info;
161 expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
162 expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
163 expected_routing_info[AUTOFILL] = syncer::GROUP_PASSIVE;
164 ExpectRoutingInfo(registrar_.get(), expected_routing_info);
166 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
167 EXPECT_TRUE(types1.Equals(registrar_->GetLastConfiguredTypes()));
170 const ModelTypeSet types2(PREFERENCES, THEMES);
171 EXPECT_TRUE(registrar_->ConfigureDataTypes(types2, types1).Equals(types2));
173 syncer::ModelSafeRoutingInfo expected_routing_info;
174 expected_routing_info[PREFERENCES] = syncer::GROUP_PASSIVE;
175 expected_routing_info[THEMES] = syncer::GROUP_PASSIVE;
176 ExpectRoutingInfo(registrar_.get(), expected_routing_info);
178 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
179 EXPECT_TRUE(types2.Equals(registrar_->GetLastConfiguredTypes()));
182 EXPECT_TRUE(registrar_->ConfigureDataTypes(ModelTypeSet(), types2).Empty());
183 ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
184 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
185 EXPECT_TRUE(ModelTypeSet().Equals(registrar_->GetLastConfiguredTypes()));
188 TEST_F(SyncBackendRegistrarTest, ActivateDeactivateUIDataType) {
189 InSequence in_sequence;
190 registrar_->SetInitialTypes(ModelTypeSet());
192 // Should do nothing.
193 TriggerChanges(registrar_.get(), BOOKMARKS);
195 StrictMock<ChangeProcessorMock> change_processor_mock;
196 EXPECT_CALL(change_processor_mock, StartImpl(&profile_));
197 EXPECT_CALL(change_processor_mock, IsRunning())
198 .WillRepeatedly(Return(true));
199 EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
200 EXPECT_CALL(change_processor_mock, IsRunning())
201 .WillRepeatedly(Return(true));
202 EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
203 EXPECT_CALL(change_processor_mock, IsRunning())
204 .WillRepeatedly(Return(false));
206 const ModelTypeSet types(BOOKMARKS);
208 registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
209 registrar_->ActivateDataType(BOOKMARKS, syncer::GROUP_UI,
210 &change_processor_mock,
211 test_user_share_.user_share());
213 syncer::ModelSafeRoutingInfo expected_routing_info;
214 expected_routing_info[BOOKMARKS] = syncer::GROUP_UI;
215 ExpectRoutingInfo(registrar_.get(), expected_routing_info);
217 ExpectHasProcessorsForTypes(*registrar_, types);
219 TriggerChanges(registrar_.get(), BOOKMARKS);
221 registrar_->DeactivateDataType(BOOKMARKS);
222 ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
223 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
225 // Should do nothing.
226 TriggerChanges(registrar_.get(), BOOKMARKS);
229 void ActiviateDoneOnDb(base::WaitableEvent* done) {
233 TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) {
234 InSequence in_sequence;
235 registrar_->SetInitialTypes(ModelTypeSet());
237 // Should do nothing.
238 TriggerChanges(registrar_.get(), AUTOFILL);
240 StrictMock<ChangeProcessorMock> change_processor_mock;
241 EXPECT_CALL(change_processor_mock, StartImpl(&profile_));
242 EXPECT_CALL(change_processor_mock, IsRunning())
243 .WillRepeatedly(Return(true));
244 EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
245 EXPECT_CALL(change_processor_mock, IsRunning())
246 .WillRepeatedly(Return(true));
247 EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
248 EXPECT_CALL(change_processor_mock, IsRunning())
249 .WillRepeatedly(Return(false));
251 const ModelTypeSet types(AUTOFILL);
253 registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
255 base::WaitableEvent done(false, false);
256 BrowserThread::PostTask(
259 base::Bind(&SyncBackendRegistrarTest::TestNonUIDataTypeActivationAsync,
260 base::Unretained(this),
261 &change_processor_mock,
265 registrar_->DeactivateDataType(AUTOFILL);
266 ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
267 ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
269 // Should do nothing.
270 TriggerChanges(registrar_.get(), AUTOFILL);
275 } // namespace browser_sync