sync_errors_test.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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
18using bookmarks_helper::AddFolder;
19using bookmarks_helper::SetTitle;
20using sync_integration_test_util::AwaitCommitActivityCompletion;
21
22namespace {
23
24class SyncDisabledChecker : public SingleClientStatusChangeChecker {
25 public:
26  explicit SyncDisabledChecker(ProfileSyncService* service)
27      : SingleClientStatusChangeChecker(service) {}
28
29  virtual bool IsExitConditionSatisfied() OVERRIDE {
30    return !service()->setup_in_progress() &&
31           !service()->HasSyncSetupCompleted();
32  }
33
34  virtual std::string GetDebugMessage() const OVERRIDE {
35    return "Sync Disabled";
36  }
37};
38
39bool AwaitSyncDisabled(ProfileSyncService* service) {
40  SyncDisabledChecker checker(service);
41  checker.Wait();
42  return !checker.TimedOut();
43}
44
45class SyncErrorTest : public SyncTest {
46 public:
47  SyncErrorTest() : SyncTest(SINGLE_CLIENT) {}
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.
56class LegacySyncErrorTest : public SyncTest {
57 public:
58  LegacySyncErrorTest() : SyncTest(SINGLE_CLIENT_LEGACY) {}
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.
66class ActionableErrorChecker : public SingleClientStatusChangeChecker {
67 public:
68  explicit ActionableErrorChecker(ProfileSyncService* service)
69      : SingleClientStatusChangeChecker(service) {}
70
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.
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
82  virtual std::string GetDebugMessage() const OVERRIDE {
83    return "ActionableErrorChecker";
84  }
85
86 private:
87  DISALLOW_COPY_AND_ASSIGN(ActionableErrorChecker);
88};
89
90IN_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
105IN_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 .
138IN_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
168IN_PROC_BROWSER_TEST_F(LegacySyncErrorTest,
169    DISABLED_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.
197IN_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