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