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

Side by Side Diff: chrome/browser/sync/test/live_sync/migration_errors_test.cc

Issue 7841007: Rename browser/sync/test/live_sync directory to browser/sync/test/integration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: "" Created 9 years, 3 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
(Empty)
1 // Copyright (c) 2011 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.
4
5 // TODO(akalin): Rename this file to migration_test.cc.
6
7 #include "chrome/browser/prefs/scoped_user_pref_update.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/sync/profile_sync_service_harness.h"
10 #include "chrome/browser/sync/test/live_sync/bookmarks_helper.h"
11 #include "chrome/browser/sync/test/live_sync/live_sync_test.h"
12 #include "chrome/browser/sync/test/live_sync/preferences_helper.h"
13 #include "chrome/browser/translate/translate_prefs.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/ui_test_utils.h"
16
17 using bookmarks_helper::AddURL;
18 using bookmarks_helper::IndexedURL;
19 using bookmarks_helper::IndexedURLTitle;
20
21 using preferences_helper::BooleanPrefMatches;
22 using preferences_helper::ChangeBooleanPref;
23
24 namespace {
25
26 // Utility functions to make a model type set out of a small number of
27 // model types.
28
29 syncable::ModelTypeSet MakeSet(syncable::ModelType type) {
30 syncable::ModelTypeSet model_types;
31 model_types.insert(type);
32 return model_types;
33 }
34
35 syncable::ModelTypeSet MakeSet(syncable::ModelType type1,
36 syncable::ModelType type2) {
37 syncable::ModelTypeSet model_types;
38 model_types.insert(type1);
39 model_types.insert(type2);
40 return model_types;
41 }
42
43 // An ordered list of model types sets to migrate. Used by
44 // RunMigrationTest().
45 typedef std::deque<syncable::ModelTypeSet> MigrationList;
46
47 // Utility functions to make a MigrationList out of a small number of
48 // model types / model type sets.
49
50 MigrationList MakeList(const syncable::ModelTypeSet& model_types) {
51 return MigrationList(1, model_types);
52 }
53
54 MigrationList MakeList(const syncable::ModelTypeSet& model_types1,
55 const syncable::ModelTypeSet& model_types2) {
56 MigrationList migration_list;
57 migration_list.push_back(model_types1);
58 migration_list.push_back(model_types2);
59 return migration_list;
60 }
61
62 MigrationList MakeList(syncable::ModelType type) {
63 return MakeList(MakeSet(type));
64 }
65
66 MigrationList MakeList(syncable::ModelType type1,
67 syncable::ModelType type2) {
68 return MakeList(MakeSet(type1), MakeSet(type2));
69 }
70
71 class MigrationTest : public LiveSyncTest {
72 public:
73 explicit MigrationTest(TestType test_type) : LiveSyncTest(test_type) {}
74 virtual ~MigrationTest() {}
75
76 // TODO(akalin): Add more MODIFY_(data type) trigger methods, as
77 // well as a poll-based trigger method.
78 enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION };
79
80 syncable::ModelTypeSet GetPreferredDataTypes() {
81 syncable::ModelTypeSet preferred_data_types;
82 GetClient(0)->service()->GetPreferredDataTypes(&preferred_data_types);
83 // Make sure all clients have the same preferred data types.
84 for (int i = 1; i < num_clients(); ++i) {
85 syncable::ModelTypeSet other_preferred_data_types;
86 GetClient(i)->service()->GetPreferredDataTypes(
87 &other_preferred_data_types);
88 EXPECT_EQ(preferred_data_types, other_preferred_data_types);
89 }
90 return preferred_data_types;
91 }
92
93 // Returns a MigrationList with every enabled data type in its own
94 // set.
95 MigrationList GetPreferredDataTypesList() {
96 MigrationList migration_list;
97 const syncable::ModelTypeSet& preferred_data_types =
98 GetPreferredDataTypes();
99 for (syncable::ModelTypeSet::const_iterator it =
100 preferred_data_types.begin();
101 it != preferred_data_types.end(); ++it) {
102 migration_list.push_back(MakeSet(*it));
103 }
104 return migration_list;
105 }
106
107 // Trigger a migration for the given types with the given method.
108 void TriggerMigration(const syncable::ModelTypeSet& model_types,
109 TriggerMethod trigger_method) {
110 switch (trigger_method) {
111 case MODIFY_PREF:
112 // Unlike MODIFY_BOOKMARK, MODIFY_PREF doesn't cause a
113 // notification to happen (since model association on a
114 // boolean pref clobbers the local value), so it doesn't work
115 // for anything but single-client tests.
116 ASSERT_EQ(1, num_clients());
117 ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
118 ChangeBooleanPref(0, prefs::kShowHomeButton);
119 break;
120 case MODIFY_BOOKMARK:
121 ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))));
122 break;
123 case TRIGGER_NOTIFICATION:
124 TriggerNotification(model_types);
125 break;
126 default:
127 ADD_FAILURE();
128 }
129 }
130
131 // Block until all clients have completed migration for the given
132 // types.
133 void AwaitMigration(const syncable::ModelTypeSet& migrate_types) {
134 for (int i = 0; i < num_clients(); ++i) {
135 ASSERT_TRUE(GetClient(i)->AwaitMigration(migrate_types));
136 }
137 }
138
139 bool ShouldRunMigrationTest() const {
140 if (!ServerSupportsNotificationControl() ||
141 !ServerSupportsErrorTriggering()) {
142 LOG(WARNING) << "Test skipped in this server environment.";
143 return false;
144 }
145 return true;
146 }
147
148 // Makes sure migration works with the given migration list and
149 // trigger method.
150 void RunMigrationTest(const MigrationList& migration_list,
151 TriggerMethod trigger_method) {
152 ASSERT_TRUE(ShouldRunMigrationTest());
153
154 // If we have only one client, turn off notifications to avoid the
155 // possibility of spurious sync cycles.
156 bool do_test_without_notifications =
157 (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1);
158
159 if (do_test_without_notifications) {
160 DisableNotifications();
161 }
162
163 // Phase 1: Trigger the migrations on the server.
164 for (MigrationList::const_iterator it = migration_list.begin();
165 it != migration_list.end(); ++it) {
166 TriggerMigrationDoneError(*it);
167 }
168
169 // Phase 2: Trigger each migration individually and wait for it to
170 // complete. (Multiple migrations may be handled by each
171 // migration cycle, but there's no guarantee of that, so we have
172 // to trigger each migration individually.)
173 for (MigrationList::const_iterator it = migration_list.begin();
174 it != migration_list.end(); ++it) {
175 TriggerMigration(*it, trigger_method);
176 AwaitMigration(*it);
177 }
178
179 // Phase 3: Wait for all clients to catch up.
180 AwaitQuiescence();
181
182 // Re-enable notifications if we disabled it.
183 if (do_test_without_notifications) {
184 EnableNotifications();
185 }
186 }
187
188 private:
189 DISALLOW_COPY_AND_ASSIGN(MigrationTest);
190 };
191
192 class MigrationSingleClientTest : public MigrationTest {
193 public:
194 MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT) {}
195 virtual ~MigrationSingleClientTest() {}
196
197 void RunSingleClientMigrationTest(const MigrationList& migration_list,
198 TriggerMethod trigger_method) {
199 if (!ShouldRunMigrationTest()) {
200 return;
201 }
202 ASSERT_TRUE(SetupSync());
203 RunMigrationTest(migration_list, trigger_method);
204 }
205
206 private:
207 DISALLOW_COPY_AND_ASSIGN(MigrationSingleClientTest);
208 };
209
210 // The simplest possible migration tests -- a single data type.
211
212 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyPref) {
213 RunSingleClientMigrationTest(MakeList(syncable::PREFERENCES), MODIFY_PREF);
214 }
215
216 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyBookmark) {
217 RunSingleClientMigrationTest(MakeList(syncable::PREFERENCES),
218 MODIFY_BOOKMARK);
219 }
220
221 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
222 PrefsOnlyTriggerNotification) {
223 RunSingleClientMigrationTest(MakeList(syncable::PREFERENCES),
224 TRIGGER_NOTIFICATION);
225 }
226
227 // Nigori is handled specially, so we test that separately.
228
229 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, NigoriOnly) {
230 RunSingleClientMigrationTest(MakeList(syncable::PREFERENCES),
231 TRIGGER_NOTIFICATION);
232 }
233
234 // A little more complicated -- two data types.
235
236 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
237 BookmarksPrefsIndividually) {
238 RunSingleClientMigrationTest(
239 MakeList(syncable::BOOKMARKS, syncable::PREFERENCES),
240 MODIFY_PREF);
241 }
242
243 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, BookmarksPrefsBoth) {
244 RunSingleClientMigrationTest(
245 MakeList(MakeSet(syncable::BOOKMARKS, syncable::PREFERENCES)),
246 MODIFY_BOOKMARK);
247 }
248
249 // Two data types with one being nigori.
250
251 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriIndividiaully) {
252 RunSingleClientMigrationTest(
253 MakeList(syncable::PREFERENCES, syncable::NIGORI),
254 TRIGGER_NOTIFICATION);
255 }
256
257 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriBoth) {
258 RunSingleClientMigrationTest(
259 MakeList(MakeSet(syncable::PREFERENCES, syncable::NIGORI)),
260 MODIFY_PREF);
261 }
262
263 // The whole shebang -- all data types.
264
265 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesIndividually) {
266 ASSERT_TRUE(SetupClients());
267 RunSingleClientMigrationTest(GetPreferredDataTypesList(), MODIFY_BOOKMARK);
268 }
269
270 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
271 AllTypesIndividuallyTriggerNotification) {
272 ASSERT_TRUE(SetupClients());
273 RunSingleClientMigrationTest(GetPreferredDataTypesList(),
274 TRIGGER_NOTIFICATION);
275 }
276
277 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesAtOnce) {
278 ASSERT_TRUE(SetupClients());
279 RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
280 MODIFY_PREF);
281 }
282
283 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
284 AllTypesAtOnceTriggerNotification) {
285 ASSERT_TRUE(SetupClients());
286 RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
287 TRIGGER_NOTIFICATION);
288 }
289
290 // All data types plus nigori.
291
292 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
293 AllTypesWithNigoriIndividually) {
294 ASSERT_TRUE(SetupClients());
295 MigrationList migration_list = GetPreferredDataTypesList();
296 migration_list.push_front(MakeSet(syncable::NIGORI));
297 RunSingleClientMigrationTest(migration_list, MODIFY_BOOKMARK);
298 }
299
300 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesWithNigoriAtOnce) {
301 ASSERT_TRUE(SetupClients());
302 syncable::ModelTypeSet all_types = GetPreferredDataTypes();
303 all_types.insert(syncable::NIGORI);
304 RunSingleClientMigrationTest(MakeList(all_types), MODIFY_PREF);
305 }
306
307 class MigrationTwoClientTest : public MigrationTest {
308 public:
309 MigrationTwoClientTest() : MigrationTest(TWO_CLIENT) {}
310 virtual ~MigrationTwoClientTest() {}
311
312 // Helper function that verifies that preferences sync still works.
313 void VerifyPrefSync() {
314 ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
315 ChangeBooleanPref(0, prefs::kShowHomeButton);
316 ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
317 ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
318 }
319
320 void RunTwoClientMigrationTest(const MigrationList& migration_list,
321 TriggerMethod trigger_method) {
322 if (!ShouldRunMigrationTest()) {
323 return;
324 }
325 ASSERT_TRUE(SetupSync());
326
327 // Make sure pref sync works before running the migration test.
328 VerifyPrefSync();
329
330 RunMigrationTest(migration_list, trigger_method);
331
332 // Make sure pref sync still works after running the migration
333 // test.
334 VerifyPrefSync();
335 }
336
337 private:
338 DISALLOW_COPY_AND_ASSIGN(MigrationTwoClientTest);
339 };
340
341 // Easiest possible test of migration errors: triggers a server
342 // migration on one datatype, then modifies some other datatype.
343 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
344 MigratePrefsThenModifyBookmark) {
345 RunTwoClientMigrationTest(MakeList(syncable::PREFERENCES),
346 MODIFY_BOOKMARK);
347 }
348
349 // Triggers a server migration on two datatypes, then makes a local
350 // modification to one of them.
351 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
352 MigratePrefsAndBookmarksThenModifyBookmark) {
353 RunTwoClientMigrationTest(
354 MakeList(syncable::PREFERENCES, syncable::BOOKMARKS),
355 MODIFY_BOOKMARK);
356 }
357
358 // Migrate every datatype in sequence; the catch being that the server
359 // will only tell the client about the migrations one at a time.
360 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigrationHellWithoutNigori) {
361 ASSERT_TRUE(SetupClients());
362 MigrationList migration_list = GetPreferredDataTypesList();
363 // Let the first nudge be a datatype that's neither prefs nor
364 // bookmarks.
365 migration_list.push_front(MakeSet(syncable::THEMES));
366 RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
367 }
368
369 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigrationHellWithNigori) {
370 ASSERT_TRUE(SetupClients());
371 MigrationList migration_list = GetPreferredDataTypesList();
372 // Let the first nudge be a datatype that's neither prefs nor
373 // bookmarks.
374 migration_list.push_front(MakeSet(syncable::THEMES));
375 // Pop off one so that we don't migrate all data types; the syncer
376 // freaks out if we do that (see http://crbug.com/94882).
377 ASSERT_GE(migration_list.size(), 2u);
378 ASSERT_NE(migration_list.back(), MakeSet(syncable::NIGORI));
379 migration_list.back() = MakeSet(syncable::NIGORI);
380 RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
381 }
382
383 class MigrationReconfigureTest : public MigrationTwoClientTest {
384 public:
385 MigrationReconfigureTest() {}
386
387 virtual void SetUpCommandLine(CommandLine* cl) OVERRIDE {
388 AddTestSwitches(cl);
389 // Do not add optional datatypes.
390 }
391
392 virtual ~MigrationReconfigureTest() {}
393
394 private:
395 DISALLOW_COPY_AND_ASSIGN(MigrationReconfigureTest);
396 };
397
398 IN_PROC_BROWSER_TEST_F(MigrationReconfigureTest, SetSyncTabs) {
399 if (!ServerSupportsErrorTriggering()) {
400 LOG(WARNING) << "Test skipped in this server environment.";
401 return;
402 }
403
404 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
405 ASSERT_FALSE(GetClient(0)->IsTypeRegistered(syncable::SESSIONS));
406 ASSERT_FALSE(GetClient(0)->IsTypePreferred(syncable::SESSIONS));
407
408 // Phase 1: Before migrating anything, create & sync a preference.
409 VerifyPrefSync();
410
411 // Phase 2: Trigger setting the sync_tabs field.
412 TriggerSetSyncTabs();
413
414 // Phase 3: Modify a bookmark and wait for it to sync.
415 ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))) != NULL);
416 ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
417
418 // Phase 4: Verify that preferences can still be synchronized.
419 VerifyPrefSync();
420
421 // Phase 5: Verify that sessions are registered and enabled.
422 ASSERT_TRUE(GetClient(0)->IsTypeRegistered(syncable::SESSIONS));
423 ASSERT_TRUE(GetClient(0)->IsTypePreferred(syncable::SESSIONS));
424 }
425
426 IN_PROC_BROWSER_TEST_F(MigrationReconfigureTest, SetSyncTabsAndMigrate) {
427 if (!ServerSupportsErrorTriggering()) {
428 LOG(WARNING) << "Test skipped in this server environment.";
429 return;
430 }
431
432 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
433 ASSERT_FALSE(GetClient(0)->IsTypeRegistered(syncable::SESSIONS));
434 ASSERT_FALSE(GetClient(0)->IsTypePreferred(syncable::SESSIONS));
435
436 // Phase 1: Before migrating anything, create & sync a preference.
437 VerifyPrefSync();
438
439 // Phase 2: Trigger setting the sync_tabs field.
440 TriggerSetSyncTabs();
441
442 // Phase 3: Trigger a preference migration on the server.
443 RunMigrationTest(MakeList(syncable::PREFERENCES), MODIFY_BOOKMARK);
444
445 // Phase 5: Verify that preferences can still be synchronized.
446 VerifyPrefSync();
447
448 // Phase 6: Verify that sessions are registered and enabled.
449 ASSERT_TRUE(GetClient(0)->IsTypeRegistered(syncable::SESSIONS));
450 ASSERT_TRUE(GetClient(0)->IsTypePreferred(syncable::SESSIONS));
451 }
452
453 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698