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/ui_model_type_controller.h" | 5 #include "components/sync/driver/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 // A no-op instance of CommitQueue. | 33 // A no-op instance of CommitQueue. |
34 class NullCommitQueue : public syncer_v2::CommitQueue { | 34 class NullCommitQueue : public CommitQueue { |
35 public: | 35 public: |
36 NullCommitQueue() {} | 36 NullCommitQueue() {} |
37 ~NullCommitQueue() override {} | 37 ~NullCommitQueue() override {} |
38 | 38 |
39 void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { | 39 void EnqueueForCommit(const CommitRequestDataList& list) override { |
40 NOTREACHED() << "Not implemented."; | 40 NOTREACHED() << "Not implemented."; |
41 } | 41 } |
42 }; | 42 }; |
43 | 43 |
44 // A class that pretends to be the sync backend. | 44 // A class that pretends to be the sync backend. |
45 class MockSyncBackend { | 45 class MockSyncBackend { |
46 public: | 46 public: |
47 void Connect( | 47 void Connect(ModelType type, |
48 syncer::ModelType type, | 48 std::unique_ptr<ActivationContext> activation_context) { |
49 std::unique_ptr<syncer_v2::ActivationContext> activation_context) { | |
50 enabled_types_.Put(type); | 49 enabled_types_.Put(type); |
51 activation_context->type_processor->ConnectSync( | 50 activation_context->type_processor->ConnectSync( |
52 base::MakeUnique<NullCommitQueue>()); | 51 base::MakeUnique<NullCommitQueue>()); |
53 } | 52 } |
54 | 53 |
55 void Disconnect(syncer::ModelType type) { | 54 void Disconnect(ModelType type) { |
56 DCHECK(enabled_types_.Has(type)); | 55 DCHECK(enabled_types_.Has(type)); |
57 enabled_types_.Remove(type); | 56 enabled_types_.Remove(type); |
58 } | 57 } |
59 | 58 |
60 private: | 59 private: |
61 syncer::ModelTypeSet enabled_types_; | 60 ModelTypeSet enabled_types_; |
62 }; | 61 }; |
63 | 62 |
64 // Fake implementation of BackendDataTypeConfigurer that pretends to be Sync | 63 // Fake implementation of BackendDataTypeConfigurer that pretends to be Sync |
65 // backend. | 64 // backend. |
66 class MockBackendDataTypeConfigurer | 65 class MockBackendDataTypeConfigurer : public BackendDataTypeConfigurer { |
67 : public sync_driver::BackendDataTypeConfigurer { | |
68 public: | 66 public: |
69 MockBackendDataTypeConfigurer( | 67 MockBackendDataTypeConfigurer( |
70 MockSyncBackend* backend, | 68 MockSyncBackend* backend, |
71 const scoped_refptr<base::TaskRunner>& sync_task_runner) | 69 const scoped_refptr<base::TaskRunner>& sync_task_runner) |
72 : backend_(backend), sync_task_runner_(sync_task_runner) {} | 70 : backend_(backend), sync_task_runner_(sync_task_runner) {} |
73 ~MockBackendDataTypeConfigurer() override {} | 71 ~MockBackendDataTypeConfigurer() override {} |
74 | 72 |
75 syncer::ModelTypeSet ConfigureDataTypes( | 73 ModelTypeSet ConfigureDataTypes( |
76 syncer::ConfigureReason reason, | 74 ConfigureReason reason, |
77 const DataTypeConfigStateMap& config_state_map, | 75 const DataTypeConfigStateMap& config_state_map, |
78 const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& | 76 const base::Callback<void(ModelTypeSet, ModelTypeSet)>& ready_task, |
79 ready_task, | |
80 const base::Callback<void()>& retry_callback) override { | 77 const base::Callback<void()>& retry_callback) override { |
81 NOTREACHED() << "Not implemented."; | 78 NOTREACHED() << "Not implemented."; |
82 return syncer::ModelTypeSet(); | 79 return ModelTypeSet(); |
83 } | 80 } |
84 | 81 |
85 void ActivateDirectoryDataType( | 82 void ActivateDirectoryDataType(ModelType type, |
86 syncer::ModelType type, | 83 ModelSafeGroup group, |
87 syncer::ModelSafeGroup group, | 84 ChangeProcessor* change_processor) override { |
88 sync_driver::ChangeProcessor* change_processor) override { | |
89 NOTREACHED() << "Not implemented."; | 85 NOTREACHED() << "Not implemented."; |
90 } | 86 } |
91 | 87 |
92 void DeactivateDirectoryDataType(syncer::ModelType type) override { | 88 void DeactivateDirectoryDataType(ModelType type) override { |
93 NOTREACHED() << "Not implemented."; | 89 NOTREACHED() << "Not implemented."; |
94 } | 90 } |
95 | 91 |
96 void ActivateNonBlockingDataType(syncer::ModelType type, | 92 void ActivateNonBlockingDataType( |
97 std::unique_ptr<syncer_v2::ActivationContext> | 93 ModelType type, |
98 activation_context) override { | 94 std::unique_ptr<ActivationContext> activation_context) override { |
99 // Post on Sync thread just like the real implementation does. | 95 // Post on Sync thread just like the real implementation does. |
100 sync_task_runner_->PostTask( | 96 sync_task_runner_->PostTask( |
101 FROM_HERE, | 97 FROM_HERE, |
102 base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, | 98 base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, |
103 base::Passed(std::move(activation_context)))); | 99 base::Passed(std::move(activation_context)))); |
104 } | 100 } |
105 | 101 |
106 void DeactivateNonBlockingDataType(syncer::ModelType type) override { | 102 void DeactivateNonBlockingDataType(ModelType type) override { |
107 sync_task_runner_->PostTask(FROM_HERE, | 103 sync_task_runner_->PostTask(FROM_HERE, |
108 base::Bind(&MockSyncBackend::Disconnect, | 104 base::Bind(&MockSyncBackend::Disconnect, |
109 base::Unretained(backend_), type)); | 105 base::Unretained(backend_), type)); |
110 } | 106 } |
111 | 107 |
112 private: | 108 private: |
113 MockSyncBackend* backend_; | 109 MockSyncBackend* backend_; |
114 scoped_refptr<base::TaskRunner> sync_task_runner_; | 110 scoped_refptr<base::TaskRunner> sync_task_runner_; |
115 }; | 111 }; |
116 | 112 |
117 } // namespace | 113 } // namespace |
118 | 114 |
119 class UIModelTypeControllerTest : public testing::Test, | 115 class UIModelTypeControllerTest : public testing::Test, public FakeSyncClient { |
120 public sync_driver::FakeSyncClient { | |
121 public: | 116 public: |
122 UIModelTypeControllerTest() | 117 UIModelTypeControllerTest() |
123 : auto_run_tasks_(true), | 118 : auto_run_tasks_(true), |
124 load_models_callback_called_(false), | 119 load_models_callback_called_(false), |
125 association_callback_called_(false), | 120 association_callback_called_(false), |
126 configurer_(&backend_, ui_loop_.task_runner()) {} | 121 configurer_(&backend_, ui_loop_.task_runner()) {} |
127 | 122 |
128 ~UIModelTypeControllerTest() override {} | 123 ~UIModelTypeControllerTest() override {} |
129 | 124 |
130 void SetUp() override { | 125 void SetUp() override { |
131 controller_ = base::MakeUnique<UIModelTypeController>( | 126 controller_ = base::MakeUnique<UIModelTypeController>( |
132 syncer::DEVICE_INFO, base::Closure(), this); | 127 DEVICE_INFO, base::Closure(), this); |
133 service_ = base::MakeUnique<syncer_v2::StubModelTypeService>(base::Bind( | 128 service_ = base::MakeUnique<StubModelTypeService>(base::Bind( |
134 &UIModelTypeControllerTest::CreateProcessor, base::Unretained(this))); | 129 &UIModelTypeControllerTest::CreateProcessor, base::Unretained(this))); |
135 } | 130 } |
136 | 131 |
137 void TearDown() override { | 132 void TearDown() override { |
138 controller_ = NULL; | 133 controller_ = NULL; |
139 RunAllTasks(); | 134 RunAllTasks(); |
140 } | 135 } |
141 | 136 |
142 base::WeakPtr<syncer_v2::ModelTypeService> GetModelTypeServiceForType( | 137 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( |
143 syncer::ModelType type) override { | 138 ModelType type) override { |
144 return service_->AsWeakPtr(); | 139 return service_->AsWeakPtr(); |
145 } | 140 } |
146 | 141 |
147 protected: | 142 protected: |
148 std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( | 143 std::unique_ptr<ModelTypeChangeProcessor> CreateProcessor( |
149 syncer::ModelType type, | 144 ModelType type, |
150 syncer_v2::ModelTypeService* service) { | 145 ModelTypeService* service) { |
151 std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = | 146 std::unique_ptr<SharedModelTypeProcessor> processor = |
152 base::MakeUnique<syncer_v2::SharedModelTypeProcessor>(type, service); | 147 base::MakeUnique<SharedModelTypeProcessor>(type, service); |
153 type_processor_ = processor.get(); | 148 type_processor_ = processor.get(); |
154 return std::move(processor); | 149 return std::move(processor); |
155 } | 150 } |
156 | 151 |
157 void ExpectProcessorConnected(bool isConnected) { | 152 void ExpectProcessorConnected(bool isConnected) { |
158 DCHECK(type_processor_); | 153 DCHECK(type_processor_); |
159 EXPECT_EQ(isConnected, type_processor_->IsConnected()); | 154 EXPECT_EQ(isConnected, type_processor_->IsConnected()); |
160 } | 155 } |
161 | 156 |
162 void LoadModels() { | 157 void LoadModels() { |
163 controller_->LoadModels(base::Bind( | 158 controller_->LoadModels(base::Bind( |
164 &UIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); | 159 &UIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); |
165 if (!type_processor_->IsAllowingChanges()) { | 160 if (!type_processor_->IsAllowingChanges()) { |
166 type_processor_->OnMetadataLoaded( | 161 type_processor_->OnMetadataLoaded(SyncError(), |
167 syncer::SyncError(), base::MakeUnique<syncer_v2::MetadataBatch>()); | 162 base::MakeUnique<MetadataBatch>()); |
168 } | 163 } |
169 | 164 |
170 if (auto_run_tasks_) { | 165 if (auto_run_tasks_) { |
171 RunAllTasks(); | 166 RunAllTasks(); |
172 } | 167 } |
173 } | 168 } |
174 | 169 |
175 void RegisterWithBackend() { | 170 void RegisterWithBackend() { |
176 controller_->RegisterWithBackend(&configurer_); | 171 controller_->RegisterWithBackend(&configurer_); |
177 if (auto_run_tasks_) { | 172 if (auto_run_tasks_) { |
(...skipping 16 matching lines...) Expand all Loading... |
194 } | 189 } |
195 } | 190 } |
196 | 191 |
197 // These threads can ping-pong for a bit so we run the UI thread twice. | 192 // These threads can ping-pong for a bit so we run the UI thread twice. |
198 void RunAllTasks() { base::RunLoop().RunUntilIdle(); } | 193 void RunAllTasks() { base::RunLoop().RunUntilIdle(); } |
199 | 194 |
200 void SetAutoRunTasks(bool auto_run_tasks) { | 195 void SetAutoRunTasks(bool auto_run_tasks) { |
201 auto_run_tasks_ = auto_run_tasks; | 196 auto_run_tasks_ = auto_run_tasks; |
202 } | 197 } |
203 | 198 |
204 void LoadModelsDone(syncer::ModelType type, const syncer::SyncError& error) { | 199 void LoadModelsDone(ModelType type, const SyncError& error) { |
205 load_models_callback_called_ = true; | 200 load_models_callback_called_ = true; |
206 load_models_error_ = error; | 201 load_models_error_ = error; |
207 } | 202 } |
208 | 203 |
209 void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, | 204 void AssociationDone(DataTypeController::ConfigureResult result, |
210 const syncer::SyncMergeResult& local_merge_result, | 205 const SyncMergeResult& local_merge_result, |
211 const syncer::SyncMergeResult& syncer_merge_result) { | 206 const SyncMergeResult& syncer_merge_result) { |
212 EXPECT_EQ(sync_driver::DataTypeController::OK, result); | 207 EXPECT_EQ(DataTypeController::OK, result); |
213 association_callback_called_ = true; | 208 association_callback_called_ = true; |
214 } | 209 } |
215 | 210 |
216 syncer_v2::SharedModelTypeProcessor* type_processor_; | 211 SharedModelTypeProcessor* type_processor_; |
217 std::unique_ptr<UIModelTypeController> controller_; | 212 std::unique_ptr<UIModelTypeController> controller_; |
218 | 213 |
219 bool auto_run_tasks_; | 214 bool auto_run_tasks_; |
220 bool load_models_callback_called_; | 215 bool load_models_callback_called_; |
221 syncer::SyncError load_models_error_; | 216 SyncError load_models_error_; |
222 bool association_callback_called_; | 217 bool association_callback_called_; |
223 base::MessageLoopForUI ui_loop_; | 218 base::MessageLoopForUI ui_loop_; |
224 MockSyncBackend backend_; | 219 MockSyncBackend backend_; |
225 MockBackendDataTypeConfigurer configurer_; | 220 MockBackendDataTypeConfigurer configurer_; |
226 std::unique_ptr<syncer_v2::StubModelTypeService> service_; | 221 std::unique_ptr<StubModelTypeService> service_; |
227 }; | 222 }; |
228 | 223 |
229 TEST_F(UIModelTypeControllerTest, InitialState) { | 224 TEST_F(UIModelTypeControllerTest, InitialState) { |
230 EXPECT_EQ(syncer::DEVICE_INFO, controller_->type()); | 225 EXPECT_EQ(DEVICE_INFO, controller_->type()); |
231 EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); | 226 EXPECT_EQ(DataTypeController::NOT_RUNNING, controller_->state()); |
232 } | 227 } |
233 | 228 |
234 TEST_F(UIModelTypeControllerTest, LoadModelsOnUIThread) { | 229 TEST_F(UIModelTypeControllerTest, LoadModelsOnUIThread) { |
235 LoadModels(); | 230 LoadModels(); |
236 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 231 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
237 controller_->state()); | |
238 EXPECT_TRUE(load_models_callback_called_); | 232 EXPECT_TRUE(load_models_callback_called_); |
239 EXPECT_FALSE(load_models_error_.IsSet()); | 233 EXPECT_FALSE(load_models_error_.IsSet()); |
240 ExpectProcessorConnected(false); | 234 ExpectProcessorConnected(false); |
241 } | 235 } |
242 | 236 |
243 TEST_F(UIModelTypeControllerTest, LoadModelsTwice) { | 237 TEST_F(UIModelTypeControllerTest, LoadModelsTwice) { |
244 LoadModels(); | 238 LoadModels(); |
245 SetAutoRunTasks(false); | 239 SetAutoRunTasks(false); |
246 LoadModels(); | 240 LoadModels(); |
247 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 241 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
248 controller_->state()); | |
249 // The second LoadModels call should set the error. | 242 // The second LoadModels call should set the error. |
250 EXPECT_TRUE(load_models_error_.IsSet()); | 243 EXPECT_TRUE(load_models_error_.IsSet()); |
251 } | 244 } |
252 | 245 |
253 TEST_F(UIModelTypeControllerTest, ActivateDataTypeOnUIThread) { | 246 TEST_F(UIModelTypeControllerTest, ActivateDataTypeOnUIThread) { |
254 LoadModels(); | 247 LoadModels(); |
255 EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, | 248 EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); |
256 controller_->state()); | |
257 RegisterWithBackend(); | 249 RegisterWithBackend(); |
258 ExpectProcessorConnected(true); | 250 ExpectProcessorConnected(true); |
259 | 251 |
260 StartAssociating(); | 252 StartAssociating(); |
261 EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); | 253 EXPECT_EQ(DataTypeController::RUNNING, controller_->state()); |
262 } | 254 } |
263 | 255 |
264 TEST_F(UIModelTypeControllerTest, Stop) { | 256 TEST_F(UIModelTypeControllerTest, Stop) { |
265 LoadModels(); | 257 LoadModels(); |
266 RegisterWithBackend(); | 258 RegisterWithBackend(); |
267 ExpectProcessorConnected(true); | 259 ExpectProcessorConnected(true); |
268 StartAssociating(); | 260 StartAssociating(); |
269 | 261 |
270 DeactivateDataTypeAndStop(); | 262 DeactivateDataTypeAndStop(); |
271 EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); | 263 EXPECT_EQ(DataTypeController::NOT_RUNNING, controller_->state()); |
272 } | 264 } |
273 | 265 |
274 } // namespace sync_driver_v2 | 266 } // namespace syncer |
OLD | NEW |