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::BookmarkNode
;
20 using bookmarks_helper::AddFolder
;
21 using bookmarks_helper::SetTitle
;
22 using sync_integration_test_util::AwaitCommitActivityCompletion
;
26 class SyncDisabledChecker
: public SingleClientStatusChangeChecker
{
28 explicit SyncDisabledChecker(ProfileSyncService
* service
)
29 : SingleClientStatusChangeChecker(service
) {}
31 bool IsExitConditionSatisfied() override
{
32 return !service()->setup_in_progress() &&
33 !service()->HasSyncSetupCompleted();
36 std::string
GetDebugMessage() const override
{ return "Sync Disabled"; }
39 class TypeDisabledChecker
: public SingleClientStatusChangeChecker
{
41 explicit TypeDisabledChecker(ProfileSyncService
* service
,
42 syncer::ModelType type
)
43 : SingleClientStatusChangeChecker(service
), type_(type
) {}
45 bool IsExitConditionSatisfied() override
{
46 return !service()->GetActiveDataTypes().Has(type_
);
49 std::string
GetDebugMessage() const override
{ return "Type disabled"; }
51 syncer::ModelType type_
;
54 bool AwaitSyncDisabled(ProfileSyncService
* service
) {
55 SyncDisabledChecker
checker(service
);
57 return !checker
.TimedOut();
60 bool AwaitTypeDisabled(ProfileSyncService
* service
,
61 syncer::ModelType type
) {
62 TypeDisabledChecker
checker(service
, type
);
64 return !checker
.TimedOut();
67 class SyncErrorTest
: public SyncTest
{
69 SyncErrorTest() : SyncTest(SINGLE_CLIENT
) {}
70 ~SyncErrorTest() override
{}
73 DISALLOW_COPY_AND_ASSIGN(SyncErrorTest
);
76 // Helper class that waits until the sync engine has hit an actionable error.
77 class ActionableErrorChecker
: public SingleClientStatusChangeChecker
{
79 explicit ActionableErrorChecker(ProfileSyncService
* service
)
80 : SingleClientStatusChangeChecker(service
) {}
82 ~ActionableErrorChecker() override
{}
84 // Checks if an actionable error has been hit. Called repeatedly each time PSS
85 // notifies observers of a state change.
86 bool IsExitConditionSatisfied() override
{
87 ProfileSyncService::Status status
;
88 service()->QueryDetailedSyncStatus(&status
);
89 return (status
.sync_protocol_error
.action
!= syncer::UNKNOWN_ACTION
&&
90 service()->HasUnrecoverableError());
93 std::string
GetDebugMessage() const override
{
94 return "ActionableErrorChecker";
98 DISALLOW_COPY_AND_ASSIGN(ActionableErrorChecker
);
101 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, BirthdayErrorTest
) {
102 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
104 // Add an item, wait for sync, and trigger a birthday error on the server.
105 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
106 SetTitle(0, node1
, "new_title1");
107 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
108 GetFakeServer()->ClearServerData();
110 // Now make one more change so we will do another sync.
111 const BookmarkNode
* node2
= AddFolder(0, 0, "title2");
112 SetTitle(0, node2
, "new_title2");
113 ASSERT_TRUE(AwaitSyncDisabled(GetSyncService((0))));
116 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, ActionableErrorTest
) {
117 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
119 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
120 SetTitle(0, node1
, "new_title1");
121 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
123 std::string description
= "Not My Fault";
124 std::string url
= "www.google.com";
125 EXPECT_TRUE(GetFakeServer()->TriggerActionableError(
126 sync_pb::SyncEnums::TRANSIENT_ERROR
,
129 sync_pb::SyncEnums::UPGRADE_CLIENT
));
131 // Now make one more change so we will do another sync.
132 const BookmarkNode
* node2
= AddFolder(0, 0, "title2");
133 SetTitle(0, node2
, "new_title2");
135 // Wait until an actionable error is encountered.
136 ActionableErrorChecker
actionable_error_checker(GetSyncService((0)));
137 actionable_error_checker
.Wait();
138 ASSERT_FALSE(actionable_error_checker
.TimedOut());
140 ProfileSyncService::Status status
;
141 GetSyncService((0))->QueryDetailedSyncStatus(&status
);
142 ASSERT_EQ(status
.sync_protocol_error
.error_type
, syncer::TRANSIENT_ERROR
);
143 ASSERT_EQ(status
.sync_protocol_error
.action
, syncer::UPGRADE_CLIENT
);
144 ASSERT_EQ(status
.sync_protocol_error
.url
, url
);
145 ASSERT_EQ(status
.sync_protocol_error
.error_description
, description
);
148 // TODO(sync): Fix failing test on Chrome OS: http://crbug.com/351160
149 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, DISABLED_ErrorWhileSettingUpAutoStart
) {
150 ASSERT_TRUE(SetupClients());
151 ASSERT_TRUE(GetSyncService(0)->auto_start_enabled());
153 // In auto start enabled platforms like chrome os we should be
154 // able to set up even if the first sync while setting up fails.
155 EXPECT_TRUE(GetFakeServer()->TriggerError(
156 sync_pb::SyncEnums::TRANSIENT_ERROR
));
157 EXPECT_TRUE(GetFakeServer()->EnableAlternatingTriggeredErrors());
158 // Now setup sync and it should succeed.
159 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
162 #if defined(OS_CHROMEOS)
163 #define MAYBE_ErrorWhileSettingUp DISABLED_ErrorWhileSettingUp
165 #define MAYBE_ErrorWhileSettingUp ErrorWhileSettingUp
167 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, MAYBE_ErrorWhileSettingUp
) {
168 ASSERT_TRUE(SetupClients());
169 ASSERT_FALSE(GetSyncService(0)->auto_start_enabled());
171 // In Non auto start enabled environments if the setup sync fails then
172 // the setup would fail. So setup sync normally.
173 ASSERT_TRUE(SetupSync()) << "Setup sync failed";
174 ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL
));
176 EXPECT_TRUE(GetFakeServer()->TriggerError(
177 sync_pb::SyncEnums::TRANSIENT_ERROR
));
178 EXPECT_TRUE(GetFakeServer()->EnableAlternatingTriggeredErrors());
180 // Now enable a datatype, whose first 2 syncs would fail, but we should
181 // recover and setup succesfully on the third attempt.
182 ASSERT_TRUE(GetClient(0)->EnableSyncForDatatype(syncer::AUTOFILL
));
185 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, BirthdayErrorUsingActionableErrorTest
) {
186 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
188 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
189 SetTitle(0, node1
, "new_title1");
190 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
192 std::string description
= "Not My Fault";
193 std::string url
= "www.google.com";
194 EXPECT_TRUE(GetFakeServer()->TriggerActionableError(
195 sync_pb::SyncEnums::NOT_MY_BIRTHDAY
,
198 sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT
));
200 // Now make one more change so we will do another sync.
201 const BookmarkNode
* node2
= AddFolder(0, 0, "title2");
202 SetTitle(0, node2
, "new_title2");
203 ASSERT_TRUE(AwaitSyncDisabled(GetSyncService((0))));
204 ProfileSyncService::Status status
;
205 GetSyncService((0))->QueryDetailedSyncStatus(&status
);
206 ASSERT_EQ(status
.sync_protocol_error
.error_type
, syncer::NOT_MY_BIRTHDAY
);
207 ASSERT_EQ(status
.sync_protocol_error
.action
, syncer::DISABLE_SYNC_ON_CLIENT
);
208 ASSERT_EQ(status
.sync_protocol_error
.url
, url
);
209 ASSERT_EQ(status
.sync_protocol_error
.error_description
, description
);
212 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, DisableDatatypeWhileRunning
) {
213 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
214 syncer::ModelTypeSet synced_datatypes
=
215 GetSyncService((0))->GetActiveDataTypes();
216 ASSERT_TRUE(synced_datatypes
.Has(syncer::TYPED_URLS
));
217 ASSERT_TRUE(synced_datatypes
.Has(syncer::SESSIONS
));
218 GetProfile(0)->GetPrefs()->SetBoolean(
219 prefs::kSavingBrowserHistoryDisabled
, true);
221 // Wait for reconfigurations.
222 ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::TYPED_URLS
));
223 ASSERT_TRUE(AwaitTypeDisabled(GetSyncService(0), syncer::SESSIONS
));
225 const BookmarkNode
* node1
= AddFolder(0, 0, "title1");
226 SetTitle(0, node1
, "new_title1");
227 ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
228 // TODO(lipalani)" Verify initial sync ended for typed url is false.