Commit d4898917 authored by lipalani@chromium.org's avatar lipalani@chromium.org

Integration test cases for the server directed error handling feature.

BUG=97671
TEST=sync_integration_tests.exe


Review URL: http://codereview.chromium.org/7919001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102426 0039d316-1c4b-4281-b951-d872f2087c98
parent 915fbcbd
...@@ -363,13 +363,16 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() { ...@@ -363,13 +363,16 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
GetLastSessionSnapshot(); GetLastSessionSnapshot();
CHECK(snap); CHECK(snap);
retry_verifier_.VerifyRetryInterval(*snap); retry_verifier_.VerifyRetryInterval(*snap);
if (retry_verifier_.done()) if (retry_verifier_.done()) {
// Retry verifier is done verifying exponential backoff.
SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); SignalStateCompleteWithNextState(WAITING_FOR_NOTHING);
}
break; break;
} }
case WAITING_FOR_MIGRATION_TO_START: { case WAITING_FOR_MIGRATION_TO_START: {
VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_START"); VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_START");
if (HasPendingBackendMigration()) { if (HasPendingBackendMigration()) {
// There are pending migrations. Wait for them.
SignalStateCompleteWithNextState(WAITING_FOR_MIGRATION_TO_FINISH); SignalStateCompleteWithNextState(WAITING_FOR_MIGRATION_TO_FINISH);
} }
break; break;
...@@ -377,6 +380,17 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() { ...@@ -377,6 +380,17 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
case WAITING_FOR_MIGRATION_TO_FINISH: { case WAITING_FOR_MIGRATION_TO_FINISH: {
VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_FINISH"); VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_FINISH");
if (!HasPendingBackendMigration()) { if (!HasPendingBackendMigration()) {
// Done migrating.
SignalStateCompleteWithNextState(WAITING_FOR_NOTHING);
}
break;
}
case WAITING_FOR_ACTIONABLE_ERROR: {
VLOG(1) << GetClientInfoString("WAITING_FOR_ACTIONABLE_ERROR");
ProfileSyncService::Status status = GetStatus();
if (status.sync_protocol_error.action != browser_sync::UNKNOWN_ACTION &&
service_->unrecoverable_error_detected() == true) {
// An actionable error has been detected.
SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); SignalStateCompleteWithNextState(WAITING_FOR_NOTHING);
} }
break; break;
...@@ -582,6 +596,17 @@ bool ProfileSyncServiceHarness::AwaitExponentialBackoffVerification() { ...@@ -582,6 +596,17 @@ bool ProfileSyncServiceHarness::AwaitExponentialBackoffVerification() {
return (retry_verifier_.Succeeded()); return (retry_verifier_.Succeeded());
} }
bool ProfileSyncServiceHarness::AwaitActionableError() {
ProfileSyncService::Status status = GetStatus();
CHECK(status.sync_protocol_error.action == browser_sync::UNKNOWN_ACTION);
wait_state_ = WAITING_FOR_ACTIONABLE_ERROR;
AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs,
"Waiting for actionable error");
status = GetStatus();
return (status.sync_protocol_error.action != browser_sync::UNKNOWN_ACTION &&
service_->unrecoverable_error_detected());
}
bool ProfileSyncServiceHarness::AwaitMigration( bool ProfileSyncServiceHarness::AwaitMigration(
const syncable::ModelTypeSet& expected_migrated_types) { const syncable::ModelTypeSet& expected_migrated_types) {
VLOG(1) << GetClientInfoString("AwaitMigration"); VLOG(1) << GetClientInfoString("AwaitMigration");
......
...@@ -80,13 +80,17 @@ class ProfileSyncServiceHarness ...@@ -80,13 +80,17 @@ class ProfileSyncServiceHarness
// since the previous one. Returns true if a sync cycle has completed. // since the previous one. Returns true if a sync cycle has completed.
bool AwaitSyncCycleCompletion(const std::string& reason); bool AwaitSyncCycleCompletion(const std::string& reason);
// Blocks the caller until the sync has been disabled for this client. Returns // Blocks the caller until sync has been disabled for this client. Returns
// true if sync is disabled. // true if sync is disabled.
bool AwaitSyncDisabled(const std::string& reason); bool AwaitSyncDisabled(const std::string& reason);
// Blocks the caller until exponential backoff has been verified to happen. // Blocks the caller until exponential backoff has been verified to happen.
bool AwaitExponentialBackoffVerification(); bool AwaitExponentialBackoffVerification();
// Blocks the caller until the syncer receives an actionable error.
// Returns true if the sync client received an actionable error.
bool AwaitActionableError();
// Blocks until the given set of data types are migrated. // Blocks until the given set of data types are migrated.
bool AwaitMigration(const syncable::ModelTypeSet& expected_migrated_types); bool AwaitMigration(const syncable::ModelTypeSet& expected_migrated_types);
...@@ -125,10 +129,10 @@ class ProfileSyncServiceHarness ...@@ -125,10 +129,10 @@ class ProfileSyncServiceHarness
// calling SetPassphrase has been accepted. // calling SetPassphrase has been accepted.
bool AwaitPassphraseAccepted(); bool AwaitPassphraseAccepted();
// Returns the ProfileSyncService member of the the sync client. // Returns the ProfileSyncService member of the sync client.
ProfileSyncService* service() { return service_; } ProfileSyncService* service() { return service_; }
// Returns the status of the ProfileSyncService member of the the sync client. // Returns the status of the ProfileSyncService member of the sync client.
ProfileSyncService::Status GetStatus(); ProfileSyncService::Status GetStatus();
// See ProfileSyncService::ShouldPushChanges(). // See ProfileSyncService::ShouldPushChanges().
...@@ -207,7 +211,7 @@ class ProfileSyncServiceHarness ...@@ -207,7 +211,7 @@ class ProfileSyncServiceHarness
// full sync cycle is not expected to occur. // full sync cycle is not expected to occur.
WAITING_FOR_SYNC_CONFIGURATION, WAITING_FOR_SYNC_CONFIGURATION,
// The sync client is waiting for the sync to be disabled for this client. // The sync client is waiting for sync to be disabled for this client.
WAITING_FOR_SYNC_DISABLED, WAITING_FOR_SYNC_DISABLED,
// The sync client is in the exponential backoff mode. Verify that // The sync client is in the exponential backoff mode. Verify that
...@@ -220,6 +224,9 @@ class ProfileSyncServiceHarness ...@@ -220,6 +224,9 @@ class ProfileSyncServiceHarness
// The sync client is waiting for migration to finish. // The sync client is waiting for migration to finish.
WAITING_FOR_MIGRATION_TO_FINISH, WAITING_FOR_MIGRATION_TO_FINISH,
// The sync client is waiting for an actionable error from the server.
WAITING_FOR_ACTIONABLE_ERROR,
// The client verification is complete. We don't care about the state of // The client verification is complete. We don't care about the state of
// the syncer any more. // the syncer any more.
WAITING_FOR_NOTHING, WAITING_FOR_NOTHING,
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_harness.h" #include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/protocol/sync_protocol_error.h"
#include "chrome/browser/sync/test/integration/bookmarks_helper.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h" #include "chrome/browser/sync/test/integration/sync_test.h"
...@@ -46,3 +48,58 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest, TransientErrorTest) { ...@@ -46,3 +48,58 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest, TransientErrorTest) {
ASSERT_TRUE( ASSERT_TRUE(
GetClient(0)->AwaitExponentialBackoffVerification()); GetClient(0)->AwaitExponentialBackoffVerification());
} }
IN_PROC_BROWSER_TEST_F(SyncErrorTest, ActionableErrorTest) {
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
const BookmarkNode* node1 = AddFolder(0, 0, L"title1");
SetTitle(0, node1, L"new_title1");
ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion("Sync."));
browser_sync::SyncProtocolError protocol_error;
protocol_error.error_type = browser_sync::TRANSIENT_ERROR;
protocol_error.action = browser_sync::UPGRADE_CLIENT;
protocol_error.error_description = "Not My Fault";
protocol_error.url = "www.google.com";
TriggerSyncError(protocol_error);
// Now make one more change so we will do another sync.
const BookmarkNode* node2 = AddFolder(0, 0, L"title2");
SetTitle(0, node2, L"new_title2");
ASSERT_TRUE(
GetClient(0)->AwaitActionableError());
ProfileSyncService::Status status = GetClient(0)->GetStatus();
ASSERT_EQ(status.sync_protocol_error.error_type, protocol_error.error_type);
ASSERT_EQ(status.sync_protocol_error.action, protocol_error.action);
ASSERT_EQ(status.sync_protocol_error.url, protocol_error.url);
ASSERT_EQ(status.sync_protocol_error.error_description,
protocol_error.error_description);
}
IN_PROC_BROWSER_TEST_F(SyncErrorTest,
BirthdayErrorUsingActionableErrorTest) {
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
const BookmarkNode* node1 = AddFolder(0, 0, L"title1");
SetTitle(0, node1, L"new_title1");
ASSERT_TRUE(GetClient(0)->AwaitSyncCycleCompletion("Sync."));
browser_sync::SyncProtocolError protocol_error;
protocol_error.error_type = browser_sync::NOT_MY_BIRTHDAY;
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);
// Now make one more change so we will do another sync.
const BookmarkNode* node2 = AddFolder(0, 0, L"title2");
SetTitle(0, node2, L"new_title2");
ASSERT_TRUE(
GetClient(0)->AwaitSyncDisabled("Birthday Error."));
ProfileSyncService::Status status = GetClient(0)->GetStatus();
ASSERT_EQ(status.sync_protocol_error.error_type, protocol_error.error_type);
ASSERT_EQ(status.sync_protocol_error.action, protocol_error.action);
ASSERT_EQ(status.sync_protocol_error.url, protocol_error.url);
ASSERT_EQ(status.sync_protocol_error.error_description,
protocol_error.error_description);
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/sync/notifier/p2p_notifier.h" #include "chrome/browser/sync/notifier/p2p_notifier.h"
#include "chrome/browser/sync/profile_sync_service_harness.h" #include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/protocol/sync.pb.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h" #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_list.h"
...@@ -610,6 +611,77 @@ void SyncTest::TriggerTransientError() { ...@@ -610,6 +611,77 @@ void SyncTest::TriggerTransientError() {
UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle())); UTF16ToASCII(browser()->GetSelectedTabContents()->GetTitle()));
} }
namespace {
sync_pb::ClientToServerResponse::ErrorType
GetClientToServerResponseErrorType(
browser_sync::SyncProtocolErrorType error) {
switch (error) {
case browser_sync::SYNC_SUCCESS:
return sync_pb::ClientToServerResponse::SUCCESS;
case browser_sync::NOT_MY_BIRTHDAY:
return sync_pb::ClientToServerResponse::NOT_MY_BIRTHDAY;
case browser_sync::THROTTLED:
return sync_pb::ClientToServerResponse::THROTTLED;
case browser_sync::CLEAR_PENDING:
return sync_pb::ClientToServerResponse::CLEAR_PENDING;
case browser_sync::TRANSIENT_ERROR:
return sync_pb::ClientToServerResponse::TRANSIENT_ERROR;
case browser_sync::MIGRATION_DONE:
return sync_pb::ClientToServerResponse::MIGRATION_DONE;
case browser_sync::UNKNOWN_ERROR:
return sync_pb::ClientToServerResponse::UNKNOWN;
default:
NOTREACHED();
return sync_pb::ClientToServerResponse::UNKNOWN;
}
}
sync_pb::ClientToServerResponse::Error::Action
GetClientToServerResponseAction(
const browser_sync::ClientAction& action) {
switch (action) {
case browser_sync::UPGRADE_CLIENT:
return sync_pb::ClientToServerResponse::Error::UPGRADE_CLIENT;
case browser_sync::CLEAR_USER_DATA_AND_RESYNC:
return sync_pb::ClientToServerResponse::Error::CLEAR_USER_DATA_AND_RESYNC;
case browser_sync::ENABLE_SYNC_ON_ACCOUNT:
return sync_pb::ClientToServerResponse::Error::ENABLE_SYNC_ON_ACCOUNT;
case browser_sync::STOP_AND_RESTART_SYNC:
return sync_pb::ClientToServerResponse::Error::STOP_AND_RESTART_SYNC;
case browser_sync::DISABLE_SYNC_ON_CLIENT:
return sync_pb::ClientToServerResponse::Error::DISABLE_SYNC_ON_CLIENT;
case browser_sync::UNKNOWN_ACTION:
return sync_pb::ClientToServerResponse::Error::UNKNOWN_ACTION;
default:
NOTREACHED();
return sync_pb::ClientToServerResponse::Error::UNKNOWN_ACTION;
}
}
} // namespace
void SyncTest::TriggerSyncError(const browser_sync::SyncProtocolError& error) {
ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/error";
int error_type =
static_cast<int>(GetClientToServerResponseErrorType(
error.error_type));
int action = static_cast<int>(GetClientToServerResponseAction(
error.action));
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;
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
std::string output = UTF16ToASCII(
browser()->GetSelectedTabContents()->GetTitle());
ASSERT_TRUE(output.find("SetError: 200") != string16::npos);
}
void SyncTest::TriggerSetSyncTabs() { void SyncTest::TriggerSetSyncTabs() {
ASSERT_TRUE(ServerSupportsErrorTriggering()); ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/synctabs"; std::string path = "chromiumsync/synctabs";
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/process_util.h" #include "base/process_util.h"
#include "chrome/browser/sync/protocol/sync_protocol_error.h"
#include "chrome/browser/sync/syncable/model_type.h" #include "chrome/browser/sync/syncable/model_type.h"
#include "net/base/mock_host_resolver.h" #include "net/base/mock_host_resolver.h"
#include "net/test/test_server.h" #include "net/test/test_server.h"
...@@ -173,6 +174,9 @@ class SyncTest : public InProcessBrowserTest { ...@@ -173,6 +174,9 @@ class SyncTest : public InProcessBrowserTest {
// this state until shut down. // this state until shut down.
void TriggerTransientError(); void TriggerTransientError();
// Triggers a sync error on the server.
void TriggerSyncError(const browser_sync::SyncProtocolError& error);
// Triggers setting the sync_tabs field of the nigori node. // Triggers setting the sync_tabs field of the nigori node.
void TriggerSetSyncTabs(); void TriggerSetSyncTabs();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment