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/message_loop/message_loop.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/run_loop.h"
10 #include "base/test/test_timeouts.h"
11 #include "chrome/browser/browsing_data/browsing_data_remover.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/sync/profile_sync_service.h"
14 #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
15 #include "chrome/browser/sync/test/integration/preferences_helper.h"
16 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
17 #include "chrome/browser/sync/test/integration/sync_test.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/pref_names.h"
20 #include "components/bookmarks/browser/bookmark_model.h"
21 #include "sync/internal_api/public/util/sync_db_util.h"
22 #include "sync/test/fake_server/fake_server_verifier.h"
23 #include "sync/util/time.h"
25 using bookmarks_helper::AddFolder;
26 using bookmarks_helper::AddURL;
27 using bookmarks_helper::GetOtherNode;
28 using bookmarks_helper::ModelMatchesVerifier;
29 using bookmarks_helper::Move;
30 using bookmarks_helper::Remove;
31 using sync_integration_test_util::AwaitCommitActivityCompletion;
34 const char kUrl1[] = "http://www.google.com";
35 const char kUrl2[] = "http://map.google.com";
36 const char kUrl3[] = "http://plus.google.com";
37 } // anonymous namespace
39 class SingleClientBackupRollbackTest : public SyncTest {
41 SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
42 virtual ~SingleClientBackupRollbackTest() {}
44 void DisableBackup() {
45 CommandLine::ForCurrentProcess()->AppendSwitch(
46 switches::kSyncDisableBackup);
49 void DisableRollback() {
50 CommandLine::ForCurrentProcess()->AppendSwitch(
51 switches::kSyncDisableRollback);
54 base::Time GetBackupDbLastModified() {
55 base::RunLoop run_loop;
57 base::Time backup_time;
58 syncer::CheckSyncDbLastModifiedTime(
59 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
60 base::MessageLoopProxy::current(),
61 base::Bind(&SingleClientBackupRollbackTest::CheckDbCallback,
62 base::Unretained(this), &backup_time));
63 base::MessageLoopProxy::current()->PostTask(
64 FROM_HERE, run_loop.QuitClosure());
70 void CheckDbCallback(base::Time* time_out, base::Time time_in) {
71 *time_out = syncer::ProtoTimeToTime(syncer::TimeToProtoTime(time_in));
74 DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
77 // Waits until the ProfileSyncService's backend is in IDLE mode.
78 class SyncBackendStoppedChecker : public ProfileSyncServiceBase::Observer {
80 explicit SyncBackendStoppedChecker(ProfileSyncService* service)
82 timeout_(TestTimeouts::action_max_timeout()),
85 virtual void OnStateChanged() OVERRIDE {
86 if (ProfileSyncService::IDLE == pss_->backend_mode()) {
93 pss_->AddObserver(this);
94 if (ProfileSyncService::IDLE == pss_->backend_mode())
96 base::MessageLoop::current()->PostDelayedTask(
98 run_loop_.QuitClosure(),
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 ProfileSyncServiceBase::Observer,
115 public BrowsingDataRemover::Observer {
117 explicit SyncRollbackChecker(ProfileSyncService* service)
119 timeout_(TestTimeouts::action_max_timeout()),
120 rollback_started_(false),
121 clear_done_(false) {}
123 // ProfileSyncServiceBase::Observer implementation.
124 virtual void OnStateChanged() OVERRIDE {
125 if (ProfileSyncService::ROLLBACK == pss_->backend_mode()) {
126 rollback_started_ = true;
132 // BrowsingDataRemoverObserver::Observer implementation.
133 virtual void OnBrowsingDataRemoverDone() OVERRIDE {
135 if (rollback_started_) {
141 pss_->AddObserver(this);
142 pss_->SetBrowsingDataRemoverObserverForTesting(this);
143 base::MessageLoop::current()->PostDelayedTask(
145 run_loop_.QuitClosure(),
148 pss_->RemoveObserver(this);
149 return rollback_started_ && clear_done_;
152 ProfileSyncService* const pss_;
153 const base::TimeDelta timeout_;
154 base::RunLoop run_loop_;
155 bool rollback_started_;
159 #if defined(ENABLE_PRE_SYNC_BACKUP)
160 #define MAYBE_TestBackup TestBackup
162 #define MAYBE_TestBackup DISABLED_TestBackup
164 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
166 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
168 // Setup sync, wait for its completion, and make sure changes were synced.
169 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
170 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
171 ASSERT_TRUE(ModelMatchesVerifier(0));
173 // Verify backup DB is created and backup time is set on device info.
174 base::Time backup_time = GetBackupDbLastModified();
175 ASSERT_FALSE(backup_time.is_null());
176 ASSERT_EQ(backup_time, GetSyncService(0)->GetDeviceBackupTimeForTesting());
179 #if defined(ENABLE_PRE_SYNC_BACKUP)
180 #define MAYBE_TestBackupDisabled TestBackupDisabled
182 #define MAYBE_TestBackupDisabled DISABLED_TestBackupDisabled
184 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
185 MAYBE_TestBackupDisabled) {
188 // Setup sync, wait for its completion, and make sure changes were synced.
189 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
190 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
191 ASSERT_TRUE(ModelMatchesVerifier(0));
193 // Verify backup DB is not created and backup time is not set on device info.
194 ASSERT_FALSE(base::PathExists(
195 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup"))));
196 ASSERT_TRUE(GetSyncService(0)->GetDeviceBackupTimeForTesting().is_null());
199 #if defined(ENABLE_PRE_SYNC_BACKUP)
200 #define MAYBE_TestRollback TestRollback
202 #define MAYBE_TestRollback DISABLED_TestRollback
204 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
205 MAYBE_TestRollback) {
206 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
212 // -> http://mail.google.com "tier1_a_url0"
214 // -> http://www.nhl.com "tier1_b_url0"
215 const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, "top");
216 const BookmarkNode* tier1_a = AddFolder(0, top, 0, "tier1_a");
217 const BookmarkNode* tier1_b = AddFolder(0, top, 1, "tier1_b");
218 ASSERT_TRUE(AddURL(0, tier1_a, 0, "tier1_a_url0",
219 GURL("http://mail.google.com")));
220 ASSERT_TRUE(AddURL(0, tier1_b, 0, "tier1_b_url0",
221 GURL("http://www.nhl.com")));
223 // Setup sync, wait for its completion, and make sure changes were synced.
224 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
225 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
226 ASSERT_TRUE(ModelMatchesVerifier(0));
228 // Made bookmark changes while sync is on.
229 Move(0, tier1_a->GetChild(0), tier1_b, 1);
230 Remove(0, tier1_b, 0);
231 ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c"));
232 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
233 ASSERT_TRUE(ModelMatchesVerifier(0));
235 // Let server to return rollback command on next sync request.
236 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
238 // Make another change to trigger downloading of rollback command.
239 Remove(0, tier1_b, 0);
241 // Wait for rollback to finish and sync backend is completely shut down.
242 SyncRollbackChecker rollback_checker(GetSyncService(0));
243 ASSERT_TRUE(rollback_checker.Wait());
244 SyncBackendStoppedChecker shutdown_checker(GetSyncService(0));
245 ASSERT_TRUE(shutdown_checker.Wait());
247 // Verify bookmarks are restored.
248 ASSERT_EQ(1, tier1_a->child_count());
249 const BookmarkNode* url1 = tier1_a->GetChild(0);
250 ASSERT_EQ(GURL("http://mail.google.com"), url1->url());
252 ASSERT_EQ(1, tier1_b->child_count());
253 const BookmarkNode* url2 = tier1_b->GetChild(0);
254 ASSERT_EQ(GURL("http://www.nhl.com"), url2->url());
257 #if defined(ENABLE_PRE_SYNC_BACKUP)
258 #define MAYBE_TestRollbackDisabled TestRollbackDisabled
260 #define MAYBE_TestRollbackDisabled DISABLED_TestRollbackDisabled
262 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
263 MAYBE_TestRollbackDisabled) {
266 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
270 // -> http://mail.google.com "url0"
271 // -> http://www.nhl.com "url1"
272 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
273 GURL("http://mail.google.com")));
274 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
275 GURL("http://www.nhl.com")));
277 // Setup sync, wait for its completion, and make sure changes were synced.
278 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
279 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
280 ASSERT_TRUE(ModelMatchesVerifier(0));
282 // Made bookmark changes while sync is on.
283 Remove(0, GetOtherNode(0), 1);
284 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
285 GURL("http://www.yahoo.com")));
286 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
287 ASSERT_TRUE(ModelMatchesVerifier(0));
289 // Let server to return rollback command on next sync request.
290 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
292 // Make another change to trigger downloading of rollback command.
293 Remove(0, GetOtherNode(0), 0);
295 // Wait for sync backend is completely shut down.
296 SyncBackendStoppedChecker shutdown_checker(GetSyncService(0));
297 ASSERT_TRUE(shutdown_checker.Wait());
299 // With rollback disabled, bookmarks in backup DB should not be restored.
300 // Only bookmark added during sync is present.
301 ASSERT_EQ(1, GetOtherNode(0)->child_count());
302 ASSERT_EQ(GURL("http://www.yahoo.com"),
303 GetOtherNode(0)->GetChild(0)->url());
306 #if defined(ENABLE_PRE_SYNC_BACKUP)
307 #define MAYBE_TestSyncDisabled TestSyncDisabled
309 #define MAYBE_TestSyncDisabled DISABLED_TestSyncDisabled
311 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
312 MAYBE_TestSyncDisabled) {
313 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
317 // -> http://mail.google.com "url0"
318 // -> http://www.nhl.com "url1"
319 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
320 GURL("http://mail.google.com")));
321 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
322 GURL("http://www.nhl.com")));
324 // Setup sync, wait for its completion, and make sure changes were synced.
325 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
326 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
327 ASSERT_TRUE(ModelMatchesVerifier(0));
329 // Made bookmark changes while sync is on.
330 Remove(0, GetOtherNode(0), 1);
331 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url2",
332 GURL("http://www.yahoo.com")));
333 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
334 ASSERT_TRUE(ModelMatchesVerifier(0));
336 // Let server to return birthday error on next sync request.
337 GetFakeServer()->TriggerError(sync_pb::SyncEnums::NOT_MY_BIRTHDAY);
339 // Make another change to trigger downloading of rollback command.
340 Remove(0, GetOtherNode(0), 0);
342 // Wait sync backend is completely shut down.
343 SyncBackendStoppedChecker shutdown_checker(GetSyncService(0));
344 ASSERT_TRUE(shutdown_checker.Wait());
346 // Shouldn't restore bookmarks with sign-out only.
347 ASSERT_EQ(1, GetOtherNode(0)->child_count());
348 ASSERT_EQ(GURL("http://www.yahoo.com"),
349 GetOtherNode(0)->GetChild(0)->url());
352 #if defined(ENABLE_PRE_SYNC_BACKUP)
353 #define MAYBE_RollbackNoBackup RollbackNoBackup
355 #define MAYBE_RollbackNoBackup DISABLED_RollbackNoBackup
357 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
358 MAYBE_RollbackNoBackup) {
359 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
363 // -> http://mail.google.com "url0"
364 // -> http://www.nhl.com "url1"
365 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
366 GURL("http://mail.google.com")));
368 // Setup sync, wait for its completion, and make sure changes were synced.
369 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
370 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
371 ASSERT_TRUE(ModelMatchesVerifier(0));
373 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
374 GURL("http://www.nhl.com")));
378 GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")),
381 // Let server to return rollback command on next sync request.
382 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
384 // Make another change to trigger downloading of rollback command.
385 Remove(0, GetOtherNode(0), 0);
387 // Wait for rollback to finish and sync backend is completely shut down.
388 SyncRollbackChecker rollback_checker(GetSyncService(0));
389 ASSERT_TRUE(rollback_checker.Wait());
390 SyncBackendStoppedChecker checker(GetSyncService(0));
391 ASSERT_TRUE(checker.Wait());
393 // Without backup DB, bookmarks remain at the state when sync stops.
394 ASSERT_EQ(1, GetOtherNode(0)->child_count());
395 ASSERT_EQ(GURL("http://www.nhl.com"),
396 GetOtherNode(0)->GetChild(0)->url());
399 #if defined(ENABLE_PRE_SYNC_BACKUP)
400 #define MAYBE_DontChangeBookmarkOrdering DontChangeBookmarkOrdering
402 #define MAYBE_DontChangeBookmarkOrdering DISABLED_DontChangeBookmarkOrdering
404 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
405 MAYBE_DontChangeBookmarkOrdering) {
406 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
408 const BookmarkNode* sub_folder = AddFolder(0, GetOtherNode(0), 0, "test");
409 ASSERT_TRUE(AddURL(0, sub_folder, 0, "", GURL(kUrl1)));
410 ASSERT_TRUE(AddURL(0, sub_folder, 1, "", GURL(kUrl2)));
411 ASSERT_TRUE(AddURL(0, sub_folder, 2, "", GURL(kUrl3)));
413 // Setup sync, wait for its completion, and make sure changes were synced.
414 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
415 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
416 ASSERT_TRUE(ModelMatchesVerifier(0));
418 // Made bookmark changes while sync is on.
419 Remove(0, sub_folder, 0);
420 Remove(0, sub_folder, 0);
421 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0)));
422 ASSERT_TRUE(ModelMatchesVerifier(0));
424 // Let server to return rollback command on next sync request.
425 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
427 // Make another change to trigger downloading of rollback command.
428 Remove(0, sub_folder, 0);
430 // Wait for rollback to finish and sync backend is completely shut down.
431 SyncRollbackChecker rollback_checker(GetSyncService(0));
432 ASSERT_TRUE(rollback_checker.Wait());
433 SyncBackendStoppedChecker shutdown_checker(GetSyncService(0));
434 ASSERT_TRUE(shutdown_checker.Wait());
436 // Verify bookmarks are unchanged.
437 ASSERT_EQ(3, sub_folder->child_count());
438 ASSERT_EQ(GURL(kUrl1), sub_folder->GetChild(0)->url());
439 ASSERT_EQ(GURL(kUrl2), sub_folder->GetChild(1)->url());
440 ASSERT_EQ(GURL(kUrl3), sub_folder->GetChild(2)->url());