blob: f161b3d302f30d8d23f48ce841103e5cfa631629 [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]406203d2012-06-17 01:07:1916#include "sync/syncable/syncable.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
28using sessions::ErrorCounters;
29using sessions::SyncerStatus;
30using sessions::SyncSessionSnapshot;
31
[email protected]b486b462012-02-11 00:11:4232class SyncBackendMigratorTest : public testing::Test {
[email protected]dc556252011-04-20 01:59:3533 public:
[email protected]b486b462012-02-11 00:11:4234 SyncBackendMigratorTest() { }
35 virtual ~SyncBackendMigratorTest() { }
[email protected]dc556252011-04-20 01:59:3536
37 virtual void SetUp() {
[email protected]1a425fc2011-09-01 23:11:5938 test_user_share_.SetUp();
[email protected]dc556252011-04-20 01:59:3539 Mock::VerifyAndClear(manager());
40 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:5441 preferred_types_.Put(syncable::BOOKMARKS);
42 preferred_types_.Put(syncable::PREFERENCES);
43 preferred_types_.Put(syncable::AUTOFILL);
[email protected]dc556252011-04-20 01:59:3544
[email protected]71229fa82011-12-10 01:00:5445 ON_CALL(service_, GetPreferredDataTypes()).
46 WillByDefault(Return(preferred_types_));
[email protected]1a425fc2011-09-01 23:11:5947
48 migrator_.reset(
49 new BackendMigrator(
[email protected]32d7c332012-04-23 19:44:0950 "Profile0", test_user_share_.user_share(), service(), manager(),
51 base::Closure()));
[email protected]400f521a2011-12-13 01:50:2352 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:3553 }
54
[email protected]1a425fc2011-09-01 23:11:5955 virtual void TearDown() {
56 migrator_.reset();
57 test_user_share_.TearDown();
[email protected]dc556252011-04-20 01:59:3558 }
59
[email protected]1a425fc2011-09-01 23:11:5960 // Marks all types in |unsynced_types| as unsynced and all other
61 // types as synced.
[email protected]400f521a2011-12-13 01:50:2362 void SetUnsyncedTypes(syncable::ModelTypeSet unsynced_types) {
[email protected]1a425fc2011-09-01 23:11:5963 sync_api::WriteTransaction trans(FROM_HERE,
64 test_user_share_.user_share());
65 for (int i = syncable::FIRST_REAL_MODEL_TYPE;
66 i < syncable::MODEL_TYPE_COUNT; ++i) {
67 syncable::ModelType type = syncable::ModelTypeFromInt(i);
68 sync_pb::DataTypeProgressMarker progress_marker;
[email protected]71229fa82011-12-10 01:00:5469 if (!unsynced_types.Has(type)) {
[email protected]1a425fc2011-09-01 23:11:5970 progress_marker.set_token("dummy");
71 }
[email protected]30aebeb92012-02-28 05:27:1572 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
[email protected]dc556252011-04-20 01:59:3573 }
[email protected]dc556252011-04-20 01:59:3574 }
75
[email protected]de7d78c72011-07-26 23:41:5076 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
[email protected]400f521a2011-12-13 01:50:2377 syncable::ModelTypeSet requested_types) {
[email protected]de7d78c72011-07-26 23:41:5078 if (status == DataTypeManager::OK) {
[email protected]1a425fc2011-09-01 23:11:5979 DataTypeManager::ConfigureResult result(status, requested_types);
[email protected]32d7c332012-04-23 19:44:0980 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5081 } else {
[email protected]631b193f2011-10-06 08:07:4682 std::list<SyncError> errors;
83 DataTypeManager::ConfigureResult result(
84 status,
85 requested_types,
[email protected]46220c22012-05-23 23:26:5086 errors,
87 syncable::ModelTypeSet());
[email protected]32d7c332012-04-23 19:44:0988 migrator_->OnConfigureDone(result);
[email protected]de7d78c72011-07-26 23:41:5089 }
[email protected]1a425fc2011-09-01 23:11:5990 message_loop_.RunAllPending();
[email protected]dc556252011-04-20 01:59:3591 }
92
93 ProfileSyncService* service() { return &service_; }
94 DataTypeManagerMock* manager() { return &manager_; }
[email protected]400f521a2011-12-13 01:50:2395 syncable::ModelTypeSet preferred_types() { return preferred_types_; }
[email protected]1a425fc2011-09-01 23:11:5996 BackendMigrator* migrator() { return migrator_.get(); }
[email protected]dc556252011-04-20 01:59:3597 void RemovePreferredType(syncable::ModelType type) {
[email protected]71229fa82011-12-10 01:00:5498 preferred_types_.Remove(type);
[email protected]dc556252011-04-20 01:59:3599 Mock::VerifyAndClear(&service_);
[email protected]71229fa82011-12-10 01:00:54100 ON_CALL(service_, GetPreferredDataTypes()).
101 WillByDefault(Return(preferred_types_));
[email protected]dc556252011-04-20 01:59:35102 }
[email protected]1a425fc2011-09-01 23:11:59103
[email protected]dc556252011-04-20 01:59:35104 private:
105 scoped_ptr<SyncSessionSnapshot> snap_;
[email protected]1a425fc2011-09-01 23:11:59106 MessageLoop message_loop_;
[email protected]400f521a2011-12-13 01:50:23107 syncable::ModelTypeSet preferred_types_;
[email protected]dc556252011-04-20 01:59:35108 NiceMock<ProfileSyncServiceMock> service_;
109 NiceMock<DataTypeManagerMock> manager_;
[email protected]1a425fc2011-09-01 23:11:59110 TestUserShare test_user_share_;
111 scoped_ptr<BackendMigrator> migrator_;
112};
113
114class MockMigrationObserver : public MigrationObserver {
115 public:
116 virtual ~MockMigrationObserver() {}
117
118 MOCK_METHOD0(OnMigrationStateChange, void());
[email protected]dc556252011-04-20 01:59:35119};
120
121// Test that in the normal case a migration does transition through each state
122// and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42123TEST_F(SyncBackendMigratorTest, Sanity) {
[email protected]1a425fc2011-09-01 23:11:59124 MockMigrationObserver migration_observer;
125 migrator()->AddMigrationObserver(&migration_observer);
126 EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
127
[email protected]400f521a2011-12-13 01:50:23128 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54129 to_migrate.Put(syncable::PREFERENCES);
130 difference.Put(syncable::AUTOFILL);
131 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35132
133 EXPECT_CALL(*manager(), state())
134 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59135 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
136 .Times(2);
[email protected]dc556252011-04-20 01:59:35137
[email protected]1a425fc2011-09-01 23:11:59138 migrator()->MigrateTypes(to_migrate);
139 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35140
[email protected]1a425fc2011-09-01 23:11:59141 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35142 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59143 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35144
[email protected]400f521a2011-12-13 01:50:23145 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35146 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59147 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
148
149 migrator()->RemoveMigrationObserver(&migration_observer);
[email protected]dc556252011-04-20 01:59:35150}
151
[email protected]8e8aea772011-06-02 18:43:57152// Test that in the normal case with Nigori a migration transitions through
153// each state and wind up back in IDLE.
[email protected]b486b462012-02-11 00:11:42154TEST_F(SyncBackendMigratorTest, MigrateNigori) {
[email protected]400f521a2011-12-13 01:50:23155 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54156 to_migrate.Put(syncable::NIGORI);
157 difference.Put(syncable::AUTOFILL);
158 difference.Put(syncable::BOOKMARKS);
[email protected]8e8aea772011-06-02 18:43:57159
160 EXPECT_CALL(*manager(), state())
161 .WillOnce(Return(DataTypeManager::CONFIGURED));
162
163 EXPECT_CALL(*manager(), ConfigureWithoutNigori(_,
164 sync_api::CONFIGURE_REASON_MIGRATION));
165
[email protected]1a425fc2011-09-01 23:11:59166 migrator()->MigrateTypes(to_migrate);
167 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57168
[email protected]1a425fc2011-09-01 23:11:59169 SetUnsyncedTypes(to_migrate);
[email protected]8e8aea772011-06-02 18:43:57170 SendConfigureDone(DataTypeManager::OK, difference);
[email protected]1a425fc2011-09-01 23:11:59171 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57172
[email protected]400f521a2011-12-13 01:50:23173 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]8e8aea772011-06-02 18:43:57174 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59175 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]8e8aea772011-06-02 18:43:57176}
177
178
[email protected]dc556252011-04-20 01:59:35179// Test that the migrator waits for the data type manager to be idle before
180// starting a migration.
[email protected]b486b462012-02-11 00:11:42181TEST_F(SyncBackendMigratorTest, WaitToStart) {
[email protected]400f521a2011-12-13 01:50:23182 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54183 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35184
185 EXPECT_CALL(*manager(), state())
186 .WillOnce(Return(DataTypeManager::CONFIGURING));
[email protected]b2a3c142011-05-05 03:29:55187 EXPECT_CALL(*manager(), Configure(_, _)).Times(0);
[email protected]1a425fc2011-09-01 23:11:59188 migrator()->MigrateTypes(to_migrate);
189 EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
[email protected]dc556252011-04-20 01:59:35190
191 Mock::VerifyAndClearExpectations(manager());
192 EXPECT_CALL(*manager(), state())
193 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55194 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23195 SetUnsyncedTypes(syncable::ModelTypeSet());
196 SendConfigureDone(DataTypeManager::OK, syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35197
[email protected]1a425fc2011-09-01 23:11:59198 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35199}
200
201// Test that the migrator can cope with a migration request while a migration
202// is in progress.
[email protected]b486b462012-02-11 00:11:42203TEST_F(SyncBackendMigratorTest, RestartMigration) {
[email protected]400f521a2011-12-13 01:50:23204 syncable::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
[email protected]71229fa82011-12-10 01:00:54205 to_migrate1.Put(syncable::PREFERENCES);
206 to_migrate2.Put(syncable::AUTOFILL);
207 to_migrate_union.Put(syncable::PREFERENCES);
208 to_migrate_union.Put(syncable::AUTOFILL);
209 bookmarks.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35210
211 EXPECT_CALL(*manager(), state())
212 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55213 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
[email protected]1a425fc2011-09-01 23:11:59214 .Times(2);
215 migrator()->MigrateTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35216
[email protected]1a425fc2011-09-01 23:11:59217 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
218 migrator()->MigrateTypes(to_migrate2);
[email protected]dc556252011-04-20 01:59:35219
[email protected]400f521a2011-12-13 01:50:23220 const syncable::ModelTypeSet difference1 =
[email protected]71229fa82011-12-10 01:00:54221 Difference(preferred_types(), to_migrate1);
[email protected]dc556252011-04-20 01:59:35222
223 Mock::VerifyAndClearExpectations(manager());
[email protected]1a425fc2011-09-01 23:11:59224 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
225 .Times(2);
226 SetUnsyncedTypes(to_migrate1);
[email protected]dc556252011-04-20 01:59:35227 SendConfigureDone(DataTypeManager::OK, difference1);
[email protected]1a425fc2011-09-01 23:11:59228 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35229
[email protected]1a425fc2011-09-01 23:11:59230 SetUnsyncedTypes(to_migrate_union);
[email protected]dc556252011-04-20 01:59:35231 SendConfigureDone(DataTypeManager::OK, bookmarks);
[email protected]1a425fc2011-09-01 23:11:59232 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35233}
234
235// Test that an external invocation of Configure(...) during a migration results
236// in a migration reattempt.
[email protected]b486b462012-02-11 00:11:42237TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
[email protected]400f521a2011-12-13 01:50:23238 syncable::ModelTypeSet to_migrate;
239 syncable::ModelTypeSet difference;
[email protected]71229fa82011-12-10 01:00:54240 to_migrate.Put(syncable::PREFERENCES);
241 difference.Put(syncable::AUTOFILL);
242 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35243
244 EXPECT_CALL(*manager(), state())
245 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]71229fa82011-12-10 01:00:54246 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]b2a3c142011-05-05 03:29:55247 sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]1a425fc2011-09-01 23:11:59248 migrator()->MigrateTypes(to_migrate);
249 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35250
251 Mock::VerifyAndClearExpectations(manager());
[email protected]71229fa82011-12-10 01:00:54252 EXPECT_CALL(*manager(), Configure(HasModelTypes(difference),
[email protected]b2a3c142011-05-05 03:29:55253 sync_api::CONFIGURE_REASON_MIGRATION));
[email protected]400f521a2011-12-13 01:50:23254 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35255 SendConfigureDone(DataTypeManager::OK, preferred_types());
256
[email protected]1a425fc2011-09-01 23:11:59257 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35258}
259
[email protected]1a425fc2011-09-01 23:11:59260// Test that spurious OnConfigureDone events don't confuse the
261// migrator while it's waiting for disabled types to have been purged
262// from the sync db.
[email protected]b486b462012-02-11 00:11:42263TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
[email protected]400f521a2011-12-13 01:50:23264 syncable::ModelTypeSet to_migrate, difference;
[email protected]71229fa82011-12-10 01:00:54265 to_migrate.Put(syncable::PREFERENCES);
266 to_migrate.Put(syncable::AUTOFILL);
267 difference.Put(syncable::BOOKMARKS);
[email protected]dc556252011-04-20 01:59:35268
269 EXPECT_CALL(*manager(), state())
270 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59271 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
272 .Times(2);
[email protected]dc556252011-04-20 01:59:35273
[email protected]1a425fc2011-09-01 23:11:59274 migrator()->MigrateTypes(to_migrate);
275 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
276
277 SendConfigureDone(DataTypeManager::OK, difference);
278 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35279
[email protected]400f521a2011-12-13 01:50:23280 syncable::ModelTypeSet prefs;
[email protected]71229fa82011-12-10 01:00:54281 prefs.Put(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59282 SetUnsyncedTypes(prefs);
283 SendConfigureDone(DataTypeManager::OK, difference);
284 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35285
[email protected]1a425fc2011-09-01 23:11:59286 SetUnsyncedTypes(to_migrate);
287 SendConfigureDone(DataTypeManager::OK, difference);
288 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]dc556252011-04-20 01:59:35289}
290
[email protected]b486b462012-02-11 00:11:42291TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) {
[email protected]400f521a2011-12-13 01:50:23292 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54293 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35294
295 EXPECT_CALL(*manager(), state())
296 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]1a425fc2011-09-01 23:11:59297 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
298 .Times(2);
299 migrator()->MigrateTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35300
301 RemovePreferredType(syncable::PREFERENCES);
[email protected]1a425fc2011-09-01 23:11:59302 SetUnsyncedTypes(to_migrate);
[email protected]dc556252011-04-20 01:59:35303 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59304 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
[email protected]400f521a2011-12-13 01:50:23305 SetUnsyncedTypes(syncable::ModelTypeSet());
[email protected]dc556252011-04-20 01:59:35306 SendConfigureDone(DataTypeManager::OK, preferred_types());
[email protected]1a425fc2011-09-01 23:11:59307 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35308}
309
[email protected]b486b462012-02-11 00:11:42310TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
[email protected]400f521a2011-12-13 01:50:23311 syncable::ModelTypeSet to_migrate;
[email protected]71229fa82011-12-10 01:00:54312 to_migrate.Put(syncable::PREFERENCES);
[email protected]dc556252011-04-20 01:59:35313
314 EXPECT_CALL(*manager(), state())
315 .WillOnce(Return(DataTypeManager::CONFIGURED));
[email protected]b2a3c142011-05-05 03:29:55316 EXPECT_CALL(*manager(), Configure(_, sync_api::CONFIGURE_REASON_MIGRATION))
317 .Times(1);
[email protected]1a425fc2011-09-01 23:11:59318 migrator()->MigrateTypes(to_migrate);
[email protected]400f521a2011-12-13 01:50:23319 SetUnsyncedTypes(syncable::ModelTypeSet());
320 SendConfigureDone(DataTypeManager::ABORTED, syncable::ModelTypeSet());
[email protected]1a425fc2011-09-01 23:11:59321 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
[email protected]dc556252011-04-20 01:59:35322}
323
324}; // namespace browser_sync