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