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 "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"
17 using bookmarks_helper::AddFolder
;
18 using bookmarks_helper::SetTitle
;
22 class SyncErrorTest
: public SyncTest
{
24 SyncErrorTest() : SyncTest(SINGLE_CLIENT
) {}
25 virtual ~SyncErrorTest() {}
28 DISALLOW_COPY_AND_ASSIGN(SyncErrorTest
);
31 // Helper class that waits until the sync engine has hit an actionable error.
32 class ActionableErrorChecker
: public StatusChangeChecker
{
34 explicit ActionableErrorChecker(ProfileSyncService
* service
)
35 : StatusChangeChecker("ActionableErrorChecker"),
38 virtual ~ActionableErrorChecker() {}
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
{
44 ProfileSyncService::Status status
;
45 service_
->QueryDetailedSyncStatus(&status
);
46 return (status
.sync_protocol_error
.action
!= syncer::UNKNOWN_ACTION
&&
47 service_
->HasUnrecoverableError());
51 // The PSS instance that will eventually hit an actionable error.
52 ProfileSyncService
* service_
;
54 DISALLOW_COPY_AND_ASSIGN(ActionableErrorChecker
);
57 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, BirthdayErrorTest
) {
58 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
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)->AwaitFullSyncCompletion());
64 TriggerBirthdayError();
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());
72 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, ActionableErrorTest
) {
73 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
75 const BookmarkNode
* node1
= AddFolder(0, 0, L
"title1");
76 SetTitle(0, node1
, L
"new_title1");
77 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion());
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
);
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");
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"));
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
);
103 IN_PROC_BROWSER_TEST_F(SyncErrorTest
, ErrorWhileSettingUp
) {
104 ASSERT_TRUE(SetupClients());
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";
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.";
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
));
124 // Trigger error on every 2 out of 3 requests.
125 TriggerSyncError(protocol_error
, SyncTest::ERROR_FREQUENCY_TWO_THIRDS
);
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
));
133 IN_PROC_BROWSER_TEST_F(SyncErrorTest
,
134 BirthdayErrorUsingActionableErrorTest
) {
135 ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
137 const BookmarkNode
* node1
= AddFolder(0, 0, L
"title1");
138 SetTitle(0, node1
, L
"new_title1");
139 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion());
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
);
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
);
160 // TODO(lipalani): Fix the typed_url dtc so this test case can pass.
161 IN_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);
169 synced_datatypes
= GetClient(0)->service()->GetPreferredDataTypes();
170 ASSERT_FALSE(synced_datatypes
.Has(syncer::TYPED_URLS
));
172 const BookmarkNode
* node1
= AddFolder(0, 0, L
"title1");
173 SetTitle(0, node1
, L
"new_title1");
174 ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion());
175 // TODO(lipalani)" Verify initial sync ended for typed url is false.