summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.cc4
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.h3
-rw-r--r--chrome/browser/sync/test/integration/sync_errors_test.cc37
-rw-r--r--chrome/browser/sync/test/integration/sync_test.cc9
-rw-r--r--chrome/browser/sync/test/integration/sync_test.h20
-rwxr-xr-xnet/tools/testserver/chromiumsync.py42
6 files changed, 105 insertions, 10 deletions
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index 5cf6e41..5e4d856 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -814,6 +814,10 @@ bool ProfileSyncServiceHarness::HasPendingBackendMigration() {
return migrator && migrator->state() != browser_sync::BackendMigrator::IDLE;
}
+bool ProfileSyncServiceHarness::AutoStartEnabled() {
+ return service_->auto_start_enabled();
+}
+
bool ProfileSyncServiceHarness::MatchesOtherClient(
ProfileSyncServiceHarness* partner) {
// TODO(akalin): Shouldn't this belong with the intersection check?
diff --git a/chrome/browser/sync/profile_sync_service_harness.h b/chrome/browser/sync/profile_sync_service_harness.h
index 29d783d..8aba89e 100644
--- a/chrome/browser/sync/profile_sync_service_harness.h
+++ b/chrome/browser/sync/profile_sync_service_harness.h
@@ -194,6 +194,9 @@ class ProfileSyncServiceHarness
// they're in).
size_t GetNumDatatypes() const;
+ // Gets the |auto_start_enabled_| variable from the |service_|.
+ bool AutoStartEnabled();
+
private:
friend class StateChangeTimeoutEvent;
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc
index b73f054..c1ba3e8 100644
--- a/chrome/browser/sync/test/integration/sync_errors_test.cc
+++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -63,7 +63,7 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest, ActionableErrorTest) {
protocol_error.action = browser_sync::UPGRADE_CLIENT;
protocol_error.error_description = "Not My Fault";
protocol_error.url = "www.google.com";
- TriggerSyncError(protocol_error);
+ TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_ALWAYS);
// Now make one more change so we will do another sync.
const BookmarkNode* node2 = AddFolder(0, 0, L"title2");
@@ -78,6 +78,37 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest, ActionableErrorTest) {
protocol_error.error_description);
}
+IN_PROC_BROWSER_TEST_F(SyncErrorTest, ErrorWhileSettingUp) {
+ ASSERT_TRUE(SetupClients());
+
+ browser_sync::SyncProtocolError protocol_error;
+ protocol_error.error_type = browser_sync::TRANSIENT_ERROR;
+ protocol_error.error_description = "Not My Fault";
+ protocol_error.url = "www.google.com";
+
+ if (clients()[0]->AutoStartEnabled()) {
+ // In auto start enabled platforms like chrome os we should be
+ // able to set up even if the first sync while setting up fails.
+ // Trigger error on every 2 out of 3 requests.
+ TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_TWO_THIRDS);
+ // Now setup sync and it should succeed.
+ ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
+ } else {
+ // In Non auto start enabled environments if the setup sync fails then
+ // the setup would fail. So setup sync normally.
+ ASSERT_TRUE(SetupSync()) << "Setup sync failed";
+ ASSERT_TRUE(clients()[0]->DisableSyncForDatatype(syncable::AUTOFILL));
+
+ // Trigger error on every 2 out of 3 requests.
+ TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_TWO_THIRDS);
+
+ // Now enable a datatype, whose first 2 syncs would fail, but we should
+ // recover and setup succesfully on the third attempt.
+ ASSERT_TRUE(clients()[0]->EnableSyncForDatatype(syncable::AUTOFILL));
+ }
+}
+
+
IN_PROC_BROWSER_TEST_F(SyncErrorTest,
BirthdayErrorUsingActionableErrorTest) {
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
@@ -91,7 +122,7 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest,
protocol_error.action = browser_sync::DISABLE_SYNC_ON_CLIENT;
protocol_error.error_description = "Not My Fault";
protocol_error.url = "www.google.com";
- TriggerSyncError(protocol_error);
+ TriggerSyncError(protocol_error, SyncTest::ERROR_FREQUENCY_ALWAYS);
// Now make one more change so we will do another sync.
const BookmarkNode* node2 = AddFolder(0, 0, L"title2");
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 6a3cce2..4fa23ef 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -696,7 +696,8 @@ sync_pb::ClientToServerResponse::Error::Action
} // namespace
-void SyncTest::TriggerSyncError(const browser_sync::SyncProtocolError& error) {
+void SyncTest::TriggerSyncError(const browser_sync::SyncProtocolError& error,
+ SyncErrorFrequency frequency) {
ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/error";
int error_type =
@@ -708,8 +709,10 @@ void SyncTest::TriggerSyncError(const browser_sync::SyncProtocolError& error) {
path.append(base::StringPrintf("?error=%d", error_type));
path.append(base::StringPrintf("&action=%d", action));
- path += "&error_description=" + error.error_description;
- path += "&url=" + error.url;
+ path.append(base::StringPrintf("&error_description=%s",
+ error.error_description.c_str()));
+ path.append(base::StringPrintf("&url=%s", error.url.c_str()));
+ path.append(base::StringPrintf("&frequency=%d", frequency));
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
std::string output = UTF16ToASCII(
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index cc5543b..eaa00bf 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -68,6 +68,21 @@ class SyncTest : public InProcessBrowserTest {
// account state is initially clean.
};
+ // NOTE: IMPORTANT the enum here should match with
+ // the enum defined on the chromiumsync.py test server impl.
+ enum SyncErrorFrequency {
+ // Uninitialized state.
+ ERROR_FREQUENCY_NONE,
+
+ // Server sends the error on all requests.
+ ERROR_FREQUENCY_ALWAYS,
+
+ // Server sends the error on two thirds of the request.
+ // Note this is not random. The server would send the
+ // error on the first 2 requests of every 3 requests.
+ ERROR_FREQUENCY_TWO_THIRDS
+ };
+
// A SyncTest must be associated with a particular test type.
explicit SyncTest(TestType test_type);
@@ -177,7 +192,10 @@ class SyncTest : public InProcessBrowserTest {
void TriggerAuthError();
// Triggers a sync error on the server.
- void TriggerSyncError(const browser_sync::SyncProtocolError& error);
+ // error: The error the server is expected to return.
+ // frequency: Frequency with which the error is returned.
+ void TriggerSyncError(const browser_sync::SyncProtocolError& error,
+ SyncErrorFrequency frequency);
// Triggers setting the sync_tabs field of the nigori node.
void TriggerSetSyncTabs();
diff --git a/net/tools/testserver/chromiumsync.py b/net/tools/testserver/chromiumsync.py
index da2aede..b290e50 100755
--- a/net/tools/testserver/chromiumsync.py
+++ b/net/tools/testserver/chromiumsync.py
@@ -57,6 +57,14 @@ ALL_TYPES = (
TYPED_URL,
EXTENSION_SETTINGS) = range(16)
+# An eumeration on the frequency at which the server should send errors
+# to the client. This would be specified by the url that triggers the error.
+# Note: This enum should be kept in the same order as the enum in sync_test.h.
+SYNC_ERROR_FREQUENCY = (
+ ERROR_FREQUENCY_NONE,
+ ERROR_FREQUENCY_ALWAYS,
+ ERROR_FREQUENCY_TWO_THIRDS) = range(3)
+
# Well-known server tag of the top level 'Google Chrome' folder.
TOP_LEVEL_FOLDER_TAG = 'google_chrome'
@@ -122,6 +130,10 @@ class SyncInducedError(Error):
"""The client would be sent an error."""
+class InducedErrorFrequencyNotDefined(Error):
+ """The error frequency defined is not handled."""
+
+
def GetEntryType(entry):
"""Extract the sync type from a SyncEntry.
@@ -441,6 +453,8 @@ class SyncDataModel(object):
self.migration_history = MigrationHistory()
self.induced_error = sync_pb2.ClientToServerResponse.Error()
+ self.induced_error_frequency = 0
+ self.sync_count_before_errors = 0
def _SaveEntry(self, entry):
"""Insert or update an entry in the change log, and give it a new version.
@@ -910,8 +924,11 @@ class SyncDataModel(object):
True)
self._SaveEntry(nigori_new)
- def SetInducedError(self, error):
+ def SetInducedError(self, error, error_frequency,
+ sync_count_before_errors):
self.induced_error = error
+ self.induced_error_frequency = error_frequency
+ self.sync_count_before_errors = sync_count_before_errors
def GetInducedError(self):
return self.induced_error
@@ -935,6 +952,7 @@ class TestServer(object):
self.client_name_generator = ('+' * times + chr(c)
for times in xrange(0, sys.maxint) for c in xrange(ord('A'), ord('Z')))
self.transient_error = False
+ self.sync_count = 0
def GetShortClientName(self, query):
parsed = cgi.parse_qs(query[query.find('?')+1:])
@@ -962,7 +980,20 @@ class TestServer(object):
"""Raises SyncInducedError if needed."""
if (self.account.induced_error.error_type !=
sync_enums_pb2.SyncEnums.UNKNOWN):
- raise SyncInducedError
+ # Always means return the given error for all requests.
+ if self.account.induced_error_frequency == ERROR_FREQUENCY_ALWAYS:
+ raise SyncInducedError
+ # This means the FIRST 2 requests of every 3 requests
+ # return an error. Don't switch the order of failures. There are
+ # test cases that rely on the first 2 being the failure rather than
+ # the last 2.
+ elif (self.account.induced_error_frequency ==
+ ERROR_FREQUENCY_TWO_THIRDS):
+ if (((self.sync_count -
+ self.account.sync_count_before_errors) % 3) != 0):
+ raise SyncInducedError
+ else:
+ raise InducedErrorFrequencyNotDefined
def HandleMigrate(self, path):
query = urlparse.urlparse(path)[4]
@@ -1006,7 +1037,11 @@ class TestServer(object):
(urlparse.parse_qs(query)['error_description'])[0])
except KeyError:
error.error_description = ''
- self.account.SetInducedError(error)
+ try:
+ error_frequency = int((urlparse.parse_qs(query)['frequency'])[0])
+ except KeyError:
+ error_frequency = ERROR_FREQUENCY_ALWAYS
+ self.account.SetInducedError(error, error_frequency, self.sync_count)
response = ('Error = %d, action = %d, url = %s, description = %s' %
(error.error_type, error.action,
error.url,
@@ -1053,6 +1088,7 @@ class TestServer(object):
serialized reply to the command.
"""
self.account_lock.acquire()
+ self.sync_count += 1
def print_context(direction):
print '[Client %s %s %s.py]' % (self.GetShortClientName(query), direction,
__name__),