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