Home | History | Annotate | Download | only in integration
      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 "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"
     18 
     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;
     26 
     27 namespace {
     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
     32 
     33 class SingleClientBackupRollbackTest : public SyncTest {
     34  public:
     35   SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
     36   virtual ~SingleClientBackupRollbackTest() {}
     37 
     38   void DisableBackup() {
     39     CommandLine::ForCurrentProcess()->AppendSwitch(
     40           switches::kSyncDisableBackup);
     41   }
     42 
     43   void EnableRollback() {
     44     CommandLine::ForCurrentProcess()->AppendSwitch(
     45           switches::kSyncEnableRollback);
     46   }
     47 
     48  private:
     49   DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
     50 };
     51 
     52 class BackupModeChecker {
     53  public:
     54   explicit BackupModeChecker(ProfileSyncService* service,
     55                              base::TimeDelta timeout)
     56       : pss_(service),
     57         timeout_(timeout) {}
     58 
     59   bool Wait() {
     60     expiration_ = base::TimeTicks::Now() + timeout_;
     61     base::MessageLoop::current()->PostDelayedTask(
     62         FROM_HERE,
     63         base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
     64         base::TimeDelta::FromSeconds(1));
     65     base::MessageLoop::current()->Run();
     66     return IsBackupComplete();
     67   }
     68 
     69  private:
     70   void PeriodicCheck() {
     71     if (IsBackupComplete() || base::TimeTicks::Now() > expiration_) {
     72       base::MessageLoop::current()->Quit();
     73     } else {
     74       base::MessageLoop::current()->PostDelayedTask(
     75           FROM_HERE,
     76           base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
     77           base::TimeDelta::FromSeconds(1));
     78     }
     79   }
     80 
     81   bool IsBackupComplete() {
     82     return pss_->backend_mode() == ProfileSyncService::BACKUP &&
     83         pss_->ShouldPushChanges();
     84   }
     85 
     86   ProfileSyncService* pss_;
     87   base::TimeDelta timeout_;
     88   base::TimeTicks expiration_;
     89 };
     90 
     91 #if defined(ENABLE_PRE_SYNC_BACKUP)
     92 #define MAYBE_TestBackupRollback TestBackupRollback
     93 #else
     94 #define MAYBE_TestBackupRollback DISABLED_TestBackupRollback
     95 #endif
     96 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
     97                        MAYBE_TestBackupRollback) {
     98   EnableRollback();
     99   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
    100 
    101   // Starting state:
    102   // other_node
    103   //    -> top
    104   //      -> tier1_a
    105   //        -> http://mail.google.com  "tier1_a_url0"
    106   //      -> tier1_b
    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")));
    115 
    116   BackupModeChecker checker(GetSyncService(0),
    117                             base::TimeDelta::FromSeconds(15));
    118   ASSERT_TRUE(checker.Wait());
    119 
    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));
    124 
    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));
    131 
    132   // Let server to return rollback command on next sync request.
    133   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
    134 
    135   // Make another change to trigger downloading of rollback command.
    136   Remove(0, tier1_b, 0);
    137 
    138   // Wait for sync to switch to backup mode after finishing rollback.
    139   ASSERT_TRUE(checker.Wait());
    140 
    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());
    145 
    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());
    149 }
    150 
    151 #if defined(ENABLE_PRE_SYNC_BACKUP)
    152 #define MAYBE_TestPrefBackupRollback TestPrefBackupRollback
    153 #else
    154 #define MAYBE_TestPrefBackupRollback DISABLED_TestPrefBackupRollback
    155 #endif
    156 // Verify local preferences are not affected by preferences in backup DB under
    157 // backup mode.
    158 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
    159                        MAYBE_TestPrefBackupRollback) {
    160   EnableRollback();
    161 
    162   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
    163 
    164   preferences_helper::ChangeStringPref(0, prefs::kHomePage, kUrl1);
    165 
    166   BackupModeChecker checker(GetSyncService(0),
    167                             base::TimeDelta::FromSeconds(15));
    168   ASSERT_TRUE(checker.Wait());
    169 
    170   // Shut down backup, then change preference.
    171   GetSyncService(0)->StartStopBackupForTesting();
    172   preferences_helper::ChangeStringPref(0, prefs::kHomePage, kUrl2);
    173 
    174   // Restart backup. Preference shouldn't change after backup starts.
    175   GetSyncService(0)->StartStopBackupForTesting();
    176   ASSERT_TRUE(checker.Wait());
    177   ASSERT_EQ(kUrl2,
    178             preferences_helper::GetPrefs(0)->GetString(prefs::kHomePage));
    179 
    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));
    185 
    186   // Let server return rollback command on next sync request.
    187   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
    188 
    189   // Make another change to trigger downloading of rollback command.
    190   preferences_helper::ChangeStringPref(0, prefs::kHomePage, "");
    191 
    192   // Wait for sync to switch to backup mode after finishing rollback.
    193   ASSERT_TRUE(checker.Wait());
    194 
    195   // Verify preference is restored.
    196   ASSERT_EQ(kUrl2,
    197             preferences_helper::GetPrefs(0)->GetString(prefs::kHomePage));
    198 }
    199 
    200 #if defined(ENABLE_PRE_SYNC_BACKUP)
    201 #define MAYBE_RollbackNoBackup RollbackNoBackup
    202 #else
    203 #define MAYBE_RollbackNoBackup DISABLED_RollbackNoBackup
    204 #endif
    205 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
    206                        MAYBE_RollbackNoBackup) {
    207   EnableRollback();
    208 
    209   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
    210 
    211   // Setup sync, wait for its completion, and make sure changes were synced.
    212   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    213 
    214   // Starting state:
    215   // other_node
    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")));
    222 
    223   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
    224   ASSERT_TRUE(ModelMatchesVerifier(0));
    225 
    226   // Let server to return rollback command on next sync request.
    227   GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);
    228 
    229   // Make another change to trigger downloading of rollback command.
    230   Remove(0, GetOtherNode(0), 0);
    231 
    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());
    236 
    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());
    241 }
    242 
    243 #if defined(ENABLE_PRE_SYNC_BACKUP)
    244 #define MAYBE_DontChangeBookmarkOrdering DontChangeBookmarkOrdering
    245 #else
    246 #define MAYBE_DontChangeBookmarkOrdering DISABLED_DontChangeBookmarkOrdering
    247 #endif
    248 IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
    249                        MAYBE_DontChangeBookmarkOrdering) {
    250   ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
    251 
    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)));
    256 
    257   BackupModeChecker checker(GetSyncService(0),
    258                             base::TimeDelta::FromSeconds(15));
    259   ASSERT_TRUE(checker.Wait());
    260 
    261   // Restart backup.
    262   GetSyncService(0)->StartStopBackupForTesting();
    263   GetSyncService(0)->StartStopBackupForTesting();
    264   ASSERT_TRUE(checker.Wait());
    265 
    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());
    271 }
    272 
    273