MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / chrome / browser / sync / backend_migrator_unittest.cc
blob7736e8708e555eb0bdc7189f81ff2c48dc689e50
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/profile_sync_service_mock.h"
11 #include "components/sync_driver/data_type_manager_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;
25 using sync_driver::DataTypeManager;
26 using sync_driver::DataTypeManagerMock;
28 namespace browser_sync {
30 using syncer::sessions::SyncSessionSnapshot;
32 class SyncBackendMigratorTest : public testing::Test {
33 public:
34 SyncBackendMigratorTest() : service_(&profile_) { }
35 virtual ~SyncBackendMigratorTest() { }
37 virtual void SetUp() {
38 test_user_share_.SetUp();
39 Mock::VerifyAndClear(manager());
40 Mock::VerifyAndClear(&service_);
41 preferred_types_.Put(syncer::BOOKMARKS);
42 preferred_types_.Put(syncer::PREFERENCES);
43 preferred_types_.Put(syncer::AUTOFILL);
45 ON_CALL(service_, GetPreferredDataTypes()).
46 WillByDefault(Return(preferred_types_));
48 migrator_.reset(
49 new BackendMigrator(
50 "Profile0", test_user_share_.user_share(), service(), manager(),
51 base::Closure()));
52 SetUnsyncedTypes(syncer::ModelTypeSet());
55 virtual void TearDown() {
56 migrator_.reset();
57 test_user_share_.TearDown();
60 // Marks all types in |unsynced_types| as unsynced and all other
61 // types as synced.
62 void SetUnsyncedTypes(syncer::ModelTypeSet unsynced_types) {
63 syncer::WriteTransaction trans(FROM_HERE,
64 test_user_share_.user_share());
65 for (int i = syncer::FIRST_REAL_MODEL_TYPE;
66 i < syncer::MODEL_TYPE_COUNT; ++i) {
67 syncer::ModelType type = syncer::ModelTypeFromInt(i);
68 sync_pb::DataTypeProgressMarker progress_marker;
69 if (!unsynced_types.Has(type)) {
70 progress_marker.set_token("dummy");
72 trans.GetDirectory()->SetDownloadProgress(type, progress_marker);
76 void SendConfigureDone(DataTypeManager::ConfigureStatus status,
77 syncer::ModelTypeSet requested_types) {
78 if (status == DataTypeManager::OK) {
79 DataTypeManager::ConfigureResult result(status, requested_types);
80 migrator_->OnConfigureDone(result);
81 } else {
82 DataTypeManager::ConfigureResult result(
83 status,
84 requested_types);
85 migrator_->OnConfigureDone(result);
87 message_loop_.RunUntilIdle();
90 ProfileSyncService* service() { return &service_; }
91 DataTypeManagerMock* manager() { return &manager_; }
92 syncer::ModelTypeSet preferred_types() { return preferred_types_; }
93 BackendMigrator* migrator() { return migrator_.get(); }
94 void RemovePreferredType(syncer::ModelType type) {
95 preferred_types_.Remove(type);
96 Mock::VerifyAndClear(&service_);
97 ON_CALL(service_, GetPreferredDataTypes()).
98 WillByDefault(Return(preferred_types_));
101 private:
102 scoped_ptr<SyncSessionSnapshot> snap_;
103 base::MessageLoop message_loop_;
104 syncer::ModelTypeSet preferred_types_;
105 TestingProfile profile_;
106 NiceMock<ProfileSyncServiceMock> service_;
107 NiceMock<DataTypeManagerMock> manager_;
108 syncer::TestUserShare test_user_share_;
109 scoped_ptr<BackendMigrator> migrator_;
112 class MockMigrationObserver : public MigrationObserver {
113 public:
114 virtual ~MockMigrationObserver() {}
116 MOCK_METHOD0(OnMigrationStateChange, void());
119 // Test that in the normal case a migration does transition through each state
120 // and wind up back in IDLE.
121 TEST_F(SyncBackendMigratorTest, Sanity) {
122 MockMigrationObserver migration_observer;
123 migrator()->AddMigrationObserver(&migration_observer);
124 EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4);
126 syncer::ModelTypeSet to_migrate, difference;
127 to_migrate.Put(syncer::PREFERENCES);
128 difference.Put(syncer::AUTOFILL);
129 difference.Put(syncer::BOOKMARKS);
131 EXPECT_CALL(*manager(), state())
132 .WillOnce(Return(DataTypeManager::CONFIGURED));
133 EXPECT_CALL(
134 *manager(),
135 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
136 EXPECT_CALL(
137 *manager(),
138 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
140 migrator()->MigrateTypes(to_migrate);
141 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
143 SetUnsyncedTypes(to_migrate);
144 SendConfigureDone(DataTypeManager::OK, difference);
145 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
147 SetUnsyncedTypes(syncer::ModelTypeSet());
148 SendConfigureDone(DataTypeManager::OK, preferred_types());
149 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
151 migrator()->RemoveMigrationObserver(&migration_observer);
154 // Test that in the normal case with Nigori a migration transitions through
155 // each state and wind up back in IDLE.
156 TEST_F(SyncBackendMigratorTest, MigrateNigori) {
157 syncer::ModelTypeSet to_migrate, difference;
158 to_migrate.Put(syncer::NIGORI);
159 difference.Put(syncer::AUTOFILL);
160 difference.Put(syncer::BOOKMARKS);
162 EXPECT_CALL(*manager(), state())
163 .WillOnce(Return(DataTypeManager::CONFIGURED));
165 EXPECT_CALL(*manager(), PurgeForMigration(_,
166 syncer::CONFIGURE_REASON_MIGRATION));
168 migrator()->MigrateTypes(to_migrate);
169 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
171 SetUnsyncedTypes(to_migrate);
172 SendConfigureDone(DataTypeManager::OK, difference);
173 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
175 SetUnsyncedTypes(syncer::ModelTypeSet());
176 SendConfigureDone(DataTypeManager::OK, preferred_types());
177 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
181 // Test that the migrator waits for the data type manager to be idle before
182 // starting a migration.
183 TEST_F(SyncBackendMigratorTest, WaitToStart) {
184 syncer::ModelTypeSet to_migrate;
185 to_migrate.Put(syncer::PREFERENCES);
187 EXPECT_CALL(*manager(), state())
188 .WillOnce(Return(DataTypeManager::CONFIGURING));
189 EXPECT_CALL(*manager(), Configure(_, _)).Times(0);
190 migrator()->MigrateTypes(to_migrate);
191 EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state());
193 Mock::VerifyAndClearExpectations(manager());
194 EXPECT_CALL(*manager(), state())
195 .WillOnce(Return(DataTypeManager::CONFIGURED));
196 EXPECT_CALL(*manager(),
197 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION));
198 SetUnsyncedTypes(syncer::ModelTypeSet());
199 SendConfigureDone(DataTypeManager::OK, syncer::ModelTypeSet());
201 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
204 // Test that the migrator can cope with a migration request while a migration
205 // is in progress.
206 TEST_F(SyncBackendMigratorTest, RestartMigration) {
207 syncer::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks;
208 to_migrate1.Put(syncer::PREFERENCES);
209 to_migrate2.Put(syncer::AUTOFILL);
210 to_migrate_union.Put(syncer::PREFERENCES);
211 to_migrate_union.Put(syncer::AUTOFILL);
212 bookmarks.Put(syncer::BOOKMARKS);
214 EXPECT_CALL(*manager(), state())
215 .WillOnce(Return(DataTypeManager::CONFIGURED));
216 EXPECT_CALL(
217 *manager(),
218 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(2);
219 migrator()->MigrateTypes(to_migrate1);
221 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
222 migrator()->MigrateTypes(to_migrate2);
224 const syncer::ModelTypeSet difference1 =
225 Difference(preferred_types(), to_migrate1);
227 Mock::VerifyAndClearExpectations(manager());
228 EXPECT_CALL(
229 *manager(),
230 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
231 EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION))
232 .Times(1);
233 SetUnsyncedTypes(to_migrate1);
234 SendConfigureDone(DataTypeManager::OK, difference1);
235 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
237 SetUnsyncedTypes(to_migrate_union);
238 SendConfigureDone(DataTypeManager::OK, bookmarks);
239 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
242 // Test that an external invocation of Configure(...) during a migration results
243 // in a migration reattempt.
244 TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) {
245 syncer::ModelTypeSet to_migrate;
246 syncer::ModelTypeSet difference;
247 to_migrate.Put(syncer::PREFERENCES);
248 difference.Put(syncer::AUTOFILL);
249 difference.Put(syncer::BOOKMARKS);
251 EXPECT_CALL(*manager(), state())
252 .WillOnce(Return(DataTypeManager::CONFIGURED));
253 EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate),
254 syncer::CONFIGURE_REASON_MIGRATION));
255 migrator()->MigrateTypes(to_migrate);
256 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
258 Mock::VerifyAndClearExpectations(manager());
259 EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate),
260 syncer::CONFIGURE_REASON_MIGRATION));
261 SetUnsyncedTypes(syncer::ModelTypeSet());
262 SendConfigureDone(DataTypeManager::OK, preferred_types());
264 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
267 // Test that spurious OnConfigureDone events don't confuse the
268 // migrator while it's waiting for disabled types to have been purged
269 // from the sync db.
270 TEST_F(SyncBackendMigratorTest, WaitingForPurge) {
271 syncer::ModelTypeSet to_migrate, difference;
272 to_migrate.Put(syncer::PREFERENCES);
273 to_migrate.Put(syncer::AUTOFILL);
274 difference.Put(syncer::BOOKMARKS);
276 EXPECT_CALL(*manager(), state())
277 .WillOnce(Return(DataTypeManager::CONFIGURED));
278 EXPECT_CALL(
279 *manager(),
280 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
281 EXPECT_CALL(
282 *manager(),
283 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
285 migrator()->MigrateTypes(to_migrate);
286 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
288 SendConfigureDone(DataTypeManager::OK, difference);
289 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
291 syncer::ModelTypeSet prefs;
292 prefs.Put(syncer::PREFERENCES);
293 SetUnsyncedTypes(prefs);
294 SendConfigureDone(DataTypeManager::OK, difference);
295 EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state());
297 SetUnsyncedTypes(to_migrate);
298 SendConfigureDone(DataTypeManager::OK, difference);
299 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
302 TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) {
303 syncer::ModelTypeSet to_migrate;
304 to_migrate.Put(syncer::PREFERENCES);
306 EXPECT_CALL(*manager(), state())
307 .WillOnce(Return(DataTypeManager::CONFIGURED));
308 EXPECT_CALL(
309 *manager(),
310 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
311 EXPECT_CALL(
312 *manager(),
313 Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
314 migrator()->MigrateTypes(to_migrate);
316 RemovePreferredType(syncer::PREFERENCES);
317 SetUnsyncedTypes(to_migrate);
318 SendConfigureDone(DataTypeManager::OK, preferred_types());
319 EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state());
320 SetUnsyncedTypes(syncer::ModelTypeSet());
321 SendConfigureDone(DataTypeManager::OK, preferred_types());
322 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
325 TEST_F(SyncBackendMigratorTest, ConfigureFailure) {
326 syncer::ModelTypeSet to_migrate;
327 to_migrate.Put(syncer::PREFERENCES);
329 EXPECT_CALL(*manager(), state())
330 .WillOnce(Return(DataTypeManager::CONFIGURED));
331 EXPECT_CALL(
332 *manager(),
333 PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1);
334 migrator()->MigrateTypes(to_migrate);
335 SetUnsyncedTypes(syncer::ModelTypeSet());
336 SendConfigureDone(DataTypeManager::ABORTED, syncer::ModelTypeSet());
337 EXPECT_EQ(BackendMigrator::IDLE, migrator()->state());
340 }; // namespace browser_sync