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/message_loop/message_loop.h"
7 #include "base/prefs/pref_service.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/preferences_helper.h"
12 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
13 #include "chrome/browser/sync/test/integration/sync_test.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/bookmarks/browser/bookmark_model.h"
17 #include "sync/test/fake_server/fake_server_verifier.h"
19 using bookmarks_helper::AddFolder;
20 using bookmarks_helper::AddURL;
21 using bookmarks_helper::GetOtherNode;
22 using bookmarks_helper::ModelMatchesVerifier;
23 using bookmarks_helper::Move;
24 using bookmarks_helper::Remove;
25 using sync_integration_test_util::AwaitCommitActivityCompletion;
28 const char kUrl1[] = "http://www.google.com";
29 const char kUrl2[] = "http://map.google.com";
30 const char kUrl3[] = "http://plus.google.com";
31 } // anonymous namespace
33 class SingleClientBackupRollbackTest : public SyncTest {
35 SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
36 virtual ~SingleClientBackupRollbackTest() {}
38 void DisableBackup() {
39 CommandLine::ForCurrentProcess()->AppendSwitch(
40 switches::kSyncDisableBackup);
43 void EnableRollback() {
44 CommandLine::ForCurrentProcess()->AppendSwitch(
45 switches::kSyncEnableRollback);
49 DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
52 class BackupModeChecker {
54 explicit BackupModeChecker(ProfileSyncService* service,
55 base::TimeDelta timeout)
60 expiration_ = base::TimeTicks::Now() + timeout_;
61 base::MessageLoop::current()->PostDelayedTask(
63 base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
64 base::TimeDelta::FromSeconds(1));
65 base::MessageLoop::current()->Run();
66 return IsBackupComplete();
70 void PeriodicCheck() {
71 if (IsBackupComplete() || base::TimeTicks::Now() > expiration_) {
72 base::MessageLoop::current()->Quit();
74 base::MessageLoop::current()->PostDelayedTask(
76 base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
77 base::TimeDelta::FromSeconds(1));
81 bool IsBackupComplete() {
82 return pss_->backend_mode() == ProfileSyncService::BACKUP &&
83 pss_->ShouldPushChanges();
86 ProfileSyncService* pss_;
87 base::TimeDelta timeout_;
88 base::TimeTicks expiration_;
91 #if defined(ENABLE_PRE_SYNC_BACKUP)
92 #define MAYBE_TestBackupRollback TestBackupRollback
94 #define MAYBE_TestBackupRollback DISABLED_TestBackupRollback
96 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
97 MAYBE_TestBackupRollback) {
99 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
105 // -> http://mail.google.com "tier1_a_url0"
107 // -> http://www.nhl.com "tier1_b_url0"
108 const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, "top");
109 const BookmarkNode* tier1_a = AddFolder(0, top, 0, "tier1_a");
110 const BookmarkNode* tier1_b = AddFolder(0, top, 1, "tier1_b");
111 ASSERT_TRUE(AddURL(0, tier1_a, 0, "tier1_a_url0",
112 GURL("http://mail.google.com")));
113 ASSERT_TRUE(AddURL(0, tier1_b, 0, "tier1_b_url0",
114 GURL("http://www.nhl.com")));
116 BackupModeChecker checker(GetSyncService(0),
117 base::TimeDelta::FromSeconds(15));
118 ASSERT_TRUE(checker.Wait());
120 // Setup sync, wait for its completion, and make sure changes were synced.
121 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
122 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
123 ASSERT_TRUE(ModelMatchesVerifier(0));
125 // Made bookmark changes while sync is on.
126 Move(0, tier1_a->GetChild(0), tier1_b, 1);
127 Remove(0, tier1_b, 0);
128 ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c"));
129 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
130 ASSERT_TRUE(ModelMatchesVerifier(0));
132 // Let server to return rollback command on next sync request.
133 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
135 // Make another change to trigger downloading of rollback command.
136 Remove(0, tier1_b, 0);
138 // Wait for sync to switch to backup mode after finishing rollback.
139 ASSERT_TRUE(checker.Wait());
141 // Verify bookmarks are restored.
142 ASSERT_EQ(1, tier1_a->child_count());
143 const BookmarkNode* url1 = tier1_a->GetChild(0);
144 ASSERT_EQ(GURL("http://mail.google.com"), url1->url());
146 ASSERT_EQ(1, tier1_b->child_count());
147 const BookmarkNode* url2 = tier1_b->GetChild(0);
148 ASSERT_EQ(GURL("http://www.nhl.com"), url2->url());
151 #if defined(ENABLE_PRE_SYNC_BACKUP)
152 #define MAYBE_TestPrefBackupRollback TestPrefBackupRollback
154 #define MAYBE_TestPrefBackupRollback DISABLED_TestPrefBackupRollback
156 // Verify local preferences are not affected by preferences in backup DB under
158 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
159 MAYBE_TestPrefBackupRollback) {
162 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
164 preferences_helper::ChangeStringPref(0, prefs::kHomePage, kUrl1);
166 BackupModeChecker checker(GetSyncService(0),
167 base::TimeDelta::FromSeconds(15));
168 ASSERT_TRUE(checker.Wait());
170 // Shut down backup, then change preference.
171 GetSyncService(0)->StartStopBackupForTesting();
172 preferences_helper::ChangeStringPref(0, prefs::kHomePage, kUrl2);
174 // Restart backup. Preference shouldn't change after backup starts.
175 GetSyncService(0)->StartStopBackupForTesting();
176 ASSERT_TRUE(checker.Wait());
178 preferences_helper::GetPrefs(0)->GetString(prefs::kHomePage));
180 // Start sync and change preference.
181 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
182 preferences_helper::ChangeStringPref(0, prefs::kHomePage, kUrl3);
183 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
184 ASSERT_TRUE(ModelMatchesVerifier(0));
186 // Let server return rollback command on next sync request.
187 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
189 // Make another change to trigger downloading of rollback command.
190 preferences_helper::ChangeStringPref(0, prefs::kHomePage, "");
192 // Wait for sync to switch to backup mode after finishing rollback.
193 ASSERT_TRUE(checker.Wait());
195 // Verify preference is restored.
197 preferences_helper::GetPrefs(0)->GetString(prefs::kHomePage));
200 #if defined(ENABLE_PRE_SYNC_BACKUP)
201 #define MAYBE_RollbackNoBackup RollbackNoBackup
203 #define MAYBE_RollbackNoBackup DISABLED_RollbackNoBackup
205 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
206 MAYBE_RollbackNoBackup) {
209 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
211 // Setup sync, wait for its completion, and make sure changes were synced.
212 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
216 // -> http://mail.google.com "url0"
217 // -> http://www.nhl.com "url1"
218 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 0, "url0",
219 GURL("http://mail.google.com")));
220 ASSERT_TRUE(AddURL(0, GetOtherNode(0), 1, "url1",
221 GURL("http://www.nhl.com")));
223 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
224 ASSERT_TRUE(ModelMatchesVerifier(0));
226 // Let server to return rollback command on next sync request.
227 GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
229 // Make another change to trigger downloading of rollback command.
230 Remove(0, GetOtherNode(0), 0);
232 // Wait for sync to switch to backup mode after finishing rollback.
233 BackupModeChecker checker(GetSyncService(0),
234 base::TimeDelta::FromSeconds(15));
235 ASSERT_TRUE(checker.Wait());
237 // Without backup DB, bookmarks added during sync shouldn't be removed.
238 ASSERT_EQ(1, GetOtherNode(0)->child_count());
239 ASSERT_EQ(GURL("http://www.nhl.com"),
240 GetOtherNode(0)->GetChild(0)->url());
243 #if defined(ENABLE_PRE_SYNC_BACKUP)
244 #define MAYBE_DontChangeBookmarkOrdering DontChangeBookmarkOrdering
246 #define MAYBE_DontChangeBookmarkOrdering DISABLED_DontChangeBookmarkOrdering
248 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
249 MAYBE_DontChangeBookmarkOrdering) {
250 ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
252 const BookmarkNode* sub_folder = AddFolder(0, GetOtherNode(0), 0, "test");
253 ASSERT_TRUE(AddURL(0, sub_folder, 0, "", GURL(kUrl1)));
254 ASSERT_TRUE(AddURL(0, sub_folder, 1, "", GURL(kUrl2)));
255 ASSERT_TRUE(AddURL(0, sub_folder, 2, "", GURL(kUrl3)));
257 BackupModeChecker checker(GetSyncService(0),
258 base::TimeDelta::FromSeconds(15));
259 ASSERT_TRUE(checker.Wait());
262 GetSyncService(0)->StartStopBackupForTesting();
263 GetSyncService(0)->StartStopBackupForTesting();
264 ASSERT_TRUE(checker.Wait());
266 // Verify bookmarks are unchanged.
267 ASSERT_EQ(3, sub_folder->child_count());
268 ASSERT_EQ(GURL(kUrl1), sub_folder->GetChild(0)->url());
269 ASSERT_EQ(GURL(kUrl2), sub_folder->GetChild(1)->url());
270 ASSERT_EQ(GURL(kUrl3), sub_folder->GetChild(2)->url());