Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / test / integration / migration_test.cc
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
3 // found in the LICENSE file.
4
5 #include "base/compiler_specific.h"
6 #include "base/memory/scoped_vector.h"
7 #include "base/prefs/scoped_user_pref_update.h"
8 #include "chrome/browser/profiles/profile.h"
9 #include "chrome/browser/sync/profile_sync_service.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"
13 #include "chrome/browser/sync/test/integration/preferences_helper.h"
14 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
15 #include "chrome/browser/sync/test/integration/sync_test.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/translate/core/browser/translate_prefs.h"
18
19 using bookmarks_helper::AddURL;
20 using bookmarks_helper::IndexedURL;
21 using bookmarks_helper::IndexedURLTitle;
22
23 using preferences_helper::BooleanPrefMatches;
24 using preferences_helper::ChangeBooleanPref;
25
26 namespace {
27
28 // Utility functions to make a model type set out of a small number of
29 // model types.
30
31 syncer::ModelTypeSet MakeSet(syncer::ModelType type) {
32   return syncer::ModelTypeSet(type);
33 }
34
35 syncer::ModelTypeSet MakeSet(syncer::ModelType type1,
36                              syncer::ModelType type2) {
37   return syncer::ModelTypeSet(type1, type2);
38 }
39
40 // An ordered list of model types sets to migrate.  Used by
41 // RunMigrationTest().
42 typedef std::deque<syncer::ModelTypeSet> MigrationList;
43
44 // Utility functions to make a MigrationList out of a small number of
45 // model types / model type sets.
46
47 MigrationList MakeList(syncer::ModelTypeSet model_types) {
48   return MigrationList(1, model_types);
49 }
50
51 MigrationList MakeList(syncer::ModelTypeSet model_types1,
52                        syncer::ModelTypeSet model_types2) {
53   MigrationList migration_list;
54   migration_list.push_back(model_types1);
55   migration_list.push_back(model_types2);
56   return migration_list;
57 }
58
59 MigrationList MakeList(syncer::ModelType type) {
60   return MakeList(MakeSet(type));
61 }
62
63 MigrationList MakeList(syncer::ModelType type1,
64                        syncer::ModelType type2) {
65   return MakeList(MakeSet(type1), MakeSet(type2));
66 }
67
68
69 class MigrationTest : public SyncTest  {
70  public:
71   explicit MigrationTest(TestType test_type) : SyncTest(test_type) {}
72   ~MigrationTest() override {}
73
74   enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION };
75
76   // Set up sync for all profiles and initialize all MigrationWatchers. This
77   // helps ensure that all migration events are captured, even if they were to
78   // occur before a test calls AwaitMigration for a specific profile.
79   bool SetupSync() override {
80     if (!SyncTest::SetupSync())
81       return false;
82
83     for (int i = 0; i < num_clients(); ++i) {
84       MigrationWatcher* watcher = new MigrationWatcher(GetClient(i));
85       migration_watchers_.push_back(watcher);
86     }
87     return true;
88   }
89
90   syncer::ModelTypeSet GetPreferredDataTypes() {
91     // ProfileSyncService must already have been created before we can call
92     // GetPreferredDataTypes().
93     DCHECK(GetSyncService((0)));
94     syncer::ModelTypeSet preferred_data_types =
95         GetSyncService((0))->GetPreferredDataTypes();
96     preferred_data_types.RemoveAll(syncer::ProxyTypes());
97
98     // The managed user settings will be "unready" during this test, so we
99     // should not request that they be migrated.
100     preferred_data_types.Remove(syncer::SUPERVISED_USER_SETTINGS);
101
102     // Make sure all clients have the same preferred data types.
103     for (int i = 1; i < num_clients(); ++i) {
104       const syncer::ModelTypeSet other_preferred_data_types =
105           GetSyncService((i))->GetPreferredDataTypes();
106       EXPECT_TRUE(preferred_data_types.Equals(other_preferred_data_types));
107     }
108     return preferred_data_types;
109   }
110
111   // Returns a MigrationList with every enabled data type in its own
112   // set.
113   MigrationList GetPreferredDataTypesList() {
114     MigrationList migration_list;
115     const syncer::ModelTypeSet preferred_data_types =
116         GetPreferredDataTypes();
117     for (syncer::ModelTypeSet::Iterator it =
118              preferred_data_types.First(); it.Good(); it.Inc()) {
119       migration_list.push_back(MakeSet(it.Get()));
120     }
121     return migration_list;
122   }
123
124   // Trigger a migration for the given types with the given method.
125   void TriggerMigration(syncer::ModelTypeSet model_types,
126                         TriggerMethod trigger_method) {
127     switch (trigger_method) {
128       case MODIFY_PREF:
129         // Unlike MODIFY_BOOKMARK, MODIFY_PREF doesn't cause a
130         // notification to happen (since model association on a
131         // boolean pref clobbers the local value), so it doesn't work
132         // for anything but single-client tests.
133         ASSERT_EQ(1, num_clients());
134         ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
135         ChangeBooleanPref(0, prefs::kShowHomeButton);
136         break;
137       case MODIFY_BOOKMARK:
138         ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))));
139         break;
140       case TRIGGER_NOTIFICATION:
141         TriggerNotification(model_types);
142         break;
143       default:
144         ADD_FAILURE();
145     }
146   }
147
148   // Block until all clients have completed migration for the given
149   // types.
150   void AwaitMigration(syncer::ModelTypeSet migrate_types) {
151     for (int i = 0; i < num_clients(); ++i) {
152       MigrationWaiter waiter(migrate_types, migration_watchers_[i]);
153       waiter.Wait();
154       ASSERT_FALSE(waiter.TimedOut());
155     }
156   }
157
158   // Makes sure migration works with the given migration list and
159   // trigger method.
160   void RunMigrationTest(const MigrationList& migration_list,
161                         TriggerMethod trigger_method) {
162     // If we have only one client, turn off notifications to avoid the
163     // possibility of spurious sync cycles.
164     bool do_test_without_notifications =
165         (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1);
166
167     if (do_test_without_notifications) {
168       DisableNotifications();
169     }
170
171     // Make sure migration hasn't been triggered prematurely.
172     for (int i = 0; i < num_clients(); ++i) {
173       ASSERT_TRUE(migration_watchers_[i]->GetMigratedTypes().Empty());
174     }
175
176     // Phase 1: Trigger the migrations on the server.
177     for (MigrationList::const_iterator it = migration_list.begin();
178          it != migration_list.end(); ++it) {
179       TriggerMigrationDoneError(*it);
180     }
181
182     // Phase 2: Trigger each migration individually and wait for it to
183     // complete.  (Multiple migrations may be handled by each
184     // migration cycle, but there's no guarantee of that, so we have
185     // to trigger each migration individually.)
186     for (MigrationList::const_iterator it = migration_list.begin();
187          it != migration_list.end(); ++it) {
188       TriggerMigration(*it, trigger_method);
189       AwaitMigration(*it);
190     }
191
192     // Phase 3: Wait for all clients to catch up.
193     //
194     // AwaitQuiescence() will not succeed when notifications are disabled.  We
195     // can safely avoid calling it because we know that, in the single client
196     // case, there is no one else to wait for.
197     //
198     // TODO(rlarocque, 97780): Remove the if condition when the test harness
199     // supports calling AwaitQuiescence() when notifications are disabled.
200     if (!do_test_without_notifications) {
201       AwaitQuiescence();
202     }
203
204     // TODO(rlarocque): It should be possible to re-enable notifications
205     // here, but doing so makes some windows tests flaky.
206   }
207
208  private:
209   // Used to keep track of the migration progress for each sync client.
210   ScopedVector<MigrationWatcher> migration_watchers_;
211
212   DISALLOW_COPY_AND_ASSIGN(MigrationTest);
213 };
214
215 class MigrationSingleClientTest : public MigrationTest {
216  public:
217   MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT_LEGACY) {}
218   ~MigrationSingleClientTest() override {}
219
220   void RunSingleClientMigrationTest(const MigrationList& migration_list,
221                                     TriggerMethod trigger_method) {
222     ASSERT_TRUE(SetupSync());
223     RunMigrationTest(migration_list, trigger_method);
224   }
225
226  private:
227   DISALLOW_COPY_AND_ASSIGN(MigrationSingleClientTest);
228 };
229
230 // The simplest possible migration tests -- a single data type.
231
232 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyPref) {
233   RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES), MODIFY_PREF);
234 }
235
236 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyBookmark) {
237   RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
238                                MODIFY_BOOKMARK);
239 }
240
241 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
242                        PrefsOnlyTriggerNotification) {
243   RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
244                                TRIGGER_NOTIFICATION);
245 }
246
247 // Nigori is handled specially, so we test that separately.
248
249 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, NigoriOnly) {
250   RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
251                                TRIGGER_NOTIFICATION);
252 }
253
254 // A little more complicated -- two data types.
255
256 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, BookmarksPrefsIndividually) {
257   RunSingleClientMigrationTest(
258       MakeList(syncer::BOOKMARKS, syncer::PREFERENCES),
259       MODIFY_PREF);
260 }
261
262 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, BookmarksPrefsBoth) {
263   RunSingleClientMigrationTest(
264       MakeList(MakeSet(syncer::BOOKMARKS, syncer::PREFERENCES)),
265       MODIFY_BOOKMARK);
266 }
267
268 // Two data types with one being nigori.
269
270 // See crbug.com/124480.
271 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
272                        DISABLED_PrefsNigoriIndividiaully) {
273   RunSingleClientMigrationTest(
274       MakeList(syncer::PREFERENCES, syncer::NIGORI),
275       TRIGGER_NOTIFICATION);
276 }
277
278 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriBoth) {
279   RunSingleClientMigrationTest(
280       MakeList(MakeSet(syncer::PREFERENCES, syncer::NIGORI)),
281       MODIFY_PREF);
282 }
283
284 // The whole shebang -- all data types.
285 #if defined(OS_WIN) || defined(OS_MACOSX)
286 // http://crbug.com/403778
287 #define MAYBE_AllTypesIndividually DISABLED_AllTypesIndividually
288 #else
289 #define MAYBE_AllTypesIndividually AllTypesIndividually
290 #endif
291 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, MAYBE_AllTypesIndividually) {
292   ASSERT_TRUE(SetupClients());
293   RunSingleClientMigrationTest(GetPreferredDataTypesList(), MODIFY_BOOKMARK);
294 }
295
296 #if defined(OS_WIN) || defined(OS_MACOSX)
297 // http://crbug.com/403778
298 #define MAYBE_AllTypesIndividuallyTriggerNotification DISABLED_AllTypesIndividuallyTriggerNotification
299 #else
300 #define MAYBE_AllTypesIndividuallyTriggerNotification AllTypesIndividuallyTriggerNotification
301 #endif
302 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
303                        MAYBE_AllTypesIndividuallyTriggerNotification) {
304   ASSERT_TRUE(SetupClients());
305   RunSingleClientMigrationTest(GetPreferredDataTypesList(),
306                                TRIGGER_NOTIFICATION);
307 }
308
309 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesAtOnce) {
310   ASSERT_TRUE(SetupClients());
311   RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
312                                MODIFY_PREF);
313 }
314
315 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
316                        AllTypesAtOnceTriggerNotification) {
317   ASSERT_TRUE(SetupClients());
318   RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
319                                TRIGGER_NOTIFICATION);
320 }
321
322 // All data types plus nigori.
323
324 // See crbug.com/124480.
325 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
326                        DISABLED_AllTypesWithNigoriIndividually) {
327   ASSERT_TRUE(SetupClients());
328   MigrationList migration_list = GetPreferredDataTypesList();
329   migration_list.push_front(MakeSet(syncer::NIGORI));
330   RunSingleClientMigrationTest(migration_list, MODIFY_BOOKMARK);
331 }
332
333 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesWithNigoriAtOnce) {
334   ASSERT_TRUE(SetupClients());
335   syncer::ModelTypeSet all_types = GetPreferredDataTypes();
336   all_types.Put(syncer::NIGORI);
337   RunSingleClientMigrationTest(MakeList(all_types), MODIFY_PREF);
338 }
339
340 class MigrationTwoClientTest : public MigrationTest {
341  public:
342   MigrationTwoClientTest() : MigrationTest(TWO_CLIENT_LEGACY) {}
343   ~MigrationTwoClientTest() override {}
344
345   // Helper function that verifies that preferences sync still works.
346   void VerifyPrefSync() {
347     ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
348     ChangeBooleanPref(0, prefs::kShowHomeButton);
349     ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
350     ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
351   }
352
353   void RunTwoClientMigrationTest(const MigrationList& migration_list,
354                                  TriggerMethod trigger_method) {
355     ASSERT_TRUE(SetupSync());
356
357     // Make sure pref sync works before running the migration test.
358     VerifyPrefSync();
359
360     RunMigrationTest(migration_list, trigger_method);
361
362     // Make sure pref sync still works after running the migration
363     // test.
364     VerifyPrefSync();
365   }
366
367  private:
368   DISALLOW_COPY_AND_ASSIGN(MigrationTwoClientTest);
369 };
370
371 // Easiest possible test of migration errors: triggers a server
372 // migration on one datatype, then modifies some other datatype.
373 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigratePrefsThenModifyBookmark) {
374   RunTwoClientMigrationTest(MakeList(syncer::PREFERENCES),
375                             MODIFY_BOOKMARK);
376 }
377
378 // Triggers a server migration on two datatypes, then makes a local
379 // modification to one of them.
380 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
381                        MigratePrefsAndBookmarksThenModifyBookmark) {
382   RunTwoClientMigrationTest(
383       MakeList(syncer::PREFERENCES, syncer::BOOKMARKS),
384       MODIFY_BOOKMARK);
385 }
386
387 // Migrate every datatype in sequence; the catch being that the server
388 // will only tell the client about the migrations one at a time.
389 // TODO(rsimha): This test takes longer than 60 seconds, and will cause tree
390 // redness due to sharding.
391 // Re-enable this test after syncer::kInitialBackoffShortRetrySeconds is reduced
392 // to zero.
393 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
394                        DISABLED_MigrationHellWithoutNigori) {
395   ASSERT_TRUE(SetupClients());
396   MigrationList migration_list = GetPreferredDataTypesList();
397   // Let the first nudge be a datatype that's neither prefs nor
398   // bookmarks.
399   migration_list.push_front(MakeSet(syncer::THEMES));
400   RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
401 }
402
403 // See crbug.com/124480.
404 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
405                        DISABLED_MigrationHellWithNigori) {
406   ASSERT_TRUE(SetupClients());
407   MigrationList migration_list = GetPreferredDataTypesList();
408   // Let the first nudge be a datatype that's neither prefs nor
409   // bookmarks.
410   migration_list.push_front(MakeSet(syncer::THEMES));
411   // Pop off one so that we don't migrate all data types; the syncer
412   // freaks out if we do that (see http://crbug.com/94882).
413   ASSERT_GE(migration_list.size(), 2u);
414   ASSERT_FALSE(migration_list.back().Equals(MakeSet(syncer::NIGORI)));
415   migration_list.back() = MakeSet(syncer::NIGORI);
416   RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
417 }
418
419 class MigrationReconfigureTest : public MigrationTwoClientTest {
420  public:
421   MigrationReconfigureTest() {}
422
423   void SetUpCommandLine(base::CommandLine* cl) override {
424     AddTestSwitches(cl);
425     // Do not add optional datatypes.
426   }
427
428   ~MigrationReconfigureTest() override {}
429
430  private:
431   DISALLOW_COPY_AND_ASSIGN(MigrationReconfigureTest);
432 };
433
434 }  // namespace