diff options
-rw-r--r-- | chrome/browser/sync/profile_sync_service_harness.cc | 4 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_harness.h | 3 | ||||
-rw-r--r-- | chrome/browser/sync/test/integration/sync_errors_test.cc | 37 | ||||
-rw-r--r-- | chrome/browser/sync/test/integration/sync_test.cc | 9 | ||||
-rw-r--r-- | chrome/browser/sync/test/integration/sync_test.h | 20 | ||||
-rwxr-xr-x | net/tools/testserver/chromiumsync.py | 42 |
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__), |