single_client_backup_rollback_test.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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/message_loop/message_loop.h"
7#include "chrome/browser/profiles/profile.h"
8#include "chrome/browser/sync/profile_sync_service.h"
9#include "chrome/browser/sync/test/integration/bookmarks_helper.h"
10#include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
11#include "chrome/browser/sync/test/integration/sync_test.h"
12#include "chrome/common/chrome_switches.h"
13#include "components/bookmarks/browser/bookmark_model.h"
14#include "sync/test/fake_server/fake_server_verifier.h"
15
16using bookmarks_helper::AddFolder;
17using bookmarks_helper::AddURL;
18using bookmarks_helper::GetOtherNode;
19using bookmarks_helper::ModelMatchesVerifier;
20using bookmarks_helper::Move;
21using bookmarks_helper::Remove;
22using sync_integration_test_util::AwaitCommitActivityCompletion;
23
24class SingleClientBackupRollbackTest : public SyncTest {
25 public:
26  SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
27  virtual ~SingleClientBackupRollbackTest() {}
28
29  virtual void SetUp() OVERRIDE {
30    CommandLine::ForCurrentProcess()->AppendSwitch(
31          switches::kSyncEnableRollback);
32    SyncTest::SetUp();
33  }
34
35 private:
36  DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
37};
38
39class BackupModeChecker {
40 public:
41  explicit BackupModeChecker(ProfileSyncService* service,
42                             base::TimeDelta timeout)
43      : pss_(service),
44        expiration_(base::TimeTicks::Now() + timeout) {}
45
46  bool Wait() {
47    base::MessageLoop::current()->PostDelayedTask(
48        FROM_HERE,
49        base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
50        base::TimeDelta::FromSeconds(1));
51    base::MessageLoop::current()->Run();
52    return IsBackupComplete();
53  }
54
55 private:
56  void PeriodicCheck() {
57    if (IsBackupComplete() || base::TimeTicks::Now() > expiration_) {
58      base::MessageLoop::current()->Quit();
59    } else {
60      base::MessageLoop::current()->PostDelayedTask(
61          FROM_HERE,
62          base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
63          base::TimeDelta::FromSeconds(1));
64    }
65  }
66
67  bool IsBackupComplete() {
68    return pss_->backend_mode() == ProfileSyncService::BACKUP &&
69        pss_->ShouldPushChanges();
70  }
71
72  ProfileSyncService* pss_;
73  base::TimeTicks expiration_;
74};
75
76#if defined(ENABLE_PRE_SYNC_BACKUP)
77#define MAYBE_TestBackupRollback TestBackupRollback
78#else
79#define MAYBE_TestBackupRollback DISABLED_TestBackupRollback
80#endif
81IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
82                       MAYBE_TestBackupRollback) {
83  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
84
85  // Starting state:
86  // other_node
87  //    -> top
88  //      -> tier1_a
89  //        -> http://mail.google.com  "tier1_a_url0"
90  //      -> tier1_b
91  //        -> http://www.nhl.com "tier1_b_url0"
92  const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, "top");
93  const BookmarkNode* tier1_a = AddFolder(0, top, 0, "tier1_a");
94  const BookmarkNode* tier1_b = AddFolder(0, top, 1, "tier1_b");
95  ASSERT_TRUE(AddURL(0, tier1_a, 0, "tier1_a_url0",
96                     GURL("http://mail.google.com")));
97  ASSERT_TRUE(AddURL(0, tier1_b, 0, "tier1_b_url0",
98                     GURL("http://www.nhl.com")));
99
100  BackupModeChecker checker(GetSyncService(0),
101                            base::TimeDelta::FromSeconds(15));
102  ASSERT_TRUE(checker.Wait());
103
104  // Setup sync, wait for its completion, and make sure changes were synced.
105  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
106  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
107  ASSERT_TRUE(ModelMatchesVerifier(0));
108
109  // Made bookmark changes while sync is on.
110  Move(0, tier1_a->GetChild(0), tier1_b, 1);
111  Remove(0, tier1_b, 0);
112  ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c"));
113  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
114  ASSERT_TRUE(ModelMatchesVerifier(0));
115
116  // Let server to return rollback command on next sync request.
117  GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
118
119  // Make another change to trigger downloading of rollback command.
120  Remove(0, tier1_b, 0);
121
122  // Wait for sync to switch to backup mode after finishing rollback.
123  ASSERT_TRUE(checker.Wait());
124
125  // Verify bookmarks are restored.
126  ASSERT_EQ(1, tier1_a->child_count());
127  const BookmarkNode* url1 = tier1_a->GetChild(0);
128  ASSERT_EQ(GURL("http://mail.google.com"), url1->url());
129
130  ASSERT_EQ(1, tier1_b->child_count());
131  const BookmarkNode* url2 = tier1_b->GetChild(0);
132  ASSERT_EQ(GURL("http://www.nhl.com"), url2->url());
133}
134