Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / sync_driver / model_association_manager_unittest.cc
1 // Copyright 2014 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 "base/callback.h"
6 #include "base/message_loop/message_loop.h"
7 #include "components/sync_driver/fake_data_type_controller.h"
8 #include "components/sync_driver/model_association_manager.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 using ::testing::_;
13
14 namespace sync_driver {
15
16 class MockModelAssociationManagerDelegate :
17     public ModelAssociationManagerDelegate {
18  public:
19   MockModelAssociationManagerDelegate() {}
20   ~MockModelAssociationManagerDelegate() {}
21   MOCK_METHOD2(OnSingleDataTypeAssociationDone,
22       void(syncer::ModelType type,
23       const syncer::DataTypeAssociationStats& association_stats));
24   MOCK_METHOD2(OnSingleDataTypeWillStop,
25                void(syncer::ModelType, const syncer::SyncError& error));
26   MOCK_METHOD1(OnModelAssociationDone, void(
27       const DataTypeManager::ConfigureResult& result));
28 };
29
30 FakeDataTypeController* GetController(
31     const DataTypeController::TypeMap& controllers,
32     syncer::ModelType model_type) {
33   DataTypeController::TypeMap::const_iterator it =
34       controllers.find(model_type);
35   if (it == controllers.end()) {
36     return NULL;
37   }
38   return (FakeDataTypeController*)(it->second.get());
39 }
40
41 ACTION_P(VerifyResult, expected_result) {
42   EXPECT_EQ(arg0.status, expected_result.status);
43   EXPECT_TRUE(arg0.requested_types.Equals(expected_result.requested_types));
44 }
45
46 class SyncModelAssociationManagerTest : public testing::Test {
47  public:
48   SyncModelAssociationManagerTest() {
49   }
50
51  protected:
52   base::MessageLoopForUI ui_loop_;
53   MockModelAssociationManagerDelegate delegate_;
54   DataTypeController::TypeMap controllers_;
55 };
56
57 // Start a type and make sure ModelAssociationManager callst the |Start|
58 // method and calls the callback when it is done.
59 TEST_F(SyncModelAssociationManagerTest, SimpleModelStart) {
60   controllers_[syncer::BOOKMARKS] =
61       new FakeDataTypeController(syncer::BOOKMARKS);
62   controllers_[syncer::APPS] =
63       new FakeDataTypeController(syncer::APPS);
64   ModelAssociationManager model_association_manager(&controllers_,
65                                                     &delegate_);
66   syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS);
67   DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types);
68   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
69               WillOnce(VerifyResult(expected_result));
70
71   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
72             DataTypeController::NOT_RUNNING);
73   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
74             DataTypeController::NOT_RUNNING);
75
76   // Initialize() kicks off model loading.
77   model_association_manager.Initialize(types);
78
79   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
80             DataTypeController::MODEL_LOADED);
81   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
82             DataTypeController::MODEL_LOADED);
83
84   model_association_manager.StartAssociationAsync(types);
85
86   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
87             DataTypeController::ASSOCIATING);
88   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
89             DataTypeController::ASSOCIATING);
90   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
91       DataTypeController::OK);
92   GetController(controllers_, syncer::APPS)->FinishStart(
93       DataTypeController::OK);
94 }
95
96 // Start a type and call stop before it finishes associating.
97 TEST_F(SyncModelAssociationManagerTest, StopModelBeforeFinish) {
98   controllers_[syncer::BOOKMARKS] =
99       new FakeDataTypeController(syncer::BOOKMARKS);
100   ModelAssociationManager model_association_manager(
101       &controllers_,
102       &delegate_);
103
104   syncer::ModelTypeSet types;
105   types.Put(syncer::BOOKMARKS);
106
107   DataTypeManager::ConfigureResult expected_result(DataTypeManager::ABORTED,
108                                                    types);
109
110   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
111               WillOnce(VerifyResult(expected_result));
112   EXPECT_CALL(delegate_,
113               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
114
115   model_association_manager.Initialize(types);
116   model_association_manager.StartAssociationAsync(types);
117
118   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
119             DataTypeController::ASSOCIATING);
120   model_association_manager.Stop();
121   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
122             DataTypeController::NOT_RUNNING);
123 }
124
125 // Start a type, let it finish and then call stop.
126 TEST_F(SyncModelAssociationManagerTest, StopAfterFinish) {
127   controllers_[syncer::BOOKMARKS] =
128       new FakeDataTypeController(syncer::BOOKMARKS);
129   ModelAssociationManager model_association_manager(
130       &controllers_,
131       &delegate_);
132   syncer::ModelTypeSet types;
133   types.Put(syncer::BOOKMARKS);
134   DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types);
135   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
136               WillOnce(VerifyResult(expected_result));
137   EXPECT_CALL(delegate_,
138               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
139
140   model_association_manager.Initialize(types);
141   model_association_manager.StartAssociationAsync(types);
142
143   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
144             DataTypeController::ASSOCIATING);
145   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
146       DataTypeController::OK);
147
148   model_association_manager.Stop();
149   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
150             DataTypeController::NOT_RUNNING);
151 }
152
153 // Make a type fail model association and verify correctness.
154 TEST_F(SyncModelAssociationManagerTest, TypeFailModelAssociation) {
155   controllers_[syncer::BOOKMARKS] =
156       new FakeDataTypeController(syncer::BOOKMARKS);
157   ModelAssociationManager model_association_manager(
158       &controllers_,
159       &delegate_);
160   syncer::ModelTypeSet types;
161   types.Put(syncer::BOOKMARKS);
162   DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types);
163   EXPECT_CALL(delegate_,
164               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
165   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
166               WillOnce(VerifyResult(expected_result));
167
168   model_association_manager.Initialize(types);
169   model_association_manager.StartAssociationAsync(types);
170
171   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
172             DataTypeController::ASSOCIATING);
173   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
174       DataTypeController::ASSOCIATION_FAILED);
175   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
176             DataTypeController::NOT_RUNNING);
177 }
178
179 // Ensure configuring stops when a type returns a unrecoverable error.
180 TEST_F(SyncModelAssociationManagerTest, TypeReturnUnrecoverableError) {
181   controllers_[syncer::BOOKMARKS] =
182       new FakeDataTypeController(syncer::BOOKMARKS);
183   ModelAssociationManager model_association_manager(
184       &controllers_,
185       &delegate_);
186   syncer::ModelTypeSet types;
187   types.Put(syncer::BOOKMARKS);
188   DataTypeManager::ConfigureResult expected_result(
189       DataTypeManager::UNRECOVERABLE_ERROR, types);
190   EXPECT_CALL(delegate_,
191               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
192   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
193               WillOnce(VerifyResult(expected_result));
194
195   model_association_manager.Initialize(types);
196
197   model_association_manager.StartAssociationAsync(types);
198
199   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
200             DataTypeController::ASSOCIATING);
201   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
202       DataTypeController::UNRECOVERABLE_ERROR);
203 }
204
205 TEST_F(SyncModelAssociationManagerTest, SlowTypeAsFailedType) {
206   controllers_[syncer::BOOKMARKS] =
207       new FakeDataTypeController(syncer::BOOKMARKS);
208   controllers_[syncer::APPS] =
209       new FakeDataTypeController(syncer::APPS);
210   GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad();
211   ModelAssociationManager model_association_manager(&controllers_,
212                                                     &delegate_);
213   syncer::ModelTypeSet types;
214   types.Put(syncer::BOOKMARKS);
215   types.Put(syncer::APPS);
216
217   syncer::ModelTypeSet expected_types_unfinished;
218   expected_types_unfinished.Put(syncer::BOOKMARKS);
219   DataTypeManager::ConfigureResult expected_result_partially_done(
220       DataTypeManager::OK, types);
221
222   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
223               WillOnce(VerifyResult(expected_result_partially_done));
224
225   model_association_manager.Initialize(types);
226   model_association_manager.StartAssociationAsync(types);
227   GetController(controllers_, syncer::APPS)->FinishStart(
228       DataTypeController::OK);
229
230   EXPECT_CALL(delegate_,
231               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
232   model_association_manager.GetTimerForTesting()->user_task().Run();
233
234   EXPECT_EQ(DataTypeController::NOT_RUNNING,
235             GetController(controllers_, syncer::BOOKMARKS)->state());
236 }
237
238 TEST_F(SyncModelAssociationManagerTest, StartMultipleTimes) {
239   controllers_[syncer::BOOKMARKS] =
240       new FakeDataTypeController(syncer::BOOKMARKS);
241   controllers_[syncer::APPS] =
242       new FakeDataTypeController(syncer::APPS);
243   ModelAssociationManager model_association_manager(&controllers_,
244                                                     &delegate_);
245   syncer::ModelTypeSet types;
246   types.Put(syncer::BOOKMARKS);
247   types.Put(syncer::APPS);
248
249   DataTypeManager::ConfigureResult result_1st(
250       DataTypeManager::OK,
251       syncer::ModelTypeSet(syncer::BOOKMARKS));
252   DataTypeManager::ConfigureResult result_2nd(
253       DataTypeManager::OK,
254       syncer::ModelTypeSet(syncer::APPS));
255   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
256       Times(2).
257       WillOnce(VerifyResult(result_1st)).
258       WillOnce(VerifyResult(result_2nd));
259
260   model_association_manager.Initialize(types);
261
262   // Start BOOKMARKS first.
263   model_association_manager.StartAssociationAsync(
264       syncer::ModelTypeSet(syncer::BOOKMARKS));
265   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
266             DataTypeController::ASSOCIATING);
267   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
268             DataTypeController::MODEL_LOADED);
269
270   // Finish BOOKMARKS association.
271   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
272       DataTypeController::OK);
273   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
274             DataTypeController::RUNNING);
275   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
276             DataTypeController::MODEL_LOADED);
277
278   // Start APPS next.
279   model_association_manager.StartAssociationAsync(
280       syncer::ModelTypeSet(syncer::APPS));
281   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
282             DataTypeController::ASSOCIATING);
283   GetController(controllers_, syncer::APPS)->FinishStart(
284       DataTypeController::OK);
285   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
286             DataTypeController::RUNNING);
287 }
288
289 // Test that model that failed to load between initialization and association
290 // is reported and stopped properly.
291 TEST_F(SyncModelAssociationManagerTest, ModelLoadFailBeforeAssociationStart) {
292   controllers_[syncer::BOOKMARKS] =
293       new FakeDataTypeController(syncer::BOOKMARKS);
294   GetController(controllers_, syncer::BOOKMARKS)->SetModelLoadError(
295       syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
296                         "", syncer::BOOKMARKS));
297   ModelAssociationManager model_association_manager(
298       &controllers_,
299       &delegate_);
300   syncer::ModelTypeSet types;
301   types.Put(syncer::BOOKMARKS);
302   DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types);
303   EXPECT_CALL(delegate_,
304               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
305   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
306               WillOnce(VerifyResult(expected_result));
307
308   model_association_manager.Initialize(types);
309   EXPECT_EQ(DataTypeController::NOT_RUNNING,
310             GetController(controllers_, syncer::BOOKMARKS)->state());
311   model_association_manager.StartAssociationAsync(types);
312   EXPECT_EQ(DataTypeController::NOT_RUNNING,
313             GetController(controllers_, syncer::BOOKMARKS)->state());
314 }
315
316 // Test that a runtime error is handled by stopping the type.
317 TEST_F(SyncModelAssociationManagerTest, StopAfterConfiguration) {
318   controllers_[syncer::BOOKMARKS] =
319       new FakeDataTypeController(syncer::BOOKMARKS);
320   ModelAssociationManager model_association_manager(
321       &controllers_,
322       &delegate_);
323   syncer::ModelTypeSet types;
324   types.Put(syncer::BOOKMARKS);
325   DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types);
326   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
327               WillOnce(VerifyResult(expected_result));
328
329   model_association_manager.Initialize(types);
330   model_association_manager.StartAssociationAsync(types);
331
332   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
333             DataTypeController::ASSOCIATING);
334   GetController(controllers_, syncer::BOOKMARKS)->FinishStart(
335       DataTypeController::OK);
336   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
337             DataTypeController::RUNNING);
338
339   testing::Mock::VerifyAndClearExpectations(&delegate_);
340   EXPECT_CALL(delegate_,
341               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
342   syncer::SyncError error(FROM_HERE,
343                           syncer::SyncError::DATATYPE_ERROR,
344                           "error",
345                           syncer::BOOKMARKS);
346   GetController(controllers_, syncer::BOOKMARKS)
347       ->OnSingleDataTypeUnrecoverableError(error);
348 }
349
350 TEST_F(SyncModelAssociationManagerTest, AbortDuringAssociation) {
351   controllers_[syncer::BOOKMARKS] =
352       new FakeDataTypeController(syncer::BOOKMARKS);
353   controllers_[syncer::APPS] =
354       new FakeDataTypeController(syncer::APPS);
355   ModelAssociationManager model_association_manager(&controllers_,
356                                                     &delegate_);
357   syncer::ModelTypeSet types;
358   types.Put(syncer::BOOKMARKS);
359   types.Put(syncer::APPS);
360
361   syncer::ModelTypeSet expected_types_unfinished;
362   expected_types_unfinished.Put(syncer::BOOKMARKS);
363   DataTypeManager::ConfigureResult expected_result_partially_done(
364       DataTypeManager::OK, types);
365
366   EXPECT_CALL(delegate_, OnModelAssociationDone(_)).
367               WillOnce(VerifyResult(expected_result_partially_done));
368
369   model_association_manager.Initialize(types);
370   model_association_manager.StartAssociationAsync(types);
371   GetController(controllers_, syncer::APPS)->FinishStart(
372       DataTypeController::OK);
373   EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(),
374             DataTypeController::RUNNING);
375   EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(),
376             DataTypeController::ASSOCIATING);
377
378   EXPECT_CALL(delegate_,
379               OnSingleDataTypeWillStop(syncer::BOOKMARKS, _));
380   model_association_manager.GetTimerForTesting()->user_task().Run();
381
382   EXPECT_EQ(DataTypeController::NOT_RUNNING,
383             GetController(controllers_, syncer::BOOKMARKS)->state());
384 }
385
386 }  // namespace sync_driver