Home | History | Annotate | Download | only in integration
      1 // Copyright (c) 2012 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/prefs/pref_member.h"
      6 #include "base/prefs/pref_service.h"
      7 #include "base/run_loop.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/passwords_helper.h"
     11 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
     12 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
     13 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
     14 #include "chrome/browser/sync/test/integration/sync_test.h"
     15 #include "chrome/common/pref_names.h"
     16 #include "google_apis/gaia/google_service_auth_error.h"
     17 #include "sync/protocol/sync_protocol_error.h"
     18 
     19 using bookmarks_helper::AddFolder;
     20 using bookmarks_helper::SetTitle;
     21 using sync_integration_test_util::AwaitCommitActivityCompletion;
     22 
     23 namespace {
     24 
     25 class SyncDisabledChecker : public SingleClientStatusChangeChecker {
     26  public:
     27   explicit SyncDisabledChecker(ProfileSyncService* service)
     28       : SingleClientStatusChangeChecker(service) {}
     29 
     30   virtual bool IsExitConditionSatisfied() OVERRIDE {
     31     return !service()->setup_in_progress() &&
     32            !service()->HasSyncSetupCompleted();
     33   }
     34 
     35   virtual std::string GetDebugMessage() const OVERRIDE {
     36     return "Sync Disabled";
     37   }
     38 };
     39 
     40 class TypeDisabledChecker : public SingleClientStatusChangeChecker {
     41  public:
     42   explicit TypeDisabledChecker(ProfileSyncService* service,
     43                                syncer::ModelType type)
     44       : SingleClientStatusChangeChecker(service), type_(type) {}
     45 
     46   virtual bool IsExitConditionSatisfied() OVERRIDE {
     47     return !service()->GetActiveDataTypes().Has(type_);
     48   }
     49 
     50   virtual std::string GetDebugMessage() const OVERRIDE {
     51     return "Type disabled";
     52   }
     53  private:
     54    syncer::ModelType type_;
     55 };
     56 
     57 bool AwaitSyncDisabled(ProfileSyncService* service) {
     58   SyncDisabledChecker checker(service);
     59   checker.Wait();
     60   return !checker.TimedOut();
     61 }
     62 
     63 bool AwaitTypeDisabled(ProfileSyncService* service,
     64                        syncer::ModelType type) {
     65   TypeDisabledChecker checker(service, type);
     66   checker.Wait();
     67   return !checker.TimedOut();
     68 }
     69 
     70 class SyncErrorTest : public SyncTest {
     71  public:
     72   SyncErrorTest() : SyncTest(SINGLE_CLIENT) {}
     73   virtual ~SyncErrorTest() {}
     74 
     75  private:
     76   DISALLOW_COPY_AND_ASSIGN(SyncErrorTest);
     77 };
     78 
     79 // TODO(pvalenzuela): Remove this class when all tests here are converted to
     80 // use FakeServer.
     81 class LegacySyncErrorTest : public SyncTest {
     82  public:
     83   LegacySyncErrorTest() : SyncTest(SINGLE_CLIENT_LEGACY) {}
     84   virtual ~LegacySyncErrorTest() {}
     85 
     86  private:
     87   DISALLOW_COPY_AND_ASSIGN(LegacySyncErrorTest);
     88 };
     89 
     90 // Helper class that waits until the sync engine has hit an actionable error.
     91 class ActionableErrorChecker : public SingleClientStatusChangeChecker {
     92  public:
     93   explicit ActionableErrorChecker(ProfileSyncService* service)
     94       : SingleClientStatusChangeChecker(service) {}
     95 
     96   virtual ~ActionableErrorChecker() {}
     97 
     98   // Checks if an actionable error has been hit. Called repeatedly each time PSS
     99   // notifies observers of a state change.
    100   virtual bool IsExitConditionSatisfied() OVERRIDE {
    101     ProfileSyncService::Status status;
    102     service()->QueryDetailedSyncStatus(&status);
    103     return (status.sync_protocol_error.action != syncer::UNKNOWN_ACTION &&
    104             service()->HasUnrecoverableError());
    105   }
    106 
    107   virtual std::string GetDebugMessage() const OVERRIDE {
    108     return "ActionableErrorChecker";
    109   }
    110 
    111  private:
    112   DISALLOW_COPY_AND_ASSIGN(ActionableErrorChecker);
    113 };
    114 
    115 IN_PROC_BROWSER_TEST_F(SyncErrorTest, BirthdayErrorTest) {
    116   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    117 
    118   // Add an item, wait for sync, and trigger a birthday error on the server.
    119   const BookmarkNode* node1 = AddFolder(0, 0, "title1");
    120   SetTitle(0, node1, "new_title1");
    121   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
    122   ASSERT_TRUE(GetFakeServer()->SetNewStoreBirthday("new store birthday"));
    123 
    124   // Now make one more change so we will do another sync.
    125   const BookmarkNode* node2 = AddFolder(0, 0, "title2");
    126   SetTitle(0, node2, "new_title2");
    127   ASSERT_TRUE(AwaitSyncDisabled(GetSyncService((0))));
    128 }
    129 
    130 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest, ActionableErrorTest) {
    131   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    132 
    133   const BookmarkNode* node1 = AddFolder(0, 0, "title1");
    134   SetTitle(0, node1, "new_title1");
    135   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
    136 
    137   syncer::SyncProtocolError protocol_error;
    138   protocol_error.error_type = syncer::TRANSIENT_ERROR;
    139   protocol_error.action = syncer::UPGRADE_CLIENT;
    140   protocol_error.error_description = "Not My Fault";
    141   protocol_error.url = "www.google.com";
    142   TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_ALWAYS);
    143 
    144   // Now make one more change so we will do another sync.
    145   const BookmarkNode* node2 = AddFolder(0, 0, "title2");
    146   SetTitle(0, node2, "new_title2");
    147 
    148   // Wait until an actionable error is encountered.
    149   ActionableErrorChecker actionable_error_checker(GetSyncService((0)));
    150   actionable_error_checker.Wait();
    151   ASSERT_FALSE(actionable_error_checker.TimedOut());
    152 
    153   ProfileSyncService::Status status;
    154   GetSyncService((0))->QueryDetailedSyncStatus(&status);
    155   ASSERT_EQ(status.sync_protocol_error.error_type, protocol_error.error_type);
    156   ASSERT_EQ(status.sync_protocol_error.action, protocol_error.action);
    157   ASSERT_EQ(status.sync_protocol_error.url, protocol_error.url);
    158   ASSERT_EQ(status.sync_protocol_error.error_description,
    159       protocol_error.error_description);
    160 }
    161 
    162 // Disabled, http://crbug.com/351160 .
    163 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest, DISABLED_ErrorWhileSettingUp) {
    164   ASSERT_TRUE(SetupClients());
    165 
    166   syncer::SyncProtocolError protocol_error;
    167   protocol_error.error_type = syncer::TRANSIENT_ERROR;
    168   protocol_error.error_description = "Not My Fault";
    169   protocol_error.url = "www.google.com";
    170 
    171   if (GetSyncService(0)->auto_start_enabled()) {
    172     // In auto start enabled platforms like chrome os we should be
    173     // able to set up even if the first sync while setting up fails.
    174     // Trigger error on every 2 out of 3 requests.
    175     TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_TWO_THIRDS);
    176     // Now setup sync and it should succeed.
    177     ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    178   } else {
    179     // In Non auto start enabled environments if the setup sync fails then
    180     // the setup would fail. So setup sync normally.
    181     ASSERT_TRUE(SetupSync()) << "Setup sync failed";
    182     ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL));
    183 
    184     // Trigger error on every 2 out of 3 requests.
    185     TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_TWO_THIRDS);
    186 
    187     // Now enable a datatype, whose first 2 syncs would fail, but we should
    188     // recover and setup succesfully on the third attempt.
    189     ASSERT_TRUE(GetClient(0)->EnableSyncForDatatype(syncer::AUTOFILL));
    190   }
    191 }
    192 
    193 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest,
    194     DISABLED_BirthdayErrorUsingActionableErrorTest) {
    195   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    196 
    197   const BookmarkNode* node1 = AddFolder(0, 0, "title1");
    198   SetTitle(0, node1, "new_title1");
    199   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
    200 
    201   syncer::SyncProtocolError protocol_error;
    202   protocol_error.error_type = syncer::NOT_MY_BIRTHDAY;
    203   protocol_error.action = syncer::DISABLE_SYNC_ON_CLIENT;
    204   protocol_error.error_description = "Not My Fault";
    205   protocol_error.url = "www.google.com";
    206   TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_ALWAYS);
    207 
    208   // Now make one more change so we will do another sync.
    209   const BookmarkNode* node2 = AddFolder(0, 0, "title2");
    210   SetTitle(0, node2, "new_title2");
    211   ASSERT_TRUE(AwaitSyncDisabled(GetSyncService((0))));
    212   ProfileSyncService::Status status;
    213   GetSyncService((0))->QueryDetailedSyncStatus(&status);
    214   ASSERT_EQ(status.sync_protocol_error.error_type, protocol_error.error_type);
    215   ASSERT_EQ(status.sync_protocol_error.action, protocol_error.action);
    216   ASSERT_EQ(status.sync_protocol_error.url, protocol_error.url);
    217   ASSERT_EQ(status.sync_protocol_error.error_description,
    218       protocol_error.error_description);
    219 }
    220 
    221 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest, DisableDatatypeWhileRunning) {
    222   ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
    223   syncer::ModelTypeSet synced_datatypes =
    224       GetSyncService((0))->GetActiveDataTypes();
    225   ASSERT_TRUE(synced_datatypes.Has(syncer::TYPED_URLS));
    226   ASSERT_TRUE(synced_datatypes.Has(syncer::SESSIONS));
    227   GetProfile(0)->GetPrefs()->SetBoolean(
    228       prefs::kSavingBrowserHistoryDisabled, true);
    229 
    230   // Wait for reconfigurations.
    231   ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::TYPED_URLS));
    232   ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::SESSIONS));
    233 
    234   const BookmarkNode* node1 = AddFolder(0, 0, "title1");
    235   SetTitle(0, node1, "new_title1");
    236   ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
    237   // TODO(lipalani)" Verify initial sync ended for typed url is false.
    238 }
    239 
    240 }  // namespace
    241