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(migrate_types, migration_watchers_[i]); |
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 |