blob: 64ae64b92baeb24c56d016f86fde0fb0c507f39d [file] [log] [blame]
[email protected]b486b462012-02-11 00:11:421// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]dc556252011-04-20 01:59:352// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/sync/backend_migrator.h"
6
[email protected]1a425fc2011-09-01 23:11:597#include "base/message_loop.h"
8#include "base/tracked_objects.h"
[email protected]dc556252011-04-20 01:59:359#include "chrome/browser/sync/glue/data_type_manager_mock.h"
10#include "chrome/browser/sync/profile_sync_service_mock.h"
[email protected]432115822011-07-10 15:52:2711#include "chrome/common/chrome_notification_types.h"
[email protected]3f8556a2012-06-07 17:50:1912#include "sync/internal_api/public/syncable/model_type_test_util.h"
[email protected]406203d2012-06-17 01:07:1913#include "sync/internal_api/public/test/test_user_share.h"
14#include "sync/internal_api/public/write_transaction.h"
[email protected]1bcf30e2012-03-10 01:06:4115#include "sync/protocol/sync.pb.h"
[email protected]15732672012-06-20 18:58:2616#include "sync/syncable/directory.h" // TODO(tim): Remove. Bug 131130.
[email protected]dc556252011-04-20 01:59:3517#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20using ::testing::_;
21using ::testing::Eq;
22using ::testing::Mock;
23using ::testing::NiceMock;
24using ::testing::Return;
[email protected]dc556252011-04-20 01:59:3525
26namespace browser_sync {
27
[email protected]65f173552012-06-28 22:43:5828using syncer::sessions::SyncSessionSnapshot;
[email protected]dc556252011-04-20 01:59:3529
[email protected]b486b462012-02-11 00:11:4230class SyncBackendMigratorTest : public testing::Test {
[email protected]dc556252011-04-20 01:59:3531 public:
[email protected]b486b462012-02-11 00:11:4232 SyncBackendMigratorTest() { }
33 virtual ~SyncBackendMigratorTest() { }
[email protected]dc556252011-04-20 01:59:3534
35 virtual void SetUp() {
[email protected]1a425fc2011-09-01 23:11:5936 test_user_share_.SetUp();
[email protected]dc556252011-04-20 01:59:3537 Mock::VerifyAndClear(manager());
38 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:5439 preferred_types_.Put(syncable::BOOKMARKS);
40 preferred_types_.Put(syncable::PREFERENCES);
41 preferred_types_.Put(syncable::AUTOFILL);
[email protected]dc556252011-04-20 01:59:3542
[email protected]71229fa82011-12-10 01:00:5443 ON_CALL(service_, GetPreferredDataTypes()).
44 WillByDefault(Return(preferred_types_));
[email protected]1a425fc2011-09-01 23:11:5945
46 migrator_.reset(
47 new BackendMigrator(
[email protected]32d7c332012-04-23 19:44:0948 "Profile0", test_user_share_.user_share(), service(), manager(),
49 base::Closure()));
[email protected]400f521a2011-12-13 01:50:2350 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:3551 }
52
[email protected]1a425fc2011-09-01 23:11:5953 virtual void TearDown() {
54 migrator_.reset();
55 test_user_share_.TearDown();
[email protected]dc556252011-04-20 01:59:3556 }
57
[email protected]1a425fc2011-09-01 23:11:5958 // Marks all types in |unsynced_types| as unsynced and all other
59 // types as synced.
[email protected]400f521a2011-12-13 01:50:2360 void SetUnsyncedTypes(syncable::ModelTypeSet unsynced_types) {
[email protected]65f173552012-06-28 22:43:5861 syncer::WriteTransaction trans(FROM_HERE,
[email protected]1a425fc2011-09-01 23:11:5962 test_user_share_.user_share());
63 for (int i = syncable::FIRST_REAL_MODEL_TYPE;
64 i < syncable::MODEL_TYPE_COUNT; ++i) {
65 syncable::ModelType type = syncable::ModelTypeFromInt(i);
66 sync_pb::DataTypeProgressMarker progress_marker;
[email protected]71229fa82011-12-10 01:00:5467 if (!unsynced_types.Has(type)) {
[email protected]1a425fc2011-09-01 23:11:5968 progress_marker.set_token("dummy");
69 }
[email protected]30aebeb92012-02-28 05:27:1570 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
[email protected]dc556252011-04-20 01:59:3571 }
[email protected]dc556252011-04-20 01:59:3572 }
73
[email protected]de7d78c72011-07-26 23:41:5074 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
[email protected]400f521a2011-12-13 01:50:2375 syncable::ModelTypeSet requested_types) {
[email protected]de7d78c72011-07-26 23:41:5076 if (status == DataTypeManager::OK) {
[email protected]1a425fc2011-09-01 23:11:5977 DataTypeManager::ConfigureResult result(status, requested_types);
[email protected]32d7c332012-04-23 19:44:0978 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5079 } else {
[email protected]65f173552012-06-28 22:43:5880 std::list<syncer::SyncError> errors;
[email protected]631b193f2011-10-06 08:07:4681 DataTypeManager::ConfigureResult result(
82 status,
83 requested_types,
[email protected]46220c22012-05-23 23:26:5084 errors,
85 syncable::ModelTypeSet());
[email protected]32d7c332012-04-23 19:44:0986 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5087 }
[email protected]1a425fc2011-09-01 23:11:5988 message_loop_.RunAllPending();
[email protected]dc556252011-04-20 01:59:3589 }
90
91 ProfileSyncService* service() { return &service_; }
92 DataTypeManagerMock* manager() { return &manager_; }
[email protected]400f521a2011-12-13 01:50:2393 syncable::ModelTypeSet preferred_types() { return preferred_types_; }
[email protected]1a425fc2011-09-01 23:11:5994 BackendMigrator* migrator() { return migrator_.get(); }
[email protected]dc556252011-04-20 01:59:3595 void RemovePreferredType(syncable::ModelType type) {
[email protected]71229fa82011-12-10 01:00:5496 preferred_types_.Remove(type);
[email protected]dc556252011-04-20 01:59:3597 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:5498 ON_CALL(service_, GetPreferredDataTypes()).
99 WillByDefault(Return(preferred_types_));
[email protected]dc556252011-04-20 01:59:35100 }
[email protected]1a425fc2011-09-01 23:11:59101
[email protected]dc556252011-04-20 01:59:35102 private:
103 scoped_ptr<SyncSessionSnapshot> snap_;
[email protected]1a425fc2011-09-01 23:11:59104 MessageLoop message_loop_;
[email protected]400f521a2011-12-13 01:50:23105 syncable::ModelTypeSet preferred_types_;
[email protected]dc556252011-04-20 01:59:35106 NiceMock<ProfileSyncServiceMock> service_;
107 NiceMock<DataTypeManagerMock> manager_;
[email protected]65f173552012-06-28 22:43:58108 syncer::TestUserShare test_user_share_;
[email protected]1a425fc2011-09-01 23:11:59109 scoped_ptr<BackendMigrator> migrator_;
110};
111
112class MockMigrationObserver : public MigrationObserver {
113 public:
114 virtual ~MockMigrationObserver() {}
115
116 MOCK_METHOD0(OnMigrationStateChange, void());
[email protected]dc556252011-04-20 01:59:35117};
118
119// Test that in the normal case a migration does transition through each state
120// and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42121TEST_F(SyncBackendMigratorTest, Sanity) {
[email protected]1a425fc2011-09-01 23:11:59122 MockMigrationObserver migration_observer;
123 migrator()->AddMigrationObserver(&migration_observer);
124 EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
125
[email protected]400f521a2011-12-13 01:50:23126 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54127 to_migrate.Put(syncable::PREFERENCES);
128 difference.Put(syncable::AUTOFILL);
129 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35130
131 EXPECT_CALL(*manager(), state())
132 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58133 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59134 .Times(2);
[email protected]dc556252011-04-20 01:59:35135
[email protected]1a425fc2011-09-01 23:11:59136 migrator()->MigrateTypes(to_migrate);
137 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35138
[email protected]1a425fc2011-09-01 23:11:59139 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35140 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59141 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35142
[email protected]400f521a2011-12-13 01:50:23143 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35144 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59145 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
146
147 migrator()->RemoveMigrationObserver(&migration_observer);
[email protected]dc556252011-04-20 01:59:35148}
149
[email protected]8e8aea772011-06-02 18:43:57150// Test that in the normal case with Nigori a migration transitions through
151// each state and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42152TEST_F(SyncBackendMigratorTest, MigrateNigori) {
[email protected]400f521a2011-12-13 01:50:23153 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54154 to_migrate.Put(syncable::NIGORI);
155 difference.Put(syncable::AUTOFILL);
156 difference.Put(syncable::BOOKMARKS);
[email protected]8e8aea772011-06-02 18:43:57157
158 EXPECT_CALL(*manager(), state())
159 .WillOnce(Return(DataTypeManager::CONFIGURED));
160
161 EXPECT_CALL(*manager(), ConfigureWithoutNigori(_,
[email protected]65f173552012-06-28 22:43:58162 syncer::CONFIGURE_REASON_MIGRATION));
[email protected]8e8aea772011-06-02 18:43:57163
[email protected]1a425fc2011-09-01 23:11:59164 migrator()->MigrateTypes(to_migrate);
165 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57166
[email protected]1a425fc2011-09-01 23:11:59167 SetUnsyncedTypes(to_migrate);
[email protected]8e8aea772011-06-02 18:43:57168 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59169 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57170
[email protected]400f521a2011-12-13 01:50:23171 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]8e8aea772011-06-02 18:43:57172 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59173 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57174}
175
176
[email protected]dc556252011-04-20 01:59:35177// Test that the migrator waits for the data type manager to be idle before
178// starting a migration.
[email protected]b486b462012-02-11 00:11:42179TEST_F(SyncBackendMigratorTest, WaitToStart) {
[email protected]400f521a2011-12-13 01:50:23180 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54181 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35182
183 EXPECT_CALL(*manager(), state())
184 .WillOnce(Return(DataTypeManager::CONFIGURING));
[email protected]b2a3c142011-05-05 03:29:55185 EXPECT_CALL(*manager(), Configure(_, _)).Times(0);
[email protected]1a425fc2011-09-01 23:11:59186 migrator()->MigrateTypes(to_migrate);
187 EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
[email protected]dc556252011-04-20 01:59:35188
189 Mock::VerifyAndClearExpectations(manager());
190 EXPECT_CALL(*manager(), state())
191 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58192 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23193 SetUnsyncedTypes(syncable::ModelTypeSet());
194 SendConfigureDone(DataTypeManager::OK, syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35195
[email protected]1a425fc2011-09-01 23:11:59196 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35197}
198
199// Test that the migrator can cope with a migration request while a migration
200// is in progress.
[email protected]b486b462012-02-11 00:11:42201TEST_F(SyncBackendMigratorTest, RestartMigration) {
[email protected]400f521a2011-12-13 01:50:23202 syncable::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
[email protected]71229fa82011-12-10 01:00:54203 to_migrate1.Put(syncable::PREFERENCES);
204 to_migrate2.Put(syncable::AUTOFILL);
205 to_migrate_union.Put(syncable::PREFERENCES);
206 to_migrate_union.Put(syncable::AUTOFILL);
207 bookmarks.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35208
209 EXPECT_CALL(*manager(), state())
210 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58211 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59212 .Times(2);
213 migrator()->MigrateTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35214
[email protected]1a425fc2011-09-01 23:11:59215 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
216 migrator()->MigrateTypes(to_migrate2);
[email protected]dc556252011-04-20 01:59:35217
[email protected]400f521a2011-12-13 01:50:23218 const syncable::ModelTypeSet difference1 =
[email protected]71229fa82011-12-10 01:00:54219 Difference(preferred_types(), to_migrate1);
[email protected]dc556252011-04-20 01:59:35220
221 Mock::VerifyAndClearExpectations(manager());
[email protected]65f173552012-06-28 22:43:58222 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59223 .Times(2);
224 SetUnsyncedTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35225 SendConfigureDone(DataTypeManager::OK, difference1);
[email protected]1a425fc2011-09-01 23:11:59226 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35227
[email protected]1a425fc2011-09-01 23:11:59228 SetUnsyncedTypes(to_migrate_union);
[email protected]dc556252011-04-20 01:59:35229 SendConfigureDone(DataTypeManager::OK, bookmarks);
[email protected]1a425fc2011-09-01 23:11:59230 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35231}
232
233// Test that an external invocation of Configure(...) during a migration results
234// in a migration reattempt.
[email protected]b486b462012-02-11 00:11:42235TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
[email protected]400f521a2011-12-13 01:50:23236 syncable::ModelTypeSet to_migrate;
237 syncable::ModelTypeSet difference;
[email protected]71229fa82011-12-10 01:00:54238 to_migrate.Put(syncable::PREFERENCES);
239 difference.Put(syncable::AUTOFILL);
240 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35241
242 EXPECT_CALL(*manager(), state())
243 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]71229fa82011-12-10 01:00:54244 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]65f173552012-06-28 22:43:58245 syncer::CONFIGURE_REASON_MIGRATION));
[email protected]1a425fc2011-09-01 23:11:59246 migrator()->MigrateTypes(to_migrate);
247 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35248
249 Mock::VerifyAndClearExpectations(manager());
[email protected]71229fa82011-12-10 01:00:54250 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]65f173552012-06-28 22:43:58251 syncer::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23252 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35253 SendConfigureDone(DataTypeManager::OK, preferred_types());
254
[email protected]1a425fc2011-09-01 23:11:59255 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35256}
257
[email protected]1a425fc2011-09-01 23:11:59258// Test that spurious OnConfigureDone events don't confuse the
259// migrator while it's waiting for disabled types to have been purged
260// from the sync db.
[email protected]b486b462012-02-11 00:11:42261TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
[email protected]400f521a2011-12-13 01:50:23262 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54263 to_migrate.Put(syncable::PREFERENCES);
264 to_migrate.Put(syncable::AUTOFILL);
265 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35266
267 EXPECT_CALL(*manager(), state())
268 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58269 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59270 .Times(2);
[email protected]dc556252011-04-20 01:59:35271
[email protected]1a425fc2011-09-01 23:11:59272 migrator()->MigrateTypes(to_migrate);
273 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
274
275 SendConfigureDone(DataTypeManager::OK, difference);
276 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35277
[email protected]400f521a2011-12-13 01:50:23278 syncable::ModelTypeSet prefs;
[email protected]71229fa82011-12-10 01:00:54279 prefs.Put(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59280 SetUnsyncedTypes(prefs);
281 SendConfigureDone(DataTypeManager::OK, difference);
282 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35283
[email protected]1a425fc2011-09-01 23:11:59284 SetUnsyncedTypes(to_migrate);
285 SendConfigureDone(DataTypeManager::OK, difference);
286 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35287}
288
[email protected]b486b462012-02-11 00:11:42289TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) {
[email protected]400f521a2011-12-13 01:50:23290 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54291 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35292
293 EXPECT_CALL(*manager(), state())
294 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58295 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59296 .Times(2);
297 migrator()->MigrateTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35298
299 RemovePreferredType(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59300 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35301 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59302 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]400f521a2011-12-13 01:50:23303 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35304 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59305 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35306}
307
[email protected]b486b462012-02-11 00:11:42308TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
[email protected]400f521a2011-12-13 01:50:23309 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54310 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35311
312 EXPECT_CALL(*manager(), state())
313 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]65f173552012-06-28 22:43:58314 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
[email protected]b2a3c142011-05-05 03:29:55315 .Times(1);
[email protected]1a425fc2011-09-01 23:11:59316 migrator()->MigrateTypes(to_migrate);
[email protected]400f521a2011-12-13 01:50:23317 SetUnsyncedTypes(syncable::ModelTypeSet());
318 SendConfigureDone(DataTypeManager::ABORTED, syncable::ModelTypeSet());
[email protected]1a425fc2011-09-01 23:11:59319 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35320}
321
322}; // namespace browser_sync