single_client_backup_rollback_test.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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 23using bookmarks_helper::AddFolder; 24using bookmarks_helper::AddURL; 25using bookmarks_helper::GetOtherNode; 26using bookmarks_helper::ModelMatchesVerifier; 27using bookmarks_helper::Move; 28using bookmarks_helper::Remove; 29using sync_integration_test_util::AwaitCommitActivityCompletion; 30 31namespace { 32const char kUrl1[] = "http://www.google.com"; 33const char kUrl2[] = "http://map.google.com"; 34const char kUrl3[] = "http://plus.google.com"; 35} // anonymous namespace 36 37class 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 75class 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 117IN_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 137IN_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 157IN_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 218IN_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 272IN_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 323IN_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 369IN_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} 406