59ef9c852b13776d43c62ef9d62818a40996ee88
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / test / integration / single_client_backup_rollback_test.cc
1 // Copyright 2014 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/command_line.h"
6 #include "base/file_util.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/run_loop.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sync/profile_sync_service.h"
12 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
13 #include "chrome/browser/sync/test/integration/preferences_helper.h"
14 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
15 #include "chrome/browser/sync/test/integration/sync_test.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/bookmarks/browser/bookmark_model.h"
19 #include "sync/internal_api/public/util/sync_db_util.h"
20 #include "sync/test/fake_server/fake_server_verifier.h"
21 #include "sync/util/time.h"
22
23 using bookmarks_helper::AddFolder;
24 using bookmarks_helper::AddURL;
25 using bookmarks_helper::GetOtherNode;
26 using bookmarks_helper::ModelMatchesVerifier;
27 using bookmarks_helper::Move;
28 using bookmarks_helper::Remove;
29 using sync_integration_test_util::AwaitCommitActivityCompletion;
30
31 namespace {
32 const char kUrl1[] = "http://www.google.com";
33 const char kUrl2[] = "http://map.google.com";
34 const char kUrl3[] = "http://plus.google.com";
35 }  // anonymous namespace
36
37 class SingleClientBackupRollbackTest : public SyncTest {
38  public:
39   SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
40   virtual ~SingleClientBackupRollbackTest() {}
41
42   void DisableBackup() {
43     CommandLine::ForCurrentProcess()->AppendSwitch(
44           switches::kSyncDisableBackup);
45   }
46
47   void DisableRollback() {
48     CommandLine::ForCurrentProcess()->AppendSwitch(
49           switches::kSyncDisableRollback);
50   }
51
52   base::Time GetBackupDbLastModified() {
53     base::RunLoop run_loop;
54
55     base::Time backup_time;
56     syncer::CheckSyncDbLastModifiedTime(
57         GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
58         base::MessageLoopProxy::current(),
59         base::Bind(&SingleClientBackupRollbackTest::CheckDbCallback,
60                    base::Unretained(this), &backup_time));
61     base::MessageLoopProxy::current()->PostTask(
62         FROM_HERE, run_loop.QuitClosure());
63     run_loop.Run();
64     return backup_time;
65   }
66
67  private:
68   void CheckDbCallback(base::Time* time_out, base::Time time_in) {
69     *time_out = syncer::ProtoTimeToTime(syncer::TimeToProtoTime(time_in));
70   }
71
72   DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
73 };
74
75 class SyncBackendStoppedChecker {
76  public:
77   explicit SyncBackendStoppedChecker(ProfileSyncService* service,
78                                      base::TimeDelta timeout)
79       : pss_(service),
80         timeout_(timeout) {}
81
82   bool Wait() {
83     expiration_ = base::TimeTicks::Now() + timeout_;
84     base::MessageLoop::current()->PostDelayedTask(
85         FROM_HERE,
86         base::Bind(&SyncBackendStoppedChecker::PeriodicCheck,
87                    base::Unretained(this)),
88         base::TimeDelta::FromSeconds(1));
89     base::MessageLoop::current()->Run();
90     return ProfileSyncService::IDLE == pss_->backend_mode();
91   }
92
93  private:
94   void PeriodicCheck() {
95     if (ProfileSyncService::IDLE == pss_->backend_mode() ||
96         base::TimeTicks::Now() > expiration_) {
97       base::MessageLoop::current()->Quit();
98     } else {
99       base::MessageLoop::current()->PostDelayedTask(
100           FROM_HERE,
101           base::Bind(&SyncBackendStoppedChecker::PeriodicCheck,
102                      base::Unretained(this)),
103           base::TimeDelta::FromSeconds(1));
104     }
105   }
106
107   ProfileSyncService* pss_;
108   base::TimeDelta timeout_;
109   base::TimeTicks expiration_;
110 };
111
112 #if defined(ENABLE_PRE_SYNC_BACKUP)
113 #define MAYBE_TestBackup TestBackup
114 #else
115 #define MAYBE_TestBackup DISABLED_TestBackup
116 #endif
117 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
118                        MAYBE_TestBackup) {
119   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
120
121   // Setup sync, wait for its completion, and make sure changes were synced.
122   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
123   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
124   ASSERT_TRUE(ModelMatchesVerifier(0));
125
126   // Verify backup DB is created and backup time is set on device info.
127   base::Time backup_time = GetBackupDbLastModified();
128   ASSERT_FALSE(backup_time.is_null());
129   ASSERT_EQ(backup_time, GetSyncService(0)->GetDeviceBackupTimeForTesting());
130 }
131
132 #if defined(ENABLE_PRE_SYNC_BACKUP)
133 #define MAYBE_TestBackupDisabled TestBackupDisabled
134 #else
135 #define MAYBE_TestBackupDisabled DISABLED_TestBackupDisabled
136 #endif
137 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
138                        MAYBE_TestBackupDisabled) {
139   DisableBackup();
140
141   // Setup sync, wait for its completion, and make sure changes were synced.
142   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
143   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
144   ASSERT_TRUE(ModelMatchesVerifier(0));
145
146   // Verify backup DB is not created and backup time is not set on device info.
147   ASSERT_FALSE(base::PathExists(
148       GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
149   ASSERT_TRUE(GetSyncService(0)->GetDeviceBackupTimeForTesting().is_null());
150 }
151
152 #if defined(ENABLE_PRE_SYNC_BACKUP)
153 #define MAYBE_TestRollback TestRollback
154 #else
155 #define MAYBE_TestRollback DISABLED_TestRollback
156 #endif
157 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
158                        MAYBE_TestRollback) {
159   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
160
161   // Starting state:
162   // other_node
163   //    -> top
164   //      -> tier1_a
165   //        -> http://mail.google.com  "tier1_a_url0"
166   //      -> tier1_b
167   //        -> http://www.nhl.com "tier1_b_url0"
168   const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, "top");
169   const BookmarkNode* tier1_a = AddFolder(0, top, 0, "tier1_a");
170   const BookmarkNode* tier1_b = AddFolder(0, top, 1, "tier1_b");
171   ASSERT_TRUE(AddURL(0, tier1_a, 0, "tier1_a_url0",
172                      GURL("http://mail.google.com")));
173   ASSERT_TRUE(AddURL(0, tier1_b, 0, "tier1_b_url0",
174                      GURL("http://www.nhl.com")));
175
176   // Setup sync, wait for its completion, and make sure changes were synced.
177   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
178   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
179   ASSERT_TRUE(ModelMatchesVerifier(0));
180
181   // Made bookmark changes while sync is on.
182   Move(0, tier1_a->GetChild(0), tier1_b, 1);
183   Remove(0, tier1_b, 0);
184   ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c"));
185   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
186   ASSERT_TRUE(ModelMatchesVerifier(0));
187
188   // Let server to return rollback command on next sync request.
189   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
190
191   // Make another change to trigger downloading of rollback command.
192   Remove(0, tier1_b, 0);
193
194   // Wait for rollback to finish and sync backend is completely shut down.
195   SyncBackendStoppedChecker checker(GetSyncService(0),
196                                     base::TimeDelta::FromSeconds(5));
197   ASSERT_TRUE(checker.Wait());
198
199   // Verify bookmarks are restored.
200   ASSERT_EQ(1, tier1_a->child_count());
201   const BookmarkNode* url1 = tier1_a->GetChild(0);
202   ASSERT_EQ(GURL("http://mail.google.com"), url1->url());
203
204   ASSERT_EQ(1, tier1_b->child_count());
205   const BookmarkNode* url2 = tier1_b->GetChild(0);
206   ASSERT_EQ(GURL("http://www.nhl.com"), url2->url());
207
208   // Backup DB should be deleted after rollback is done.
209   ASSERT_FALSE(base::PathExists(
210       GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
211 }
212
213 #if defined(ENABLE_PRE_SYNC_BACKUP)
214 #define MAYBE_TestRollbackDisabled TestRollbackDisabled
215 #else
216 #define MAYBE_TestRollbackDisabled DISABLED_TestRollbackDisabled
217 #endif
218 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
219                        MAYBE_TestRollbackDisabled) {
220   DisableRollback();
221
222   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
223
224   // Starting state:
225   // other_node
226   //    -> http://mail.google.com  "url0"
227   //    -> http://www.nhl.com "url1"
228   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
229                      GURL("http://mail.google.com")));
230   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
231                      GURL("http://www.nhl.com")));
232
233   // Setup sync, wait for its completion, and make sure changes were synced.
234   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
235   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
236   ASSERT_TRUE(ModelMatchesVerifier(0));
237
238   // Made bookmark changes while sync is on.
239   Remove(0, GetOtherNode(0), 1);
240   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
241                      GURL("http://www.yahoo.com")));
242   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
243   ASSERT_TRUE(ModelMatchesVerifier(0));
244
245   // Let server to return rollback command on next sync request.
246   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
247
248   // Make another change to trigger downloading of rollback command.
249   Remove(0, GetOtherNode(0), 0);
250
251   // Wait for rollback to finish and sync backend is completely shut down.
252   SyncBackendStoppedChecker checker(GetSyncService(0),
253                                     base::TimeDelta::FromSeconds(5));
254   ASSERT_TRUE(checker.Wait());
255
256   // With rollback disabled, bookmarks in backup DB should not be restored.
257   // Only bookmark added during sync is present.
258   ASSERT_EQ(1, GetOtherNode(0)->child_count());
259   ASSERT_EQ(GURL("http://www.yahoo.com"),
260             GetOtherNode(0)->GetChild(0)->url());
261
262   // Backup DB should be deleted after.
263   ASSERT_FALSE(base::PathExists(
264       GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
265 }
266
267 #if defined(ENABLE_PRE_SYNC_BACKUP)
268 #define MAYBE_TestSyncDisabled TestSyncDisabled
269 #else
270 #define MAYBE_TestSyncDisabled DISABLED_TestSyncDisabled
271 #endif
272 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
273                        MAYBE_TestSyncDisabled) {
274   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
275
276   // Starting state:
277   // other_node
278   //    -> http://mail.google.com  "url0"
279   //    -> http://www.nhl.com "url1"
280   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
281                      GURL("http://mail.google.com")));
282   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
283                      GURL("http://www.nhl.com")));
284
285   // Setup sync, wait for its completion, and make sure changes were synced.
286   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
287   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
288   ASSERT_TRUE(ModelMatchesVerifier(0));
289
290   // Made bookmark changes while sync is on.
291   Remove(0, GetOtherNode(0), 1);
292   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
293                      GURL("http://www.yahoo.com")));
294   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
295   ASSERT_TRUE(ModelMatchesVerifier(0));
296
297   // Let server to return birthday error on next sync request.
298   GetFakeServer()->TriggerError(sync_pb::SyncEnums::NOT_MY_BIRTHDAY);
299
300   // Make another change to trigger downloading of rollback command.
301   Remove(0, GetOtherNode(0), 0);
302
303   // Wait for rollback to finish and sync backend is completely shut down.
304   SyncBackendStoppedChecker checker(GetSyncService(0),
305                                     base::TimeDelta::FromSeconds(5));
306   ASSERT_TRUE(checker.Wait());
307
308   // Shouldn't restore bookmarks with sign-out only.
309   ASSERT_EQ(1, GetOtherNode(0)->child_count());
310   ASSERT_EQ(GURL("http://www.yahoo.com"),
311             GetOtherNode(0)->GetChild(0)->url());
312
313   // Backup DB should be deleted after.
314   ASSERT_FALSE(base::PathExists(
315       GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
316 }
317
318 #if defined(ENABLE_PRE_SYNC_BACKUP)
319 #define MAYBE_RollbackNoBackup RollbackNoBackup
320 #else
321 #define MAYBE_RollbackNoBackup DISABLED_RollbackNoBackup
322 #endif
323 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
324                        MAYBE_RollbackNoBackup) {
325   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
326
327   // Starting state:
328   // other_node
329   //    -> http://mail.google.com  "url0"
330   //    -> http://www.nhl.com "url1"
331   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
332                      GURL("http://mail.google.com")));
333
334   // Setup sync, wait for its completion, and make sure changes were synced.
335   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
336   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
337   ASSERT_TRUE(ModelMatchesVerifier(0));
338
339   ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
340                      GURL("http://www.nhl.com")));
341
342   // Delete backup DB.
343   base::DeleteFile(
344       GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
345       true);
346
347   // Let server to return rollback command on next sync request.
348   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
349
350   // Make another change to trigger downloading of rollback command.
351   Remove(0, GetOtherNode(0), 0);
352
353   // Wait for backend to completely shut down.
354   SyncBackendStoppedChecker checker(GetSyncService(0),
355                                     base::TimeDelta::FromSeconds(15));
356   ASSERT_TRUE(checker.Wait());
357
358   // Without backup DB, bookmarks remain at the state when sync stops.
359   ASSERT_EQ(1, GetOtherNode(0)->child_count());
360   ASSERT_EQ(GURL("http://www.nhl.com"),
361             GetOtherNode(0)->GetChild(0)->url());
362 }
363
364 #if defined(ENABLE_PRE_SYNC_BACKUP)
365 #define MAYBE_DontChangeBookmarkOrdering DontChangeBookmarkOrdering
366 #else
367 #define MAYBE_DontChangeBookmarkOrdering DISABLED_DontChangeBookmarkOrdering
368 #endif
369 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
370                        MAYBE_DontChangeBookmarkOrdering) {
371   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
372
373   const BookmarkNode* sub_folder = AddFolder(0, GetOtherNode(0), 0, "test");
374   ASSERT_TRUE(AddURL(0, sub_folder, 0, "", GURL(kUrl1)));
375   ASSERT_TRUE(AddURL(0, sub_folder, 1, "", GURL(kUrl2)));
376   ASSERT_TRUE(AddURL(0, sub_folder, 2, "", GURL(kUrl3)));
377
378   // Setup sync, wait for its completion, and make sure changes were synced.
379   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
380   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
381   ASSERT_TRUE(ModelMatchesVerifier(0));
382
383   // Made bookmark changes while sync is on.
384   Remove(0, sub_folder, 0);
385   Remove(0, sub_folder, 0);
386   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
387   ASSERT_TRUE(ModelMatchesVerifier(0));
388
389   // Let server to return rollback command on next sync request.
390   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
391
392   // Make another change to trigger downloading of rollback command.
393   Remove(0, sub_folder, 0);
394
395   // Wait for rollback to finish and sync backend is completely shut down.
396   SyncBackendStoppedChecker checker(GetSyncService(0),
397                                     base::TimeDelta::FromSeconds(5));
398   ASSERT_TRUE(checker.Wait());
399
400   // Verify bookmarks are unchanged.
401   ASSERT_EQ(3, sub_folder->child_count());
402   ASSERT_EQ(GURL(kUrl1), sub_folder->GetChild(0)->url());
403   ASSERT_EQ(GURL(kUrl2), sub_folder->GetChild(1)->url());
404   ASSERT_EQ(GURL(kUrl3), sub_folder->GetChild(2)->url());
405 }