blob: 05b8dc5bb02e63553c4d1b3ace32f9d563548531 [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]91835ca2012-04-21 09:59:4213#include "sync/internal_api/test_user_share.h"
14#include "sync/internal_api/write_transaction.h"
[email protected]1bcf30e2012-03-10 01:06:4115#include "sync/protocol/sync.pb.h"
[email protected]dc556252011-04-20 01:59:3516#include "testing/gmock/include/gmock/gmock.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19using ::testing::_;
20using ::testing::Eq;
21using ::testing::Mock;
22using ::testing::NiceMock;
23using ::testing::Return;
[email protected]dc556252011-04-20 01:59:3524
25namespace browser_sync {
26
27using sessions::ErrorCounters;
28using sessions::SyncerStatus;
29using sessions::SyncSessionSnapshot;
30
[email protected]b486b462012-02-11 00:11:4231class SyncBackendMigratorTest : public testing::Test {
[email protected]dc556252011-04-20 01:59:3532 public:
[email protected]b486b462012-02-11 00:11:4233 SyncBackendMigratorTest() { }
34 virtual ~SyncBackendMigratorTest() { }
[email protected]dc556252011-04-20 01:59:3535
36 virtual void SetUp() {
[email protected]1a425fc2011-09-01 23:11:5937 test_user_share_.SetUp();
[email protected]dc556252011-04-20 01:59:3538 Mock::VerifyAndClear(manager());
39 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:5440 preferred_types_.Put(syncable::BOOKMARKS);
41 preferred_types_.Put(syncable::PREFERENCES);
42 preferred_types_.Put(syncable::AUTOFILL);
[email protected]dc556252011-04-20 01:59:3543
[email protected]71229fa82011-12-10 01:00:5444 ON_CALL(service_, GetPreferredDataTypes()).
45 WillByDefault(Return(preferred_types_));
[email protected]1a425fc2011-09-01 23:11:5946
47 migrator_.reset(
48 new BackendMigrator(
[email protected]32d7c332012-04-23 19:44:0949 "Profile0", test_user_share_.user_share(), service(), manager(),
50 base::Closure()));
[email protected]400f521a2011-12-13 01:50:2351 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:3552 }
53
[email protected]1a425fc2011-09-01 23:11:5954 virtual void TearDown() {
55 migrator_.reset();
56 test_user_share_.TearDown();
[email protected]dc556252011-04-20 01:59:3557 }
58
[email protected]1a425fc2011-09-01 23:11:5959 // Marks all types in |unsynced_types| as unsynced and all other
60 // types as synced.
[email protected]400f521a2011-12-13 01:50:2361 void SetUnsyncedTypes(syncable::ModelTypeSet unsynced_types) {
[email protected]1a425fc2011-09-01 23:11:5962 sync_api::WriteTransaction trans(FROM_HERE,
63 test_user_share_.user_share());
64 for (int i = syncable::FIRST_REAL_MODEL_TYPE;
65 i < syncable::MODEL_TYPE_COUNT; ++i) {
66 syncable::ModelType type = syncable::ModelTypeFromInt(i);
67 sync_pb::DataTypeProgressMarker progress_marker;
[email protected]71229fa82011-12-10 01:00:5468 if (!unsynced_types.Has(type)) {
[email protected]1a425fc2011-09-01 23:11:5969 progress_marker.set_token("dummy");
70 }
[email protected]30aebeb92012-02-28 05:27:1571 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
[email protected]dc556252011-04-20 01:59:3572 }
[email protected]dc556252011-04-20 01:59:3573 }
74
[email protected]de7d78c72011-07-26 23:41:5075 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
[email protected]400f521a2011-12-13 01:50:2376 syncable::ModelTypeSet requested_types) {
[email protected]de7d78c72011-07-26 23:41:5077 if (status == DataTypeManager::OK) {
[email protected]1a425fc2011-09-01 23:11:5978 DataTypeManager::ConfigureResult result(status, requested_types);
[email protected]32d7c332012-04-23 19:44:0979 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5080 } else {
[email protected]631b193f2011-10-06 08:07:4681 std::list<SyncError> errors;
82 DataTypeManager::ConfigureResult result(
83 status,
84 requested_types,
[email protected]46220c22012-05-23 23:26:5085 errors,
86 syncable::ModelTypeSet());
[email protected]32d7c332012-04-23 19:44:0987 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5088 }
[email protected]1a425fc2011-09-01 23:11:5989 message_loop_.RunAllPending();
[email protected]dc556252011-04-20 01:59:3590 }
91
92 ProfileSyncService* service() { return &service_; }
93 DataTypeManagerMock* manager() { return &manager_; }
[email protected]400f521a2011-12-13 01:50:2394 syncable::ModelTypeSet preferred_types() { return preferred_types_; }
[email protected]1a425fc2011-09-01 23:11:5995 BackendMigrator* migrator() { return migrator_.get(); }
[email protected]dc556252011-04-20 01:59:3596 void RemovePreferredType(syncable::ModelType type) {
[email protected]71229fa82011-12-10 01:00:5497 preferred_types_.Remove(type);
[email protected]dc556252011-04-20 01:59:3598 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:5499 ON_CALL(service_, GetPreferredDataTypes()).
100 WillByDefault(Return(preferred_types_));
[email protected]dc556252011-04-20 01:59:35101 }
[email protected]1a425fc2011-09-01 23:11:59102
[email protected]dc556252011-04-20 01:59:35103 private:
104 scoped_ptr<SyncSessionSnapshot> snap_;
[email protected]1a425fc2011-09-01 23:11:59105 MessageLoop message_loop_;
[email protected]400f521a2011-12-13 01:50:23106 syncable::ModelTypeSet preferred_types_;
[email protected]dc556252011-04-20 01:59:35107 NiceMock<ProfileSyncServiceMock> service_;
108 NiceMock<DataTypeManagerMock> manager_;
[email protected]1a425fc2011-09-01 23:11:59109 TestUserShare test_user_share_;
110 scoped_ptr<BackendMigrator> migrator_;
111};
112
113class MockMigrationObserver : public MigrationObserver {
114 public:
115 virtual ~MockMigrationObserver() {}
116
117 MOCK_METHOD0(OnMigrationStateChange, void());
[email protected]dc556252011-04-20 01:59:35118};
119
120// Test that in the normal case a migration does transition through each state
121// and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42122TEST_F(SyncBackendMigratorTest, Sanity) {
[email protected]1a425fc2011-09-01 23:11:59123 MockMigrationObserver migration_observer;
124 migrator()->AddMigrationObserver(&migration_observer);
125 EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
126
[email protected]400f521a2011-12-13 01:50:23127 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54128 to_migrate.Put(syncable::PREFERENCES);
129 difference.Put(syncable::AUTOFILL);
130 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35131
132 EXPECT_CALL(*manager(), state())
133 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59134 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
135 .Times(2);
[email protected]dc556252011-04-20 01:59:35136
[email protected]1a425fc2011-09-01 23:11:59137 migrator()->MigrateTypes(to_migrate);
138 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35139
[email protected]1a425fc2011-09-01 23:11:59140 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35141 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59142 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35143
[email protected]400f521a2011-12-13 01:50:23144 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35145 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59146 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
147
148 migrator()->RemoveMigrationObserver(&migration_observer);
[email protected]dc556252011-04-20 01:59:35149}
150
[email protected]8e8aea772011-06-02 18:43:57151// Test that in the normal case with Nigori a migration transitions through
152// each state and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42153TEST_F(SyncBackendMigratorTest, MigrateNigori) {
[email protected]400f521a2011-12-13 01:50:23154 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54155 to_migrate.Put(syncable::NIGORI);
156 difference.Put(syncable::AUTOFILL);
157 difference.Put(syncable::BOOKMARKS);
[email protected]8e8aea772011-06-02 18:43:57158
159 EXPECT_CALL(*manager(), state())
160 .WillOnce(Return(DataTypeManager::CONFIGURED));
161
162 EXPECT_CALL(*manager(), ConfigureWithoutNigori(_,
163 sync_api::CONFIGURE_REASON_MIGRATION));
164
[email protected]1a425fc2011-09-01 23:11:59165 migrator()->MigrateTypes(to_migrate);
166 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57167
[email protected]1a425fc2011-09-01 23:11:59168 SetUnsyncedTypes(to_migrate);
[email protected]8e8aea772011-06-02 18:43:57169 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59170 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57171
[email protected]400f521a2011-12-13 01:50:23172 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]8e8aea772011-06-02 18:43:57173 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59174 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57175}
176
177
[email protected]dc556252011-04-20 01:59:35178// Test that the migrator waits for the data type manager to be idle before
179// starting a migration.
[email protected]b486b462012-02-11 00:11:42180TEST_F(SyncBackendMigratorTest, WaitToStart) {
[email protected]400f521a2011-12-13 01:50:23181 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54182 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35183
184 EXPECT_CALL(*manager(), state())
185 .WillOnce(Return(DataTypeManager::CONFIGURING));
[email protected]b2a3c142011-05-05 03:29:55186 EXPECT_CALL(*manager(), Configure(_, _)).Times(0);
[email protected]1a425fc2011-09-01 23:11:59187 migrator()->MigrateTypes(to_migrate);
188 EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
[email protected]dc556252011-04-20 01:59:35189
190 Mock::VerifyAndClearExpectations(manager());
191 EXPECT_CALL(*manager(), state())
192 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55193 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23194 SetUnsyncedTypes(syncable::ModelTypeSet());
195 SendConfigureDone(DataTypeManager::OK, syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35196
[email protected]1a425fc2011-09-01 23:11:59197 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35198}
199
200// Test that the migrator can cope with a migration request while a migration
201// is in progress.
[email protected]b486b462012-02-11 00:11:42202TEST_F(SyncBackendMigratorTest, RestartMigration) {
[email protected]400f521a2011-12-13 01:50:23203 syncable::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
[email protected]71229fa82011-12-10 01:00:54204 to_migrate1.Put(syncable::PREFERENCES);
205 to_migrate2.Put(syncable::AUTOFILL);
206 to_migrate_union.Put(syncable::PREFERENCES);
207 to_migrate_union.Put(syncable::AUTOFILL);
208 bookmarks.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35209
210 EXPECT_CALL(*manager(), state())
211 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55212 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59213 .Times(2);
214 migrator()->MigrateTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35215
[email protected]1a425fc2011-09-01 23:11:59216 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
217 migrator()->MigrateTypes(to_migrate2);
[email protected]dc556252011-04-20 01:59:35218
[email protected]400f521a2011-12-13 01:50:23219 const syncable::ModelTypeSet difference1 =
[email protected]71229fa82011-12-10 01:00:54220 Difference(preferred_types(), to_migrate1);
[email protected]dc556252011-04-20 01:59:35221
222 Mock::VerifyAndClearExpectations(manager());
[email protected]1a425fc2011-09-01 23:11:59223 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
224 .Times(2);
225 SetUnsyncedTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35226 SendConfigureDone(DataTypeManager::OK, difference1);
[email protected]1a425fc2011-09-01 23:11:59227 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35228
[email protected]1a425fc2011-09-01 23:11:59229 SetUnsyncedTypes(to_migrate_union);
[email protected]dc556252011-04-20 01:59:35230 SendConfigureDone(DataTypeManager::OK, bookmarks);
[email protected]1a425fc2011-09-01 23:11:59231 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35232}
233
234// Test that an external invocation of Configure(...) during a migration results
235// in a migration reattempt.
[email protected]b486b462012-02-11 00:11:42236TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
[email protected]400f521a2011-12-13 01:50:23237 syncable::ModelTypeSet to_migrate;
238 syncable::ModelTypeSet difference;
[email protected]71229fa82011-12-10 01:00:54239 to_migrate.Put(syncable::PREFERENCES);
240 difference.Put(syncable::AUTOFILL);
241 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35242
243 EXPECT_CALL(*manager(), state())
244 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]71229fa82011-12-10 01:00:54245 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]b2a3c142011-05-05 03:29:55246 sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]1a425fc2011-09-01 23:11:59247 migrator()->MigrateTypes(to_migrate);
248 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35249
250 Mock::VerifyAndClearExpectations(manager());
[email protected]71229fa82011-12-10 01:00:54251 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]b2a3c142011-05-05 03:29:55252 sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23253 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35254 SendConfigureDone(DataTypeManager::OK, preferred_types());
255
[email protected]1a425fc2011-09-01 23:11:59256 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35257}
258
[email protected]1a425fc2011-09-01 23:11:59259// Test that spurious OnConfigureDone events don't confuse the
260// migrator while it's waiting for disabled types to have been purged
261// from the sync db.
[email protected]b486b462012-02-11 00:11:42262TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
[email protected]400f521a2011-12-13 01:50:23263 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54264 to_migrate.Put(syncable::PREFERENCES);
265 to_migrate.Put(syncable::AUTOFILL);
266 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35267
268 EXPECT_CALL(*manager(), state())
269 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59270 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
271 .Times(2);
[email protected]dc556252011-04-20 01:59:35272
[email protected]1a425fc2011-09-01 23:11:59273 migrator()->MigrateTypes(to_migrate);
274 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
275
276 SendConfigureDone(DataTypeManager::OK, difference);
277 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35278
[email protected]400f521a2011-12-13 01:50:23279 syncable::ModelTypeSet prefs;
[email protected]71229fa82011-12-10 01:00:54280 prefs.Put(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59281 SetUnsyncedTypes(prefs);
282 SendConfigureDone(DataTypeManager::OK, difference);
283 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35284
[email protected]1a425fc2011-09-01 23:11:59285 SetUnsyncedTypes(to_migrate);
286 SendConfigureDone(DataTypeManager::OK, difference);
287 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35288}
289
[email protected]b486b462012-02-11 00:11:42290TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) {
[email protected]400f521a2011-12-13 01:50:23291 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54292 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35293
294 EXPECT_CALL(*manager(), state())
295 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59296 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
297 .Times(2);
298 migrator()->MigrateTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35299
300 RemovePreferredType(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59301 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35302 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59303 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]400f521a2011-12-13 01:50:23304 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35305 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59306 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35307}
308
[email protected]b486b462012-02-11 00:11:42309TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
[email protected]400f521a2011-12-13 01:50:23310 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54311 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35312
313 EXPECT_CALL(*manager(), state())
314 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55315 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
316 .Times(1);
[email protected]1a425fc2011-09-01 23:11:59317 migrator()->MigrateTypes(to_migrate);
[email protected]400f521a2011-12-13 01:50:23318 SetUnsyncedTypes(syncable::ModelTypeSet());
319 SendConfigureDone(DataTypeManager::ABORTED, syncable::ModelTypeSet());
[email protected]1a425fc2011-09-01 23:11:59320 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35321}
322
323}; // namespace browser_sync