Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / sync / backend_migrator_unittest.cc
bloba5c29f807cde9ab1fc11a6e0b2bfc6cd67623a43
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/run_loop.h"
9 #include "base/tracked_objects.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/sync/profile_sync_service_mock.h"
12 #include "components/sync_driver/data_type_manager_mock.h"
13 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "sync/internal_api/public/base/model_type_test_util.h"
15 #include "sync/internal_api/public/test/test_user_share.h"
16 #include "sync/internal_api/public/write_transaction.h"
17 #include "sync/protocol/sync.pb.h"
18 #include "sync/syncable/directory.h" // TODO(tim): Remove. Bug 131130.
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::_;
23 using ::testing::Eq;
24 using ::testing::Mock;
25 using ::testing::NiceMock;
26 using ::testing::Return;
27 using sync_driver::DataTypeManager;
28 using sync_driver::DataTypeManagerMock;
30 namespace browser_sync {
32 using syncer::sessions::SyncSessionSnapshot;
34 class SyncBackendMigratorTest : public testing::Test {
35 public:
36 SyncBackendMigratorTest() : service_(&profile_) { }
37 virtual ~SyncBackendMigratorTest() { }
39 virtual void SetUp() {
40 test_user_share_.SetUp();
41 Mock::VerifyAndClear(manager());
42 Mock::VerifyAndClear(&service_);
43 preferred_types_.Put(syncer::BOOKMARKS);
44 preferred_types_.Put(syncer::PREFERENCES);
45 preferred_types_.Put(syncer::AUTOFILL);
47 ON_CALL(service_, GetPreferredDataTypes()).
48 WillByDefault(Return(preferred_types_));
50 migrator_.reset(
51 new BackendMigrator(
52 "Profile0", test_user_share_.user_share(), service(), manager(),
53 base::Closure()));
54 SetUnsyncedTypes(syncer::ModelTypeSet());
57 virtual void TearDown() {
58 migrator_.reset();
59 test_user_share_.TearDown();
62 // Marks all types in |unsynced_types| as unsynced and all other
63 // types as synced.
64 void SetUnsyncedTypes(syncer::ModelTypeSet unsynced_types) {
65 syncer::WriteTransaction trans(FROM_HERE,
66 test_user_share_.user_share());
67 for (int i = syncer::FIRST_REAL_MODEL_TYPE;
68 i < syncer::MODEL_TYPE_COUNT; ++i) {
69 syncer::ModelType type = syncer::ModelTypeFromInt(i);
70 sync_pb::DataTypeProgressMarker progress_marker;
71 if (!unsynced_types.Has(type)) {
72 progress_marker.set_token("dummy");
74 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
78 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
79 syncer::ModelTypeSet requested_types) {
80 if (status == DataTypeManager::OK) {
81 DataTypeManager::ConfigureResult result(status, requested_types);
82 migrator_->OnConfigureDone(result);
83 } else {
84 DataTypeManager::ConfigureResult result(
85 status,
86 requested_types);
87 migrator_->OnConfigureDone(result);
89 base::RunLoop run_loop;
90 run_loop.RunUntilIdle();
93 ProfileSyncService* service() { return &service_; }
94 DataTypeManagerMock* manager() { return &manager_; }
95 syncer::ModelTypeSet preferred_types() { return preferred_types_; }
96 BackendMigrator* migrator() { return migrator_.get(); }
97 void RemovePreferredType(syncer::ModelType type) {
98 preferred_types_.Remove(type);
99 Mock::VerifyAndClear(&service_);
100 ON_CALL(service_, GetPreferredDataTypes()).
101 WillByDefault(Return(preferred_types_));
104 private:
105 content::TestBrowserThreadBundle thread_bundle_;
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