Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / sync / backend_migrator_unittest.cc
blobf261756a5b67c9d3cf8c18ad72925e6fae8ead29
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/backend_migrator.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/tracked_objects.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/sync/glue/data_type_manager_mock.h"
11 #include "chrome/browser/sync/profile_sync_service_mock.h"
12 #include "sync/internal_api/public/base/model_type_test_util.h"
13 #include "sync/internal_api/public/test/test_user_share.h"
14 #include "sync/internal_api/public/write_transaction.h"
15 #include "sync/protocol/sync.pb.h"
16 #include "sync/syncable/directory.h" // TODO(tim): Remove. Bug 131130.
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using ::testing::_;
21 using ::testing::Eq;
22 using ::testing::Mock;
23 using ::testing::NiceMock;
24 using ::testing::Return;
26 namespace browser_sync {
28 using syncer::sessions::SyncSessionSnapshot;
30 class SyncBackendMigratorTest : public testing::Test {
31 public:
32 SyncBackendMigratorTest() : service_(&profile_) { }
33 virtual ~SyncBackendMigratorTest() { }
35 virtual void SetUp() {
36 test_user_share_.SetUp();
37 Mock::VerifyAndClear(manager());
38 Mock::VerifyAndClear(&service_);
39 preferred_types_.Put(syncer::BOOKMARKS);
40 preferred_types_.Put(syncer::PREFERENCES);
41 preferred_types_.Put(syncer::AUTOFILL);
43 ON_CALL(service_, GetPreferredDataTypes()).
44 WillByDefault(Return(preferred_types_));
46 migrator_.reset(
47 new BackendMigrator(
48 "Profile0", test_user_share_.user_share(), service(), manager(),
49 base::Closure()));
50 SetUnsyncedTypes(syncer::ModelTypeSet());
53 virtual void TearDown() {
54 migrator_.reset();
55 test_user_share_.TearDown();
58 // Marks all types in |unsynced_types| as unsynced and all other
59 // types as synced.
60 void SetUnsyncedTypes(syncer::ModelTypeSet unsynced_types) {
61 syncer::WriteTransaction trans(FROM_HERE,
62 test_user_share_.user_share());
63 for (int i = syncer::FIRST_REAL_MODEL_TYPE;
64 i < syncer::MODEL_TYPE_COUNT; ++i) {
65 syncer::ModelType type = syncer::ModelTypeFromInt(i);
66 sync_pb::DataTypeProgressMarker progress_marker;
67 if (!unsynced_types.Has(type)) {
68 progress_marker.set_token("dummy");
70 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
74 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
75 syncer::ModelTypeSet requested_types) {
76 if (status == DataTypeManager::OK) {
77 DataTypeManager::ConfigureResult result(status, requested_types);
78 migrator_->OnConfigureDone(result);
79 } else {
80 std::map<syncer::ModelType, syncer::SyncError> errors;
81 DataTypeManager::ConfigureResult result(
82 status,
83 requested_types,
84 errors,
85 syncer::ModelTypeSet(),
86 syncer::ModelTypeSet());
87 migrator_->OnConfigureDone(result);
89 message_loop_.RunUntilIdle();
92 ProfileSyncService* service() { return &service_; }
93 DataTypeManagerMock* manager() { return &manager_; }
94 syncer::ModelTypeSet preferred_types() { return preferred_types_; }
95 BackendMigrator* migrator() { return migrator_.get(); }
96 void RemovePreferredType(syncer::ModelType type) {
97 preferred_types_.Remove(type);
98 Mock::VerifyAndClear(&service_);
99 ON_CALL(service_, GetPreferredDataTypes()).
100 WillByDefault(Return(preferred_types_));
103 private:
104 scoped_ptr<SyncSessionSnapshot> snap_;
105 base::MessageLoop message_loop_;
106 syncer::ModelTypeSet preferred_types_;
107 TestingProfile profile_;
108 NiceMock<ProfileSyncServiceMock> service_;
109 NiceMock<DataTypeManagerMock> manager_;
110 syncer::TestUserShare test_user_share_;
111 scoped_ptr<BackendMigrator> migrator_;
114 class MockMigrationObserver : public MigrationObserver {
115 public:
116 virtual ~MockMigrationObserver() {}
118 MOCK_METHOD0(OnMigrationStateChange, void());
121 // Test that in the normal case a migration does transition through each state
122 // and wind up back in IDLE.
123 TEST_F(SyncBackendMigratorTest, Sanity) {
124 MockMigrationObserver migration_observer;
125 migrator()->AddMigrationObserver(&migration_observer);
126 EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
128 syncer::ModelTypeSet to_migrate, difference;
129 to_migrate.Put(syncer::PREFERENCES);
130 difference.Put(syncer::AUTOFILL);
131 difference.Put(syncer::BOOKMARKS);
133 EXPECT_CALL(*manager(), state())
134 .WillOnce(Return(DataTypeManager::CONFIGURED));
135 EXPECT_CALL(
136 *manager(),
137 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
138 EXPECT_CALL(
139 *manager(),
140 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
142 migrator()->MigrateTypes(to_migrate);
143 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
145 SetUnsyncedTypes(to_migrate);
146 SendConfigureDone(DataTypeManager::OK, difference);
147 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
149 SetUnsyncedTypes(syncer::ModelTypeSet());
150 SendConfigureDone(DataTypeManager::OK, preferred_types());
151 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
153 migrator()->RemoveMigrationObserver(&migration_observer);
156 // Test that in the normal case with Nigori a migration transitions through
157 // each state and wind up back in IDLE.
158 TEST_F(SyncBackendMigratorTest, MigrateNigori) {
159 syncer::ModelTypeSet to_migrate, difference;
160 to_migrate.Put(syncer::NIGORI);
161 difference.Put(syncer::AUTOFILL);
162 difference.Put(syncer::BOOKMARKS);
164 EXPECT_CALL(*manager(), state())
165 .WillOnce(Return(DataTypeManager::CONFIGURED));
167 EXPECT_CALL(*manager(), PurgeForMigration(_,
168 syncer::CONFIGURE_REASON_MIGRATION));
170 migrator()->MigrateTypes(to_migrate);
171 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
173 SetUnsyncedTypes(to_migrate);
174 SendConfigureDone(DataTypeManager::OK, difference);
175 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
177 SetUnsyncedTypes(syncer::ModelTypeSet());
178 SendConfigureDone(DataTypeManager::OK, preferred_types());
179 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
183 // Test that the migrator waits for the data type manager to be idle before
184 // starting a migration.
185 TEST_F(SyncBackendMigratorTest, WaitToStart) {
186 syncer::ModelTypeSet to_migrate;
187 to_migrate.Put(syncer::PREFERENCES);
189 EXPECT_CALL(*manager(), state())
190 .WillOnce(Return(DataTypeManager::CONFIGURING));
191 EXPECT_CALL(*manager(), Configure(_, _)).Times(0);
192 migrator()->MigrateTypes(to_migrate);
193 EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
195 Mock::VerifyAndClearExpectations(manager());
196 EXPECT_CALL(*manager(), state())
197 .WillOnce(Return(DataTypeManager::CONFIGURED));
198 EXPECT_CALL(*manager(),
199 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION));
200 SetUnsyncedTypes(syncer::ModelTypeSet());
201 SendConfigureDone(DataTypeManager::OK, syncer::ModelTypeSet());
203 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
206 // Test that the migrator can cope with a migration request while a migration
207 // is in progress.
208 TEST_F(SyncBackendMigratorTest, RestartMigration) {
209 syncer::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
210 to_migrate1.Put(syncer::PREFERENCES);
211 to_migrate2.Put(syncer::AUTOFILL);
212 to_migrate_union.Put(syncer::PREFERENCES);
213 to_migrate_union.Put(syncer::AUTOFILL);
214 bookmarks.Put(syncer::BOOKMARKS);
216 EXPECT_CALL(*manager(), state())
217 .WillOnce(Return(DataTypeManager::CONFIGURED));
218 EXPECT_CALL(
219 *manager(),
220 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(2);
221 migrator()->MigrateTypes(to_migrate1);
223 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
224 migrator()->MigrateTypes(to_migrate2);
226 const syncer::ModelTypeSet difference1 =
227 Difference(preferred_types(), to_migrate1);
229 Mock::VerifyAndClearExpectations(manager());
230 EXPECT_CALL(
231 *manager(),
232 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
233 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
234 .Times(1);
235 SetUnsyncedTypes(to_migrate1);
236 SendConfigureDone(DataTypeManager::OK, difference1);
237 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
239 SetUnsyncedTypes(to_migrate_union);
240 SendConfigureDone(DataTypeManager::OK, bookmarks);
241 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
244 // Test that an external invocation of Configure(...) during a migration results
245 // in a migration reattempt.
246 TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
247 syncer::ModelTypeSet to_migrate;
248 syncer::ModelTypeSet difference;
249 to_migrate.Put(syncer::PREFERENCES);
250 difference.Put(syncer::AUTOFILL);
251 difference.Put(syncer::BOOKMARKS);
253 EXPECT_CALL(*manager(), state())
254 .WillOnce(Return(DataTypeManager::CONFIGURED));
255 EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate),
256 syncer::CONFIGURE_REASON_MIGRATION));
257 migrator()->MigrateTypes(to_migrate);
258 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
260 Mock::VerifyAndClearExpectations(manager());
261 EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate),
262 syncer::CONFIGURE_REASON_MIGRATION));
263 SetUnsyncedTypes(syncer::ModelTypeSet());
264 SendConfigureDone(DataTypeManager::OK, preferred_types());
266 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
269 // Test that spurious OnConfigureDone events don't confuse the
270 // migrator while it's waiting for disabled types to have been purged
271 // from the sync db.
272 TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
273 syncer::ModelTypeSet to_migrate, difference;
274 to_migrate.Put(syncer::PREFERENCES);
275 to_migrate.Put(syncer::AUTOFILL);
276 difference.Put(syncer::BOOKMARKS);
278 EXPECT_CALL(*manager(), state())
279 .WillOnce(Return(DataTypeManager::CONFIGURED));
280 EXPECT_CALL(
281 *manager(),
282 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
283 EXPECT_CALL(
284 *manager(),
285 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
287 migrator()->MigrateTypes(to_migrate);
288 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
290 SendConfigureDone(DataTypeManager::OK, difference);
291 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
293 syncer::ModelTypeSet prefs;
294 prefs.Put(syncer::PREFERENCES);
295 SetUnsyncedTypes(prefs);
296 SendConfigureDone(DataTypeManager::OK, difference);
297 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
299 SetUnsyncedTypes(to_migrate);
300 SendConfigureDone(DataTypeManager::OK, difference);
301 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
304 TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) {
305 syncer::ModelTypeSet to_migrate;
306 to_migrate.Put(syncer::PREFERENCES);
308 EXPECT_CALL(*manager(), state())
309 .WillOnce(Return(DataTypeManager::CONFIGURED));
310 EXPECT_CALL(
311 *manager(),
312 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
313 EXPECT_CALL(
314 *manager(),
315 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
316 migrator()->MigrateTypes(to_migrate);
318 RemovePreferredType(syncer::PREFERENCES);
319 SetUnsyncedTypes(to_migrate);
320 SendConfigureDone(DataTypeManager::OK, preferred_types());
321 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
322 SetUnsyncedTypes(syncer::ModelTypeSet());
323 SendConfigureDone(DataTypeManager::OK, preferred_types());
324 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
327 TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
328 syncer::ModelTypeSet to_migrate;
329 to_migrate.Put(syncer::PREFERENCES);
331 EXPECT_CALL(*manager(), state())
332 .WillOnce(Return(DataTypeManager::CONFIGURED));
333 EXPECT_CALL(
334 *manager(),
335 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
336 migrator()->MigrateTypes(to_migrate);
337 SetUnsyncedTypes(syncer::ModelTypeSet());
338 SendConfigureDone(DataTypeManager::ABORTED, syncer::ModelTypeSet());
339 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
342 }; // namespace browser_sync