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.
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"
19 using bookmarks_helper::AddFolder
;
20 using bookmarks_helper::SetTitle
;
21 using sync_integration_test_util::AwaitCommitActivityCompletion
;
25 class SyncDisabledChecker
: public SingleClientStatusChangeChecker
{
27 explicit SyncDisabledChecker(ProfileSyncService
* service
)
28 : SingleClientStatusChangeChecker(service
) {}
30 virtual bool IsExitConditionSatisfied() OVERRIDE
{
31 return !service()->setup_in_progress() &&
32 !service()->HasSyncSetupCompleted();
35 virtual std::string
GetDebugMessage() const OVERRIDE
{
36 return "Sync Disabled";
40 class TypeDisabledChecker
: public SingleClientStatusChangeChecker
{
42 explicit TypeDisabledChecker(ProfileSyncService
* service
,
43 syncer::ModelType type
)
44 : SingleClientStatusChangeChecker(service
), type_(type
) {}
46 virtual bool IsExitConditionSatisfied() OVERRIDE
{
47 return !service()->GetActiveDataTypes().Has(type_
);
50 virtual std::string
GetDebugMessage() const OVERRIDE
{
51 return "Type disabled";
54 syncer::ModelType type_
;
57 bool AwaitSyncDisabled(ProfileSyncService
* service
) {
58 SyncDisabledChecker
checker(service
);
60 return !checker
.TimedOut();
63 bool AwaitTypeDisabled(ProfileSyncService
* service
,
64 syncer::ModelType type
) {
65 TypeDisabledChecker
checker(service
, type
);
67 return !checker
.TimedOut();
70 class SyncErrorTest
: public SyncTest
{
72 SyncErrorTest() : SyncTest(SINGLE_CLIENT
) {}
73 virtual ~SyncErrorTest() {}
76 DISALLOW_COPY_AND_ASSIGN(SyncErrorTest
);
79 // TODO(pvalenzuela): Remove this class when all tests here are converted to
81 class LegacySyncErrorTest
: public SyncTest
{
83 LegacySyncErrorTest() : SyncTest(SINGLE_CLIENT_LEGACY
) {}
84 virtual ~LegacySyncErrorTest() {}
87 DISALLOW_COPY_AND_ASSIGN(LegacySyncErrorTest
);
90 // Helper class that waits until the sync engine has hit an actionable error.
91 class ActionableErrorChecker
: public SingleClientStatusChangeChecker
{
93 explicit ActionableErrorChecker(ProfileSyncService
* service
)
94 : SingleClientStatusChangeChecker(service
) {}
96 virtual ~ActionableErrorChecker() {}
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());
107 virtual std::string
GetDebugMessage() const OVERRIDE
{
108 return "ActionableErrorChecker";
112 DISALLOW_COPY_AND_ASSIGN(ActionableErrorChecker
);
115 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, BirthdayErrorTest
) {
116 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
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"));
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))));
130 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest
, ActionableErrorTest
) {
131 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
133 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
134 SetTitle(0, node1
, "new_title1");
135 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
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
);
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");
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());
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
);
162 // Disabled, http://crbug.com/351160 .
163 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest
, DISABLED_ErrorWhileSettingUp
) {
164 ASSERT_TRUE(SetupClients());
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";
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.";
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
));
184 // Trigger error on every 2 out of 3 requests.
185 TriggerSyncError(protocol_error
, SyncTest::ERROR_FREQUENCY_TWO_THIRDS
);
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
));
193 IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest
,
194 DISABLED_BirthdayErrorUsingActionableErrorTest
) {
195 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
197 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
198 SetTitle(0, node1
, "new_title1");
199 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
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
);
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
);
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);
230 // Wait for reconfigurations.
231 ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::TYPED_URLS
));
232 ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::SESSIONS
));
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.