| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/compiler_specific.h" | 5 #include "base/compiler_specific.h" |
| 6 #include "base/memory/scoped_vector.h" | 6 #include "base/memory/scoped_vector.h" |
| 7 #include "base/prefs/scoped_user_pref_update.h" | 7 #include "base/prefs/scoped_user_pref_update.h" |
| 8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
| 9 #include "chrome/browser/sync/backend_migrator.h" | |
| 10 #include "chrome/browser/sync/profile_sync_service.h" | 9 #include "chrome/browser/sync/profile_sync_service.h" |
| 11 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" | 10 #include "chrome/browser/sync/test/integration/bookmarks_helper.h" |
| 11 #include "chrome/browser/sync/test/integration/migration_waiter.h" |
| 12 #include "chrome/browser/sync/test/integration/migration_watcher.h" |
| 12 #include "chrome/browser/sync/test/integration/preferences_helper.h" | 13 #include "chrome/browser/sync/test/integration/preferences_helper.h" |
| 13 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" | 14 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" |
| 14 #include "chrome/browser/sync/test/integration/single_client_status_change_check
er.h" | |
| 15 #include "chrome/browser/sync/test/integration/sync_test.h" | 15 #include "chrome/browser/sync/test/integration/sync_test.h" |
| 16 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
| 17 #include "chrome/test/base/ui_test_utils.h" | 17 #include "chrome/test/base/ui_test_utils.h" |
| 18 #include "components/translate/core/browser/translate_prefs.h" | 18 #include "components/translate/core/browser/translate_prefs.h" |
| 19 | 19 |
| 20 using bookmarks_helper::AddURL; | 20 using bookmarks_helper::AddURL; |
| 21 using bookmarks_helper::IndexedURL; | 21 using bookmarks_helper::IndexedURL; |
| 22 using bookmarks_helper::IndexedURLTitle; | 22 using bookmarks_helper::IndexedURLTitle; |
| 23 | 23 |
| 24 using preferences_helper::BooleanPrefMatches; | 24 using preferences_helper::BooleanPrefMatches; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 MigrationList MakeList(syncer::ModelType type) { | 60 MigrationList MakeList(syncer::ModelType type) { |
| 61 return MakeList(MakeSet(type)); | 61 return MakeList(MakeSet(type)); |
| 62 } | 62 } |
| 63 | 63 |
| 64 MigrationList MakeList(syncer::ModelType type1, | 64 MigrationList MakeList(syncer::ModelType type1, |
| 65 syncer::ModelType type2) { | 65 syncer::ModelType type2) { |
| 66 return MakeList(MakeSet(type1), MakeSet(type2)); | 66 return MakeList(MakeSet(type1), MakeSet(type2)); |
| 67 } | 67 } |
| 68 | 68 |
| 69 // Helper class that checks if the sync backend has successfully completed | |
| 70 // migration for a set of data types. | |
| 71 class MigrationChecker : public SingleClientStatusChangeChecker, | |
| 72 public browser_sync::MigrationObserver { | |
| 73 public: | |
| 74 explicit MigrationChecker(ProfileSyncServiceHarness* harness) | |
| 75 : SingleClientStatusChangeChecker(harness->service()), | |
| 76 harness_(harness) { | |
| 77 DCHECK(harness_); | |
| 78 browser_sync::BackendMigrator* migrator = | |
| 79 harness_->service()->GetBackendMigratorForTest(); | |
| 80 // PSS must have a migrator after sync is setup and initial data type | |
| 81 // configuration is complete. | |
| 82 DCHECK(migrator); | |
| 83 migrator->AddMigrationObserver(this); | |
| 84 } | |
| 85 | |
| 86 virtual ~MigrationChecker() {} | |
| 87 | |
| 88 // Returns true when sync reports that there is no pending migration, and | |
| 89 // migration is complete for all data types in |expected_types_|. | |
| 90 virtual bool IsExitConditionSatisfied() OVERRIDE { | |
| 91 DCHECK(!expected_types_.Empty()); | |
| 92 bool all_expected_types_migrated = migrated_types_.HasAll(expected_types_); | |
| 93 DVLOG(1) << harness_->profile_debug_name() << ": Migrated types " | |
| 94 << syncer::ModelTypeSetToString(migrated_types_) | |
| 95 << (all_expected_types_migrated ? " contains " : | |
| 96 " does not contain ") | |
| 97 << syncer::ModelTypeSetToString(expected_types_); | |
| 98 return all_expected_types_migrated && | |
| 99 !HasPendingBackendMigration(); | |
| 100 } | |
| 101 | |
| 102 virtual std::string GetDebugMessage() const OVERRIDE { | |
| 103 return "Waiting to migrate (" + ModelTypeSetToString(expected_types_) + ")"; | |
| 104 } | |
| 105 | |
| 106 bool HasPendingBackendMigration() const { | |
| 107 browser_sync::BackendMigrator* migrator = | |
| 108 harness_->service()->GetBackendMigratorForTest(); | |
| 109 return migrator && migrator->state() != browser_sync::BackendMigrator::IDLE; | |
| 110 } | |
| 111 | |
| 112 void set_expected_types(syncer::ModelTypeSet expected_types) { | |
| 113 expected_types_ = expected_types; | |
| 114 } | |
| 115 | |
| 116 syncer::ModelTypeSet migrated_types() const { | |
| 117 return migrated_types_; | |
| 118 } | |
| 119 | |
| 120 virtual void OnMigrationStateChange() OVERRIDE { | |
| 121 if (HasPendingBackendMigration()) { | |
| 122 // A new bunch of data types are in the process of being migrated. Merge | |
| 123 // them into |pending_types_|. | |
| 124 pending_types_.PutAll( | |
| 125 harness_->service()->GetBackendMigratorForTest()-> | |
| 126 GetPendingMigrationTypesForTest()); | |
| 127 DVLOG(1) << harness_->profile_debug_name() | |
| 128 << ": new pending migration types " | |
| 129 << syncer::ModelTypeSetToString(pending_types_); | |
| 130 } else { | |
| 131 // Migration just finished for a bunch of data types. Merge them into | |
| 132 // |migrated_types_|. | |
| 133 migrated_types_.PutAll(pending_types_); | |
| 134 pending_types_.Clear(); | |
| 135 DVLOG(1) << harness_->profile_debug_name() << ": new migrated types " | |
| 136 << syncer::ModelTypeSetToString(migrated_types_); | |
| 137 } | |
| 138 | |
| 139 // Manually trigger a check of the exit condition. | |
| 140 if (!expected_types_.Empty()) | |
| 141 OnStateChanged(); | |
| 142 } | |
| 143 | |
| 144 private: | |
| 145 // The sync client for which migration is being verified. | |
| 146 ProfileSyncServiceHarness* harness_; | |
| 147 | |
| 148 // The set of data types that are expected to eventually undergo migration. | |
| 149 syncer::ModelTypeSet expected_types_; | |
| 150 | |
| 151 // The set of data types currently undergoing migration. | |
| 152 syncer::ModelTypeSet pending_types_; | |
| 153 | |
| 154 // The set of data types for which migration is complete. Accumulated by | |
| 155 // successive calls to OnMigrationStateChanged. | |
| 156 syncer::ModelTypeSet migrated_types_; | |
| 157 | |
| 158 DISALLOW_COPY_AND_ASSIGN(MigrationChecker); | |
| 159 }; | |
| 160 | 69 |
| 161 class MigrationTest : public SyncTest { | 70 class MigrationTest : public SyncTest { |
| 162 public: | 71 public: |
| 163 explicit MigrationTest(TestType test_type) : SyncTest(test_type) {} | 72 explicit MigrationTest(TestType test_type) : SyncTest(test_type) {} |
| 164 virtual ~MigrationTest() {} | 73 virtual ~MigrationTest() {} |
| 165 | 74 |
| 166 enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION }; | 75 enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION }; |
| 167 | 76 |
| 168 // Set up sync for all profiles and initialize all MigrationCheckers. This | 77 // Set up sync for all profiles and initialize all MigrationWatchers. This |
| 169 // helps ensure that all migration events are captured, even if they were to | 78 // helps ensure that all migration events are captured, even if they were to |
| 170 // occur before a test calls AwaitMigration for a specific profile. | 79 // occur before a test calls AwaitMigration for a specific profile. |
| 171 virtual bool SetupSync() OVERRIDE { | 80 virtual bool SetupSync() OVERRIDE { |
| 172 if (!SyncTest::SetupSync()) | 81 if (!SyncTest::SetupSync()) |
| 173 return false; | 82 return false; |
| 174 | 83 |
| 175 for (int i = 0; i < num_clients(); ++i) { | 84 for (int i = 0; i < num_clients(); ++i) { |
| 176 MigrationChecker* checker = new MigrationChecker(GetClient(i)); | 85 MigrationWatcher* watcher = new MigrationWatcher(GetClient(i)); |
| 177 migration_checkers_.push_back(checker); | 86 migration_watchers_.push_back(watcher); |
| 178 } | 87 } |
| 179 return true; | 88 return true; |
| 180 } | 89 } |
| 181 | 90 |
| 182 syncer::ModelTypeSet GetPreferredDataTypes() { | 91 syncer::ModelTypeSet GetPreferredDataTypes() { |
| 183 // ProfileSyncService must already have been created before we can call | 92 // ProfileSyncService must already have been created before we can call |
| 184 // GetPreferredDataTypes(). | 93 // GetPreferredDataTypes(). |
| 185 DCHECK(GetSyncService((0))); | 94 DCHECK(GetSyncService((0))); |
| 186 syncer::ModelTypeSet preferred_data_types = | 95 syncer::ModelTypeSet preferred_data_types = |
| 187 GetSyncService((0))->GetPreferredDataTypes(); | 96 GetSyncService((0))->GetPreferredDataTypes(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 break; | 143 break; |
| 235 default: | 144 default: |
| 236 ADD_FAILURE(); | 145 ADD_FAILURE(); |
| 237 } | 146 } |
| 238 } | 147 } |
| 239 | 148 |
| 240 // Block until all clients have completed migration for the given | 149 // Block until all clients have completed migration for the given |
| 241 // types. | 150 // types. |
| 242 void AwaitMigration(syncer::ModelTypeSet migrate_types) { | 151 void AwaitMigration(syncer::ModelTypeSet migrate_types) { |
| 243 for (int i = 0; i < num_clients(); ++i) { | 152 for (int i = 0; i < num_clients(); ++i) { |
| 244 MigrationChecker* checker = migration_checkers_[i]; | 153 MigrationWaiter waiter(migration_watchers_[i], migrate_types); |
| 245 checker->set_expected_types(migrate_types); | 154 waiter.Wait(); |
| 246 checker->Wait(); | 155 ASSERT_FALSE(waiter.TimedOut()); |
| 247 ASSERT_FALSE(checker->TimedOut()); | |
| 248 } | 156 } |
| 249 } | 157 } |
| 250 | 158 |
| 251 // Makes sure migration works with the given migration list and | 159 // Makes sure migration works with the given migration list and |
| 252 // trigger method. | 160 // trigger method. |
| 253 void RunMigrationTest(const MigrationList& migration_list, | 161 void RunMigrationTest(const MigrationList& migration_list, |
| 254 TriggerMethod trigger_method) { | 162 TriggerMethod trigger_method) { |
| 255 // If we have only one client, turn off notifications to avoid the | 163 // If we have only one client, turn off notifications to avoid the |
| 256 // possibility of spurious sync cycles. | 164 // possibility of spurious sync cycles. |
| 257 bool do_test_without_notifications = | 165 bool do_test_without_notifications = |
| 258 (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1); | 166 (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1); |
| 259 | 167 |
| 260 if (do_test_without_notifications) { | 168 if (do_test_without_notifications) { |
| 261 DisableNotifications(); | 169 DisableNotifications(); |
| 262 } | 170 } |
| 263 | 171 |
| 264 // Make sure migration hasn't been triggered prematurely. | 172 // Make sure migration hasn't been triggered prematurely. |
| 265 for (int i = 0; i < num_clients(); ++i) { | 173 for (int i = 0; i < num_clients(); ++i) { |
| 266 ASSERT_TRUE(migration_checkers_[i]->migrated_types().Empty()); | 174 ASSERT_TRUE(migration_watchers_[i]->GetMigratedTypes().Empty()); |
| 267 } | 175 } |
| 268 | 176 |
| 269 // Phase 1: Trigger the migrations on the server. | 177 // Phase 1: Trigger the migrations on the server. |
| 270 for (MigrationList::const_iterator it = migration_list.begin(); | 178 for (MigrationList::const_iterator it = migration_list.begin(); |
| 271 it != migration_list.end(); ++it) { | 179 it != migration_list.end(); ++it) { |
| 272 TriggerMigrationDoneError(*it); | 180 TriggerMigrationDoneError(*it); |
| 273 } | 181 } |
| 274 | 182 |
| 275 // Phase 2: Trigger each migration individually and wait for it to | 183 // Phase 2: Trigger each migration individually and wait for it to |
| 276 // complete. (Multiple migrations may be handled by each | 184 // complete. (Multiple migrations may be handled by each |
| (...skipping 16 matching lines...) Expand all Loading... |
| 293 if (!do_test_without_notifications) { | 201 if (!do_test_without_notifications) { |
| 294 AwaitQuiescence(); | 202 AwaitQuiescence(); |
| 295 } | 203 } |
| 296 | 204 |
| 297 // TODO(rlarocque): It should be possible to re-enable notifications | 205 // TODO(rlarocque): It should be possible to re-enable notifications |
| 298 // here, but doing so makes some windows tests flaky. | 206 // here, but doing so makes some windows tests flaky. |
| 299 } | 207 } |
| 300 | 208 |
| 301 private: | 209 private: |
| 302 // Used to keep track of the migration progress for each sync client. | 210 // Used to keep track of the migration progress for each sync client. |
| 303 ScopedVector<MigrationChecker> migration_checkers_; | 211 ScopedVector<MigrationWatcher> migration_watchers_; |
| 304 | 212 |
| 305 DISALLOW_COPY_AND_ASSIGN(MigrationTest); | 213 DISALLOW_COPY_AND_ASSIGN(MigrationTest); |
| 306 }; | 214 }; |
| 307 | 215 |
| 308 class MigrationSingleClientTest : public MigrationTest { | 216 class MigrationSingleClientTest : public MigrationTest { |
| 309 public: | 217 public: |
| 310 MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT_LEGACY) {} | 218 MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT_LEGACY) {} |
| 311 virtual ~MigrationSingleClientTest() {} | 219 virtual ~MigrationSingleClientTest() {} |
| 312 | 220 |
| 313 void RunSingleClientMigrationTest(const MigrationList& migration_list, | 221 void RunSingleClientMigrationTest(const MigrationList& migration_list, |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 // Do not add optional datatypes. | 426 // Do not add optional datatypes. |
| 519 } | 427 } |
| 520 | 428 |
| 521 virtual ~MigrationReconfigureTest() {} | 429 virtual ~MigrationReconfigureTest() {} |
| 522 | 430 |
| 523 private: | 431 private: |
| 524 DISALLOW_COPY_AND_ASSIGN(MigrationReconfigureTest); | 432 DISALLOW_COPY_AND_ASSIGN(MigrationReconfigureTest); |
| 525 }; | 433 }; |
| 526 | 434 |
| 527 } // namespace | 435 } // namespace |
| OLD | NEW |