Fix build break
[chromium-blink-merge.git] / chrome / browser / sync / glue / model_association_manager_unittest.cc
blob8d38176b409f0833f846b9c61986ca56245a0752
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 "base/callback.h"
6 #include "base/message_loop.h"
7 #include "chrome/browser/sync/glue/fake_data_type_controller.h"
8 #include "chrome/browser/sync/glue/model_association_manager.h"
9 #include "content/public/test/test_browser_thread.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 using ::testing::_;
14 namespace browser_sync {
15 class MockModelAssociationResultProcessor :
16 public ModelAssociationResultProcessor {
17 public:
18 MockModelAssociationResultProcessor() {}
19 ~MockModelAssociationResultProcessor() {}
20 MOCK_METHOD1(OnModelAssociationDone, void(
21 const DataTypeManager::ConfigureResult& result));
22 MOCK_METHOD0(OnTypesLoaded, void());
25 FakeDataTypeController* GetController(
26 const DataTypeController::TypeMap& controllers,
27 syncer::ModelType model_type) {
28 DataTypeController::TypeMap::const_iterator it =
29 controllers.find(model_type);
30 if (it == controllers.end()) {
31 return NULL;
33 return (FakeDataTypeController*)(it->second.get());
36 ACTION_P(VerifyResult, expected_result) {
37 EXPECT_EQ(arg0.status, expected_result.status);
38 EXPECT_TRUE(arg0.requested_types.Equals(expected_result.requested_types));
39 EXPECT_EQ(arg0.failed_data_types.size(),
40 expected_result.failed_data_types.size());
42 if (arg0.failed_data_types.size() ==
43 expected_result.failed_data_types.size()) {
44 std::list<syncer::SyncError>::const_iterator it1, it2;
45 for (it1 = arg0.failed_data_types.begin(),
46 it2 = expected_result.failed_data_types.begin();
47 it1 != arg0.failed_data_types.end();
48 ++it1, ++it2) {
49 EXPECT_EQ((*it1).type(), (*it2).type());
53 EXPECT_TRUE(arg0.waiting_to_start.Equals(expected_result.waiting_to_start));
56 class SyncModelAssociationManagerTest : public testing::Test {
57 public:
58 SyncModelAssociationManagerTest() :
59 ui_thread_(content::BrowserThread::UI, &ui_loop_) {
62 protected:
63 MessageLoopForUI ui_loop_;
64 content::TestBrowserThread ui_thread_;
65 MockModelAssociationResultProcessor result_processor_;
66 DataTypeController::TypeMap controllers_;
69 // Start a type and make sure ModelAssociationManager callst the |Start|
70 // method and calls the callback when it is done.
71 TEST_F(SyncModelAssociationManagerTest, SimpleModelStart) {
72 controllers_[syncer::BOOKMARKS] =
73 new FakeDataTypeController(syncer::BOOKMARKS);
74 ModelAssociationManager model_association_manager(
75 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
76 &controllers_,
77 &result_processor_);
78 syncer::ModelTypeSet types;
79 types.Put(syncer::BOOKMARKS);
80 DataTypeManager::ConfigureResult expected_result(
81 DataTypeManager::OK,
82 types,
83 std::list<syncer::SyncError>(),
84 syncer::ModelTypeSet());
85 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
86 WillOnce(VerifyResult(expected_result));
88 model_association_manager.Initialize(types);
89 model_association_manager.StopDisabledTypes();
90 model_association_manager.StartAssociationAsync();
92 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
93 DataTypeController::MODEL_LOADED);
94 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
95 DataTypeController::OK);
98 // Start a type and call stop before it finishes associating.
99 TEST_F(SyncModelAssociationManagerTest, StopModelBeforeFinish) {
100 controllers_[syncer::BOOKMARKS] =
101 new FakeDataTypeController(syncer::BOOKMARKS);
102 ModelAssociationManager model_association_manager(
103 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
104 &controllers_,
105 &result_processor_);
107 syncer::ModelTypeSet types;
108 types.Put(syncer::BOOKMARKS);
110 DataTypeManager::ConfigureResult expected_result(
111 DataTypeManager::ABORTED,
112 types,
113 std::list<syncer::SyncError>(),
114 syncer::ModelTypeSet());
116 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
117 WillOnce(VerifyResult(expected_result));
119 model_association_manager.Initialize(types);
120 model_association_manager.StopDisabledTypes();
121 model_association_manager.StartAssociationAsync();
123 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
124 DataTypeController::MODEL_LOADED);
125 model_association_manager.Stop();
126 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
127 DataTypeController::NOT_RUNNING);
130 // Start a type, let it finish and then call stop.
131 TEST_F(SyncModelAssociationManagerTest, StopAfterFinish) {
132 controllers_[syncer::BOOKMARKS] =
133 new FakeDataTypeController(syncer::BOOKMARKS);
134 ModelAssociationManager model_association_manager(
135 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
136 &controllers_,
137 &result_processor_);
138 syncer::ModelTypeSet types;
139 types.Put(syncer::BOOKMARKS);
140 DataTypeManager::ConfigureResult expected_result(
141 DataTypeManager::OK,
142 types,
143 std::list<syncer::SyncError>(),
144 syncer::ModelTypeSet());
145 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
146 WillOnce(VerifyResult(expected_result));
148 model_association_manager.Initialize(types);
149 model_association_manager.StopDisabledTypes();
150 model_association_manager.StartAssociationAsync();
152 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
153 DataTypeController::MODEL_LOADED);
154 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
155 DataTypeController::OK);
157 model_association_manager.Stop();
158 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
159 DataTypeController::NOT_RUNNING);
162 // Make a type fail model association and verify correctness.
163 TEST_F(SyncModelAssociationManagerTest, TypeFailModelAssociation) {
164 controllers_[syncer::BOOKMARKS] =
165 new FakeDataTypeController(syncer::BOOKMARKS);
166 ModelAssociationManager model_association_manager(
167 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
168 &controllers_,
169 &result_processor_);
170 syncer::ModelTypeSet types;
171 types.Put(syncer::BOOKMARKS);
172 std::list<syncer::SyncError> errors;
173 syncer::SyncError error(FROM_HERE, "Failed", syncer::BOOKMARKS);
174 errors.push_back(error);
175 DataTypeManager::ConfigureResult expected_result(
176 DataTypeManager::PARTIAL_SUCCESS,
177 types,
178 errors,
179 syncer::ModelTypeSet());
180 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
181 WillOnce(VerifyResult(expected_result));
183 model_association_manager.Initialize(types);
184 model_association_manager.StopDisabledTypes();
185 model_association_manager.StartAssociationAsync();
187 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
188 DataTypeController::MODEL_LOADED);
189 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
190 DataTypeController::ASSOCIATION_FAILED);
193 // Ensure configuring stops when a type returns a unrecoverable error.
194 TEST_F(SyncModelAssociationManagerTest, TypeReturnUnrecoverableError) {
195 controllers_[syncer::BOOKMARKS] =
196 new FakeDataTypeController(syncer::BOOKMARKS);
197 ModelAssociationManager model_association_manager(
198 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
199 &controllers_,
200 &result_processor_);
201 syncer::ModelTypeSet types;
202 types.Put(syncer::BOOKMARKS);
203 std::list<syncer::SyncError> errors;
204 syncer::SyncError error(FROM_HERE, "Failed", syncer::BOOKMARKS);
205 errors.push_back(error);
206 DataTypeManager::ConfigureResult expected_result(
207 DataTypeManager::UNRECOVERABLE_ERROR,
208 types,
209 errors,
210 syncer::ModelTypeSet());
211 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
212 WillOnce(VerifyResult(expected_result));
214 model_association_manager.Initialize(types);
215 model_association_manager.StopDisabledTypes();
216 model_association_manager.StartAssociationAsync();
218 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
219 DataTypeController::MODEL_LOADED);
220 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
221 DataTypeController::UNRECOVERABLE_ERROR);
224 TEST_F(SyncModelAssociationManagerTest, InitializeAbortsLoad) {
225 controllers_[syncer::BOOKMARKS] =
226 new FakeDataTypeController(syncer::BOOKMARKS);
227 controllers_[syncer::THEMES] =
228 new FakeDataTypeController(syncer::THEMES);
230 GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad();
231 ModelAssociationManager model_association_manager(
232 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
233 &controllers_,
234 &result_processor_);
235 syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::THEMES);
237 syncer::ModelTypeSet expected_types_waiting_to_load;
238 expected_types_waiting_to_load.Put(syncer::BOOKMARKS);
239 DataTypeManager::ConfigureResult expected_result_partially_done(
240 DataTypeManager::PARTIAL_SUCCESS,
241 types,
242 std::list<syncer::SyncError>(),
243 expected_types_waiting_to_load);
245 model_association_manager.Initialize(types);
246 model_association_manager.StopDisabledTypes();
248 model_association_manager.StartAssociationAsync();
250 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
251 WillOnce(VerifyResult(expected_result_partially_done));
253 base::OneShotTimer<ModelAssociationManager>* timer =
254 model_association_manager.GetTimerForTesting();
256 base::Closure task = timer->user_task();
257 timer->Stop();
258 task.Run(); // Bookmark load times out here.
260 // Apps finishes associating here.
261 GetController(controllers_, syncer::THEMES)->FinishStart(
262 DataTypeController::OK);
264 // At this point, BOOKMARKS is still waiting to load (as evidenced by
265 // expected_result_partially_done). If we schedule another Initialize (which
266 // could happen in practice due to reconfiguration), this should abort
267 // BOOKMARKS. Aborting will call ModelLoadCallback, but the
268 // ModelAssociationManager should be smart enough to know that this is not due
269 // to the type having completed loading.
270 EXPECT_CALL(result_processor_, OnTypesLoaded()).Times(0);
272 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
273 DataTypeController::MODEL_STARTING);
275 model_association_manager.Initialize(types);
276 EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
277 DataTypeController::NOT_RUNNING);
279 DataTypeManager::ConfigureResult expected_result_done(
280 DataTypeManager::OK,
281 types,
282 std::list<syncer::SyncError>(),
283 syncer::ModelTypeSet());
284 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
285 WillOnce(VerifyResult(expected_result_done));
287 model_association_manager.StopDisabledTypes();
288 model_association_manager.StartAssociationAsync();
290 GetController(controllers_,
291 syncer::BOOKMARKS)->SimulateModelLoadFinishing();
292 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
293 DataTypeController::OK);
296 // Start 2 types. One of which timeout loading. Ensure that type is
297 // fully configured eventually.
298 TEST_F(SyncModelAssociationManagerTest, ModelStartWithSlowLoadingType) {
299 controllers_[syncer::BOOKMARKS] =
300 new FakeDataTypeController(syncer::BOOKMARKS);
301 controllers_[syncer::APPS] =
302 new FakeDataTypeController(syncer::APPS);
303 GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad();
304 ModelAssociationManager model_association_manager(
305 syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(),
306 &controllers_,
307 &result_processor_);
308 syncer::ModelTypeSet types;
309 types.Put(syncer::BOOKMARKS);
310 types.Put(syncer::APPS);
312 syncer::ModelTypeSet expected_types_waiting_to_load;
313 expected_types_waiting_to_load.Put(syncer::BOOKMARKS);
314 DataTypeManager::ConfigureResult expected_result_partially_done(
315 DataTypeManager::PARTIAL_SUCCESS,
316 types,
317 std::list<syncer::SyncError>(),
318 expected_types_waiting_to_load);
320 DataTypeManager::ConfigureResult expected_result_done(
321 DataTypeManager::OK,
322 types,
323 std::list<syncer::SyncError>(),
324 syncer::ModelTypeSet());
326 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
327 WillOnce(VerifyResult(expected_result_partially_done));
328 EXPECT_CALL(result_processor_, OnTypesLoaded());
330 model_association_manager.Initialize(types);
331 model_association_manager.StopDisabledTypes();
332 model_association_manager.StartAssociationAsync();
334 base::OneShotTimer<ModelAssociationManager>* timer =
335 model_association_manager.GetTimerForTesting();
337 // Note: Independent of the timeout value this test is not flaky.
338 // The reason is timer posts a task which would never be executed
339 // as we dont let the message loop run.
340 base::Closure task = timer->user_task();
341 timer->Stop();
342 task.Run();
344 // Simulate delayed loading of bookmark model.
345 GetController(controllers_, syncer::APPS)->FinishStart(
346 DataTypeController::OK);
348 GetController(controllers_,
349 syncer::BOOKMARKS)->SimulateModelLoadFinishing();
351 EXPECT_CALL(result_processor_, OnModelAssociationDone(_)).
352 WillOnce(VerifyResult(expected_result_done));
354 // Do it once more to associate bookmarks.
355 model_association_manager.Initialize(types);
356 model_association_manager.StopDisabledTypes();
357 model_association_manager.StartAssociationAsync();
359 GetController(controllers_,
360 syncer::BOOKMARKS)->SimulateModelLoadFinishing();
362 GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
363 DataTypeController::OK);
367 } // namespace browser_sync