OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/sync/driver/non_ui_model_type_controller.h" | 5 #include "components/sync/driver/non_ui_model_type_controller.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
18 #include "base/sequenced_task_runner.h" | 18 #include "base/sequenced_task_runner.h" |
19 #include "base/test/test_simple_task_runner.h" | 19 #include "base/test/test_simple_task_runner.h" |
20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
21 #include "components/sync/api/stub_model_type_service.h" | 21 #include "components/sync/api/stub_model_type_service.h" |
22 #include "components/sync/core/activation_context.h" | 22 #include "components/sync/core/activation_context.h" |
23 #include "components/sync/core/shared_model_type_processor.h" | 23 #include "components/sync/core/shared_model_type_processor.h" |
24 #include "components/sync/driver/backend_data_type_configurer.h" | 24 #include "components/sync/driver/backend_data_type_configurer.h" |
25 #include "components/sync/driver/fake_sync_client.h" | 25 #include "components/sync/driver/fake_sync_client.h" |
26 #include "components/sync/engine/commit_queue.h" | 26 #include "components/sync/engine/commit_queue.h" |
27 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
28 | 28 |
29 namespace sync_driver_v2 { | 29 namespace syncer { |
30 | 30 |
31 namespace { | 31 namespace { |
32 | 32 |
33 // Test controller derived from NonUIModelTypeController. | 33 // Test controller derived from NonUIModelTypeController. |
34 class TestNonUIModelTypeController : public NonUIModelTypeController { | 34 class TestNonUIModelTypeController : public NonUIModelTypeController { |
35 public: | 35 public: |
36 TestNonUIModelTypeController( | 36 TestNonUIModelTypeController( |
37 syncer::ModelType model_type, | 37 ModelType model_type, |
38 const scoped_refptr<base::TaskRunner>& model_task_runner, | 38 const scoped_refptr<base::TaskRunner>& model_task_runner, |
39 const base::Closure& dump_stack, | 39 const base::Closure& dump_stack, |
40 sync_driver::SyncClient* sync_client) | 40 SyncClient* sync_client) |
41 : NonUIModelTypeController(model_type, dump_stack, sync_client), | 41 : NonUIModelTypeController(model_type, dump_stack, sync_client), |
42 model_task_runner_(model_task_runner) {} | 42 model_task_runner_(model_task_runner) {} |
43 ~TestNonUIModelTypeController() override {} | 43 ~TestNonUIModelTypeController() override {} |
44 | 44 |
45 bool RunOnModelThread(const tracked_objects::Location& from_here, | 45 bool RunOnModelThread(const tracked_objects::Location& from_here, |
46 const base::Closure& task) override { | 46 const base::Closure& task) override { |
47 DCHECK(model_task_runner_); | 47 DCHECK(model_task_runner_); |
48 return model_task_runner_->PostTask(from_here, task); | 48 return model_task_runner_->PostTask(from_here, task); |
49 } | 49 } |
50 | 50 |
51 private: | 51 private: |
52 scoped_refptr<base::TaskRunner> model_task_runner_; | 52 scoped_refptr<base::TaskRunner> model_task_runner_; |
53 }; | 53 }; |
54 | 54 |
55 // A no-op instance of CommitQueue. | 55 // A no-op instance of CommitQueue. |
56 class NullCommitQueue : public syncer_v2::CommitQueue { | 56 class NullCommitQueue : public CommitQueue { |
57 public: | 57 public: |
58 NullCommitQueue() {} | 58 NullCommitQueue() {} |
59 ~NullCommitQueue() override {} | 59 ~NullCommitQueue() override {} |
60 | 60 |
61 void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { | 61 void EnqueueForCommit(const CommitRequestDataList& list) override { |
62 NOTREACHED() << "Not implemented."; | 62 NOTREACHED() << "Not implemented."; |
63 } | 63 } |
64 }; | 64 }; |
65 | 65 |
66 // A class that pretends to be the sync backend. | 66 // A class that pretends to be the sync backend. |
67 class MockSyncBackend { | 67 class MockSyncBackend { |
68 public: | 68 public: |
69 void Connect( | 69 void Connect(ModelType type, |
70 syncer::ModelType type, | 70 std::unique_ptr<ActivationContext> activation_context) { |
71 std::unique_ptr<syncer_v2::ActivationContext> activation_context) { | |
72 enabled_types_.Put(type); | 71 enabled_types_.Put(type); |
73 activation_context->type_processor->ConnectSync( | 72 activation_context->type_processor->ConnectSync( |
74 base::MakeUnique<NullCommitQueue>()); | 73 base::MakeUnique<NullCommitQueue>()); |
75 } | 74 } |
76 | 75 |
77 void Disconnect(syncer::ModelType type) { | 76 void Disconnect(ModelType type) { |
78 DCHECK(enabled_types_.Has(type)); | 77 DCHECK(enabled_types_.Has(type)); |
79 enabled_types_.Remove(type); | 78 enabled_types_.Remove(type); |
80 } | 79 } |
81 | 80 |
82 private: | 81 private: |
83 syncer::ModelTypeSet enabled_types_; | 82 ModelTypeSet enabled_types_; |
84 }; | 83 }; |
85 | 84 |
86 // Fake implementation of BackendDataTypeConfigurer that pretends to be Sync | 85 // Fake implementation of BackendDataTypeConfigurer that pretends to be Sync |
87 // backend. | 86 // backend. |
88 class MockBackendDataTypeConfigurer | 87 class MockBackendDataTypeConfigurer : public BackendDataTypeConfigurer { |
89 : public sync_driver::BackendDataTypeConfigurer { | |
90 public: | 88 public: |
91 MockBackendDataTypeConfigurer( | 89 MockBackendDataTypeConfigurer( |
92 MockSyncBackend* backend, | 90 MockSyncBackend* backend, |
93 const scoped_refptr<base::TaskRunner>& sync_task_runner) | 91 const scoped_refptr<base::TaskRunner>& sync_task_runner) |
94 : backend_(backend), sync_task_runner_(sync_task_runner) {} | 92 : backend_(backend), sync_task_runner_(sync_task_runner) {} |
95 ~MockBackendDataTypeConfigurer() override {} | 93 ~MockBackendDataTypeConfigurer() override {} |
96 | 94 |
97 syncer::ModelTypeSet ConfigureDataTypes( | 95 ModelTypeSet ConfigureDataTypes( |
98 syncer::ConfigureReason reason, | 96 ConfigureReason reason, |
99 const DataTypeConfigStateMap& config_state_map, | 97 const DataTypeConfigStateMap& config_state_map, |
100 const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& | 98 const base::Callback<void(ModelTypeSet, ModelTypeSet)>& ready_task, |
101 ready_task, | |
102 const base::Callback<void()>& retry_callback) override { | 99 const base::Callback<void()>& retry_callback) override { |
103 NOTREACHED() << "Not implemented."; | 100 NOTREACHED() << "Not implemented."; |
104 return syncer::ModelTypeSet(); | 101 return ModelTypeSet(); |
105 } | 102 } |
106 | 103 |
107 void ActivateDirectoryDataType( | 104 void ActivateDirectoryDataType(ModelType type, |
108 syncer::ModelType type, | 105 ModelSafeGroup group, |
109 syncer::ModelSafeGroup group, | 106 ChangeProcessor* change_processor) override { |
110 sync_driver::ChangeProcessor* change_processor) override { | |
111 NOTREACHED() << "Not implemented."; | 107 NOTREACHED() << "Not implemented."; |
112 } | 108 } |
113 | 109 |
114 void DeactivateDirectoryDataType(syncer::ModelType type) override { | 110 void DeactivateDirectoryDataType(ModelType type) override { |
115 NOTREACHED() << "Not implemented."; | 111 NOTREACHED() << "Not implemented."; |
116 } | 112 } |
117 | 113 |
118 void ActivateNonBlockingDataType(syncer::ModelType type, | 114 void ActivateNonBlockingDataType( |
119 std::unique_ptr<syncer_v2::ActivationContext> | 115 ModelType type, |
120 activation_context) override { | 116 std::unique_ptr<ActivationContext> activation_context) override { |
121 // Post on Sync thread just like the real implementation does. | 117 // Post on Sync thread just like the real implementation does. |
122 sync_task_runner_->PostTask( | 118 sync_task_runner_->PostTask( |
123 FROM_HERE, | 119 FROM_HERE, |
124 base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, | 120 base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, |
125 base::Passed(std::move(activation_context)))); | 121 base::Passed(std::move(activation_context)))); |
126 } | 122 } |
127 | 123 |
128 void DeactivateNonBlockingDataType(syncer::ModelType type) override { | 124 void DeactivateNonBlockingDataType(ModelType type) override { |
129 sync_task_runner_->PostTask(FROM_HERE, | 125 sync_task_runner_->PostTask(FROM_HERE, |
130 base::Bind(&MockSyncBackend::Disconnect, | 126 base::Bind(&MockSyncBackend::Disconnect, |
131 base::Unretained(backend_), type)); | 127 base::Unretained(backend_), type)); |
132 } | 128 } |
133 | 129 |
134 private: | 130 private: |
135 MockSyncBackend* backend_; | 131 MockSyncBackend* backend_; |
136 scoped_refptr<base::TaskRunner> sync_task_runner_; | 132 scoped_refptr<base::TaskRunner> sync_task_runner_; |
137 }; | 133 }; |
138 | 134 |
139 } // namespace | 135 } // namespace |
140 | 136 |
141 class NonUIModelTypeControllerTest : public testing::Test, | 137 class NonUIModelTypeControllerTest : public testing::Test, |
142 public sync_driver::FakeSyncClient { | 138 public FakeSyncClient { |
143 public: | 139 public: |
144 NonUIModelTypeControllerTest() | 140 NonUIModelTypeControllerTest() |
145 : auto_run_tasks_(true), | 141 : auto_run_tasks_(true), |
146 load_models_callback_called_(false), | 142 load_models_callback_called_(false), |
147 association_callback_called_(false), | 143 association_callback_called_(false), |
148 model_thread_("modelthread"), | 144 model_thread_("modelthread"), |
149 configurer_(&backend_, ui_loop_.task_runner()) {} | 145 configurer_(&backend_, ui_loop_.task_runner()) {} |
150 | 146 |
151 ~NonUIModelTypeControllerTest() override {} | 147 ~NonUIModelTypeControllerTest() override {} |
152 | 148 |
153 void SetUp() override { | 149 void SetUp() override { |
154 model_thread_.Start(); | 150 model_thread_.Start(); |
155 model_thread_runner_ = model_thread_.task_runner(); | 151 model_thread_runner_ = model_thread_.task_runner(); |
156 InitializeModelTypeService(); | 152 InitializeModelTypeService(); |
157 controller_.reset(new TestNonUIModelTypeController( | 153 controller_.reset(new TestNonUIModelTypeController( |
158 syncer::DICTIONARY, model_thread_runner_, base::Closure(), this)); | 154 DICTIONARY, model_thread_runner_, base::Closure(), this)); |
159 } | 155 } |
160 | 156 |
161 void TearDown() override { | 157 void TearDown() override { |
162 ClearModelTypeService(); | 158 ClearModelTypeService(); |
163 RunQueuedUIThreadTasks(); | 159 RunQueuedUIThreadTasks(); |
164 } | 160 } |
165 | 161 |
166 base::WeakPtr<syncer_v2::ModelTypeService> GetModelTypeServiceForType( | 162 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( |
167 syncer::ModelType type) override { | 163 ModelType type) override { |
168 return service_->AsWeakPtr(); | 164 return service_->AsWeakPtr(); |
169 } | 165 } |
170 | 166 |
171 protected: | 167 protected: |
172 std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( | 168 std::unique_ptr<ModelTypeChangeProcessor> CreateProcessor( |
173 syncer::ModelType type, | 169 ModelType type, |
174 syncer_v2::ModelTypeService* service) { | 170 ModelTypeService* service) { |
175 std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = | 171 std::unique_ptr<SharedModelTypeProcessor> processor = |
176 base::MakeUnique<syncer_v2::SharedModelTypeProcessor>(type, service); | 172 base::MakeUnique<SharedModelTypeProcessor>(type, service); |
177 type_processor_ = processor.get(); | 173 type_processor_ = processor.get(); |
178 return std::move(processor); | 174 return std::move(processor); |
179 } | 175 } |
180 | 176 |
181 void InitializeModelTypeService() { | 177 void InitializeModelTypeService() { |
182 if (!model_thread_runner_ || | 178 if (!model_thread_runner_ || |
183 model_thread_runner_->BelongsToCurrentThread()) { | 179 model_thread_runner_->BelongsToCurrentThread()) { |
184 service_.reset(new syncer_v2::StubModelTypeService( | 180 service_.reset(new StubModelTypeService( |
185 base::Bind(&NonUIModelTypeControllerTest::CreateProcessor, | 181 base::Bind(&NonUIModelTypeControllerTest::CreateProcessor, |
186 base::Unretained(this)))); | 182 base::Unretained(this)))); |
187 } else { | 183 } else { |
188 model_thread_runner_->PostTask( | 184 model_thread_runner_->PostTask( |
189 FROM_HERE, | 185 FROM_HERE, |
190 base::Bind(&NonUIModelTypeControllerTest::InitializeModelTypeService, | 186 base::Bind(&NonUIModelTypeControllerTest::InitializeModelTypeService, |
191 base::Unretained(this))); | 187 base::Unretained(this))); |
192 RunQueuedModelThreadTasks(); | 188 RunQueuedModelThreadTasks(); |
193 } | 189 } |
194 } | 190 } |
(...skipping 20 matching lines...) Expand all Loading... |
215 FROM_HERE, | 211 FROM_HERE, |
216 base::Bind(&NonUIModelTypeControllerTest::ExpectProcessorConnected, | 212 base::Bind(&NonUIModelTypeControllerTest::ExpectProcessorConnected, |
217 base::Unretained(this), isConnected)); | 213 base::Unretained(this), isConnected)); |
218 RunQueuedModelThreadTasks(); | 214 RunQueuedModelThreadTasks(); |
219 } | 215 } |
220 } | 216 } |
221 | 217 |
222 void OnMetadataLoaded() { | 218 void OnMetadataLoaded() { |
223 if (model_thread_runner_->BelongsToCurrentThread()) { | 219 if (model_thread_runner_->BelongsToCurrentThread()) { |
224 if (!type_processor_->IsAllowingChanges()) { | 220 if (!type_processor_->IsAllowingChanges()) { |
225 type_processor_->OnMetadataLoaded( | 221 type_processor_->OnMetadataLoaded(SyncError(), |
226 syncer::SyncError(), base::MakeUnique<syncer_v2::MetadataBatch>()); | 222 base::MakeUnique<MetadataBatch>()); |
227 } | 223 } |
228 } else { | 224 } else { |
229 model_thread_runner_->PostTask( | 225 model_thread_runner_->PostTask( |
230 FROM_HERE, base::Bind(&NonUIModelTypeControllerTest::OnMetadataLoaded, | 226 FROM_HERE, base::Bind(&NonUIModelTypeControllerTest::OnMetadataLoaded, |
231 base::Unretained(this))); | 227 base::Unretained(this))); |
232 } | 228 } |
233 } | 229 } |
234 | 230 |
235 void LoadModels() { | 231 void LoadModels() { |
236 controller_->LoadModels(base::Bind( | 232 controller_->LoadModels(base::Bind( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 model_thread_runner_->PostTaskAndReply( | 277 model_thread_runner_->PostTaskAndReply( |
282 FROM_HERE, base::Bind(&base::DoNothing), | 278 FROM_HERE, base::Bind(&base::DoNothing), |
283 base::Bind(&base::RunLoop::Quit, base::Unretained(&run_loop))); | 279 base::Bind(&base::RunLoop::Quit, base::Unretained(&run_loop))); |
284 run_loop.Run(); | 280 run_loop.Run(); |
285 } | 281 } |
286 | 282 |
287 void SetAutoRunTasks(bool auto_run_tasks) { | 283 void SetAutoRunTasks(bool auto_run_tasks) { |
288 auto_run_tasks_ = auto_run_tasks; | 284 auto_run_tasks_ = auto_run_tasks; |
289 } | 285 } |
290 | 286 |
291 void LoadModelsDone(syncer::ModelType type, const syncer::SyncError& error) { | 287 void LoadModelsDone(ModelType type, const SyncError& error) { |
292 load_models_callback_called_ = true; | 288 load_models_callback_called_ = true; |
293 load_models_error_ = error; | 289 load_models_error_ = error; |
294 } | 290 } |
295 | 291 |
296 void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, | 292 void AssociationDone(DataTypeController::ConfigureResult result, |
297 const syncer::SyncMergeResult& local_merge_result, | 293 const SyncMergeResult& local_merge_result, |
298 const syncer::SyncMergeResult& syncer_merge_result) { | 294 const SyncMergeResult& syncer_merge_result) { |
299 EXPECT_EQ(sync_driver::DataTypeController::OK, result); | 295 EXPECT_EQ(DataTypeController::OK, result); |
300 association_callback_called_ = true; | 296 association_callback_called_ = true; |
301 } | 297 } |
302 | 298 |
303 syncer_v2::SharedModelTypeProcessor* type_processor_; | 299 SharedModelTypeProcessor* type_processor_; |
304 std::unique_ptr<TestNonUIModelTypeController> controller_; | 300 std::unique_ptr<TestNonUIModelTypeController> controller_; |
305 | 301 |
306 bool auto_run_tasks_; | 302 bool auto_run_tasks_; |
307 bool load_models_callback_called_; | 303 bool load_models_callback_called_; |
308 syncer::SyncError load_models_error_; | 304 SyncError load_models_error_; |
309 bool association_callback_called_; | 305 bool association_callback_called_; |
310 base::MessageLoopForUI ui_loop_; | 306 base::MessageLoopForUI ui_loop_; |
311 base::Thread model_thread_; | 307 base::Thread model_thread_; |
312 scoped_refptr<base::SingleThreadTaskRunner> model_thread_runner_; | 308 scoped_refptr<base::SingleThreadTaskRunner> model_thread_runner_; |
313 MockSyncBackend backend_; | 309 MockSyncBackend backend_; |
314 MockBackendDataTypeConfigurer configurer_; | 310 MockBackendDataTypeConfigurer configurer_; |
315 std::unique_ptr<syncer_v2::StubModelTypeService> service_; | 311 std::unique_ptr<StubModelTypeService> service_; |
316 }; | 312 }; |
317 | 313 |
318 TEST_F(NonUIModelTypeControllerTest, InitialState) { | 314 TEST_F(NonUIModelTypeControllerTest, InitialState) { |
319 EXPECT_EQ(syncer::DICTIONARY, controller_->type()); | 315 EXPECT_EQ(DICTIONARY, controller_->type()); |
320 EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); | 316 EXPECT_EQ(DataTypeController::NOT_RUNNING, controller_->state()); |
321 } | 317 } |
322 | 318 |
323 TEST_F(NonUIModelTypeControllerTest, LoadModelsOnBackendThread) { | 319 TEST_F(NonUIModelTypeControllerTest, LoadModelsOnBackendThread) { |
324 SetAutoRunTasks(false); | 320 SetAutoRunTasks(false); |
325 LoadModels(); | 321 LoadModels(); |
326 EXPECT_EQ(sync_driver::DataTypeController::MODEL_STARTING, | 322 EXPECT_EQ(DataTypeController::MODEL_STARTING, controller_->state()); |
327 controller_->state()); | |
328 RunAllTasks(); | 323 RunAllTasks(); |
329 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 324 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
330 controller_->state()); | |
331 EXPECT_TRUE(load_models_callback_called_); | 325 EXPECT_TRUE(load_models_callback_called_); |
332 EXPECT_FALSE(load_models_error_.IsSet()); | 326 EXPECT_FALSE(load_models_error_.IsSet()); |
333 ExpectProcessorConnected(false); | 327 ExpectProcessorConnected(false); |
334 } | 328 } |
335 | 329 |
336 TEST_F(NonUIModelTypeControllerTest, LoadModelsTwice) { | 330 TEST_F(NonUIModelTypeControllerTest, LoadModelsTwice) { |
337 LoadModels(); | 331 LoadModels(); |
338 SetAutoRunTasks(false); | 332 SetAutoRunTasks(false); |
339 LoadModels(); | 333 LoadModels(); |
340 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 334 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
341 controller_->state()); | |
342 // The second LoadModels call should set the error. | 335 // The second LoadModels call should set the error. |
343 EXPECT_TRUE(load_models_error_.IsSet()); | 336 EXPECT_TRUE(load_models_error_.IsSet()); |
344 } | 337 } |
345 | 338 |
346 TEST_F(NonUIModelTypeControllerTest, ActivateDataTypeOnBackendThread) { | 339 TEST_F(NonUIModelTypeControllerTest, ActivateDataTypeOnBackendThread) { |
347 LoadModels(); | 340 LoadModels(); |
348 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 341 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
349 controller_->state()); | |
350 RegisterWithBackend(); | 342 RegisterWithBackend(); |
351 ExpectProcessorConnected(true); | 343 ExpectProcessorConnected(true); |
352 | 344 |
353 StartAssociating(); | 345 StartAssociating(); |
354 EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); | 346 EXPECT_EQ(DataTypeController::RUNNING, controller_->state()); |
355 } | 347 } |
356 | 348 |
357 TEST_F(NonUIModelTypeControllerTest, Stop) { | 349 TEST_F(NonUIModelTypeControllerTest, Stop) { |
358 LoadModels(); | 350 LoadModels(); |
359 RegisterWithBackend(); | 351 RegisterWithBackend(); |
360 ExpectProcessorConnected(true); | 352 ExpectProcessorConnected(true); |
361 | 353 |
362 StartAssociating(); | 354 StartAssociating(); |
363 | 355 |
364 DeactivateDataTypeAndStop(); | 356 DeactivateDataTypeAndStop(); |
365 EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); | 357 EXPECT_EQ(DataTypeController::NOT_RUNNING, controller_->state()); |
366 } | 358 } |
367 | 359 |
368 } // namespace sync_driver_v2 | 360 } // namespace syncer |
OLD | NEW |