Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: chrome/browser/sync/test/integration/migration_test.cc

Issue 490643004: sync: Refactor migration integration tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698