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.
5 #include "base/command_line.h"
6 #include "base/files/file_util.h"
7 #include "base/location.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "chrome/browser/browsing_data/browsing_data_remover.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/sync/profile_sync_service.h"
16 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
17 #include "chrome/browser/sync/test/integration/preferences_helper.h"
18 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
19 #include "chrome/browser/sync/test/integration/sync_test.h"
20 #include "components/bookmarks/browser/bookmark_model.h"
21 #include "components/sync_driver/sync_driver_switches.h"
22 #include "sync/internal_api/public/util/sync_db_util.h"
23 #include "sync/test/fake_server/fake_server_verifier.h"
24 #include "sync/util/time.h"
26 using bookmarks::BookmarkNode
;
27 using bookmarks_helper::AddFolder
;
28 using bookmarks_helper::AddURL
;
29 using bookmarks_helper::GetOtherNode
;
30 using bookmarks_helper::ModelMatchesVerifier
;
31 using bookmarks_helper::Move
;
32 using bookmarks_helper::Remove
;
33 using sync_integration_test_util::AwaitCommitActivityCompletion
;
36 const char kUrl1
[] = "http://www.google.com";
37 const char kUrl2
[] = "http://map.google.com";
38 const char kUrl3
[] = "http://plus.google.com";
39 } // anonymous namespace
41 class SingleClientBackupRollbackTest
: public SyncTest
{
43 SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT
) {}
44 ~SingleClientBackupRollbackTest() override
{}
46 void DisableBackup() {
47 base::CommandLine::ForCurrentProcess()->AppendSwitch(
48 switches::kSyncDisableBackup
);
51 void DisableRollback() {
52 base::CommandLine::ForCurrentProcess()->AppendSwitch(
53 switches::kSyncDisableRollback
);
56 base::Time
GetBackupDbLastModified() {
57 base::RunLoop run_loop
;
59 base::Time backup_time
;
60 syncer::CheckSyncDbLastModifiedTime(
61 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
62 base::ThreadTaskRunnerHandle::Get(),
63 base::Bind(&SingleClientBackupRollbackTest::CheckDbCallback
,
64 base::Unretained(this), &backup_time
));
65 base::ThreadTaskRunnerHandle::Get()->PostTask(
66 FROM_HERE
, run_loop
.QuitClosure());
72 void CheckDbCallback(base::Time
* time_out
, base::Time time_in
) {
73 *time_out
= syncer::ProtoTimeToTime(syncer::TimeToProtoTime(time_in
));
76 DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest
);
79 // Waits until the ProfileSyncService's backend is in IDLE mode.
80 class SyncBackendStoppedChecker
: public sync_driver::SyncServiceObserver
{
82 explicit SyncBackendStoppedChecker(ProfileSyncService
* service
)
84 timeout_(TestTimeouts::action_max_timeout()),
87 void OnStateChanged() override
{
88 if (ProfileSyncService::IDLE
== pss_
->backend_mode()) {
95 pss_
->AddObserver(this);
96 if (ProfileSyncService::IDLE
== pss_
->backend_mode())
98 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
99 FROM_HERE
, run_loop_
.QuitClosure(), timeout_
);
101 pss_
->RemoveObserver(this);
107 ProfileSyncService
* const pss_
;
108 const base::TimeDelta timeout_
;
109 base::RunLoop run_loop_
;
113 // Waits until a rollback finishes.
114 class SyncRollbackChecker
: public sync_driver::SyncServiceObserver
,
115 public BrowsingDataRemover::Observer
{
117 explicit SyncRollbackChecker(ProfileSyncService
* service
)
119 timeout_(TestTimeouts::action_max_timeout()),
120 rollback_started_(false),
121 clear_done_(false) {}
123 // sync_driver::SyncServiceObserver implementation.
124 void OnStateChanged() override
{
125 if (ProfileSyncService::ROLLBACK
== pss_
->backend_mode()) {
126 rollback_started_
= true;
132 // BrowsingDataRemoverObserver::Observer implementation.
133 void OnBrowsingDataRemoverDone() override
{
135 if (rollback_started_
) {
141 pss_
->AddObserver(this);
142 pss_
->SetBrowsingDataRemoverObserverForTesting(this);
143 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
144 FROM_HERE
, run_loop_
.QuitClosure(), timeout_
);
146 pss_
->RemoveObserver(this);
147 return rollback_started_
&& clear_done_
;
150 ProfileSyncService
* const pss_
;
151 const base::TimeDelta timeout_
;
152 base::RunLoop run_loop_
;
153 bool rollback_started_
;
157 #if defined(ENABLE_PRE_SYNC_BACKUP)
158 #define MAYBE_TestBackup TestBackup
160 #define MAYBE_TestBackup DISABLED_TestBackup
162 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
164 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
166 // Setup sync, wait for its completion, and make sure changes were synced.
167 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
168 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
169 ASSERT_TRUE(ModelMatchesVerifier(0));
171 // Verify backup DB is created and backup time is set on device info.
172 base::Time backup_time
= GetBackupDbLastModified();
173 ASSERT_FALSE(backup_time
.is_null());
174 ASSERT_EQ(backup_time
, GetSyncService(0)->GetDeviceBackupTimeForTesting());
177 #if defined(ENABLE_PRE_SYNC_BACKUP)
178 #define MAYBE_TestBackupDisabled TestBackupDisabled
180 #define MAYBE_TestBackupDisabled DISABLED_TestBackupDisabled
182 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
183 MAYBE_TestBackupDisabled
) {
186 // Setup sync, wait for its completion, and make sure changes were synced.
187 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
188 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
189 ASSERT_TRUE(ModelMatchesVerifier(0));
191 // Verify backup DB is not created and backup time is not set on device info.
192 ASSERT_FALSE(base::PathExists(
193 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
194 ASSERT_TRUE(GetSyncService(0)->GetDeviceBackupTimeForTesting().is_null());
197 #if defined(ENABLE_PRE_SYNC_BACKUP)
198 #define MAYBE_TestRollback TestRollback
200 #define MAYBE_TestRollback DISABLED_TestRollback
202 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
203 MAYBE_TestRollback
) {
204 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
210 // -> http://mail.google.com "tier1_a_url0"
212 // -> http://www.nhl.com "tier1_b_url0"
213 const BookmarkNode
* top
= AddFolder(0, GetOtherNode(0), 0, "top");
214 const BookmarkNode
* tier1_a
= AddFolder(0, top
, 0, "tier1_a");
215 const BookmarkNode
* tier1_b
= AddFolder(0, top
, 1, "tier1_b");
216 ASSERT_TRUE(AddURL(0, tier1_a
, 0, "tier1_a_url0",
217 GURL("http://mail.google.com")));
218 ASSERT_TRUE(AddURL(0, tier1_b
, 0, "tier1_b_url0",
219 GURL("http://www.nhl.com")));
221 // Setup sync, wait for its completion, and make sure changes were synced.
222 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
223 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
224 ASSERT_TRUE(ModelMatchesVerifier(0));
226 // Made bookmark changes while sync is on.
227 Move(0, tier1_a
->GetChild(0), tier1_b
, 1);
228 Remove(0, tier1_b
, 0);
229 ASSERT_TRUE(AddFolder(0, tier1_b
, 1, "tier2_c"));
230 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
231 ASSERT_TRUE(ModelMatchesVerifier(0));
233 // Let server to return rollback command on next sync request.
234 ASSERT_TRUE(GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK
));
236 // Make another change to trigger downloading of rollback command.
237 Remove(0, tier1_b
, 0);
239 // Wait for rollback to finish and sync backend is completely shut down.
240 SyncRollbackChecker
rollback_checker(GetSyncService(0));
241 ASSERT_TRUE(rollback_checker
.Wait());
242 SyncBackendStoppedChecker
shutdown_checker(GetSyncService(0));
243 ASSERT_TRUE(shutdown_checker
.Wait());
245 // Verify bookmarks are restored.
246 ASSERT_EQ(1, tier1_a
->child_count());
247 const BookmarkNode
* url1
= tier1_a
->GetChild(0);
248 ASSERT_EQ(GURL("http://mail.google.com"), url1
->url());
250 ASSERT_EQ(1, tier1_b
->child_count());
251 const BookmarkNode
* url2
= tier1_b
->GetChild(0);
252 ASSERT_EQ(GURL("http://www.nhl.com"), url2
->url());
255 #if defined(ENABLE_PRE_SYNC_BACKUP)
256 #define MAYBE_TestRollbackDisabled TestRollbackDisabled
258 #define MAYBE_TestRollbackDisabled DISABLED_TestRollbackDisabled
260 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
261 MAYBE_TestRollbackDisabled
) {
264 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
268 // -> http://mail.google.com "url0"
269 // -> http://www.nhl.com "url1"
270 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
271 GURL("http://mail.google.com")));
272 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
273 GURL("http://www.nhl.com")));
275 // Setup sync, wait for its completion, and make sure changes were synced.
276 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
277 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
278 ASSERT_TRUE(ModelMatchesVerifier(0));
280 // Made bookmark changes while sync is on.
281 Remove(0, GetOtherNode(0), 1);
282 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
283 GURL("http://www.yahoo.com")));
284 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
285 ASSERT_TRUE(ModelMatchesVerifier(0));
287 // Let server to return rollback command on next sync request.
288 ASSERT_TRUE(GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK
));
290 // Make another change to trigger downloading of rollback command.
291 Remove(0, GetOtherNode(0), 0);
293 // Wait for sync backend is completely shut down.
294 SyncBackendStoppedChecker
shutdown_checker(GetSyncService(0));
295 ASSERT_TRUE(shutdown_checker
.Wait());
297 // With rollback disabled, bookmarks in backup DB should not be restored.
298 // Only bookmark added during sync is present.
299 ASSERT_EQ(1, GetOtherNode(0)->child_count());
300 ASSERT_EQ(GURL("http://www.yahoo.com"),
301 GetOtherNode(0)->GetChild(0)->url());
304 #if defined(ENABLE_PRE_SYNC_BACKUP)
305 #define MAYBE_TestSyncDisabled TestSyncDisabled
307 #define MAYBE_TestSyncDisabled DISABLED_TestSyncDisabled
309 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
310 MAYBE_TestSyncDisabled
) {
311 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
315 // -> http://mail.google.com "url0"
316 // -> http://www.nhl.com "url1"
317 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
318 GURL("http://mail.google.com")));
319 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
320 GURL("http://www.nhl.com")));
322 // Setup sync, wait for its completion, and make sure changes were synced.
323 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
324 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
325 ASSERT_TRUE(ModelMatchesVerifier(0));
327 // Made bookmark changes while sync is on.
328 Remove(0, GetOtherNode(0), 1);
329 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
330 GURL("http://www.yahoo.com")));
331 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
332 ASSERT_TRUE(ModelMatchesVerifier(0));
334 // Let server to return birthday error on next sync request.
335 ASSERT_TRUE(GetFakeServer()->TriggerError(
336 sync_pb::SyncEnums::NOT_MY_BIRTHDAY
));
338 // Make another change to trigger downloading of rollback command.
339 Remove(0, GetOtherNode(0), 0);
341 // Wait sync backend is completely shut down.
342 SyncBackendStoppedChecker
shutdown_checker(GetSyncService(0));
343 ASSERT_TRUE(shutdown_checker
.Wait());
345 // Shouldn't restore bookmarks with sign-out only.
346 ASSERT_EQ(1, GetOtherNode(0)->child_count());
347 ASSERT_EQ(GURL("http://www.yahoo.com"),
348 GetOtherNode(0)->GetChild(0)->url());
351 #if defined(ENABLE_PRE_SYNC_BACKUP)
352 #define MAYBE_RollbackNoBackup RollbackNoBackup
354 #define MAYBE_RollbackNoBackup DISABLED_RollbackNoBackup
356 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
357 MAYBE_RollbackNoBackup
) {
358 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
362 // -> http://mail.google.com "url0"
363 // -> http://www.nhl.com "url1"
364 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
365 GURL("http://mail.google.com")));
367 // Setup sync, wait for its completion, and make sure changes were synced.
368 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
369 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
370 ASSERT_TRUE(ModelMatchesVerifier(0));
372 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
373 GURL("http://www.nhl.com")));
377 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
380 // Let server to return rollback command on next sync request.
381 ASSERT_TRUE(GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK
));
383 // Make another change to trigger downloading of rollback command.
384 Remove(0, GetOtherNode(0), 0);
386 // Wait for rollback to finish and sync backend is completely shut down.
387 SyncRollbackChecker
rollback_checker(GetSyncService(0));
388 ASSERT_TRUE(rollback_checker
.Wait());
389 SyncBackendStoppedChecker
checker(GetSyncService(0));
390 ASSERT_TRUE(checker
.Wait());
392 // Without backup DB, bookmarks remain at the state when sync stops.
393 ASSERT_EQ(1, GetOtherNode(0)->child_count());
394 ASSERT_EQ(GURL("http://www.nhl.com"),
395 GetOtherNode(0)->GetChild(0)->url());
398 #if defined(ENABLE_PRE_SYNC_BACKUP)
399 #define MAYBE_DontChangeBookmarkOrdering DontChangeBookmarkOrdering
401 #define MAYBE_DontChangeBookmarkOrdering DISABLED_DontChangeBookmarkOrdering
403 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest
,
404 MAYBE_DontChangeBookmarkOrdering
) {
405 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
407 const BookmarkNode
* sub_folder
= AddFolder(0, GetOtherNode(0), 0, "test");
408 ASSERT_TRUE(AddURL(0, sub_folder
, 0, "", GURL(kUrl1
)));
409 ASSERT_TRUE(AddURL(0, sub_folder
, 1, "", GURL(kUrl2
)));
410 ASSERT_TRUE(AddURL(0, sub_folder
, 2, "", GURL(kUrl3
)));
412 // Setup sync, wait for its completion, and make sure changes were synced.
413 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
414 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
415 ASSERT_TRUE(ModelMatchesVerifier(0));
417 // Made bookmark changes while sync is on.
418 Remove(0, sub_folder
, 0);
419 Remove(0, sub_folder
, 0);
420 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
421 ASSERT_TRUE(ModelMatchesVerifier(0));
423 // Let server to return rollback command on next sync request.
424 ASSERT_TRUE(GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK
));
426 // Make another change to trigger downloading of rollback command.
427 Remove(0, sub_folder
, 0);
429 // Wait for rollback to finish and sync backend is completely shut down.
430 SyncRollbackChecker
rollback_checker(GetSyncService(0));
431 ASSERT_TRUE(rollback_checker
.Wait());
432 SyncBackendStoppedChecker
shutdown_checker(GetSyncService(0));
433 ASSERT_TRUE(shutdown_checker
.Wait());
435 // Verify bookmarks are unchanged.
436 ASSERT_EQ(3, sub_folder
->child_count());
437 ASSERT_EQ(GURL(kUrl1
), sub_folder
->GetChild(0)->url());
438 ASSERT_EQ(GURL(kUrl2
), sub_folder
->GetChild(1)->url());
439 ASSERT_EQ(GURL(kUrl3
), sub_folder
->GetChild(2)->url());