summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync/profile_sync_service.cc4
-rw-r--r--chrome/browser/sync/profile_sync_service.h3
-rw-r--r--chrome/browser/sync/profile_sync_service_harness.cc6
-rw-r--r--chrome/browser/sync/test/integration/sync_auth_test.cc54
-rw-r--r--chrome/browser/sync/test/integration/sync_errors_test.cc36
-rw-r--r--chrome/browser/sync/test/integration/sync_test.cc33
-rw-r--r--chrome/browser/sync/test/integration/sync_test.h26
-rw-r--r--chrome/chrome_tests.gypi1
8 files changed, 109 insertions, 54 deletions
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index f2e0c4e..bc576b9 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -2144,6 +2144,10 @@ void ProfileSyncService::OnInternalUnrecoverableError(
OnUnrecoverableErrorImpl(from_here, message, delete_sync_database);
}
+bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const {
+ return request_access_token_retry_timer_.IsRunning();
+}
+
std::string ProfileSyncService::GetEffectiveUsername() {
if (profile_->IsManaged()) {
#if defined(ENABLE_MANAGED_USERS)
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 4dd851a..f64f8ea 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -495,6 +495,9 @@ class ProfileSyncService : public ProfileSyncServiceBase,
// Used by ProfileSyncServiceHarness. May return NULL.
browser_sync::BackendMigrator* GetBackendMigratorForTest();
+ // Used by tests to inspect interaction with OAuth2TokenService.
+ bool IsRetryingAccessTokenFetchForTest() const;
+
// TODO(sync): This is only used in tests. Can we remove it?
void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const;
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index 800d1bb..f90f791 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -349,6 +349,12 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
}
case WAITING_FOR_FULL_SYNC: {
DVLOG(1) << GetClientInfoString("WAITING_FOR_FULL_SYNC");
+ if (service()->GetAuthError().state() ==
+ GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
+ // Our credentials were rejected. Do not wait any more.
+ SignalStateCompleteWithNextState(CREDENTIALS_REJECTED);
+ break;
+ }
if (IsFullySynced()) {
// The sync cycle we were waiting for is complete.
SignalStateCompleteWithNextState(FULLY_SYNCED);
diff --git a/chrome/browser/sync/test/integration/sync_auth_test.cc b/chrome/browser/sync/test/integration/sync_auth_test.cc
new file mode 100644
index 0000000..7393cfb
--- /dev/null
+++ b/chrome/browser/sync/test/integration/sync_auth_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2013 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.
+
+#include "base/threading/platform_thread.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/profile_sync_service_harness.h"
+#include "chrome/browser/sync/test/integration/bookmarks_helper.h"
+#include "chrome/browser/sync/test/integration/sync_test.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
+
+using bookmarks_helper::AddURL;
+
+const char kValidOAuth2Token[] = "{"
+ " \"refresh_token\": \"rt1\","
+ " \"access_token\": \"at1\","
+ " \"expires_in\": 3600," // 1 hour.
+ " \"token_type\": \"Bearer\""
+ "}";
+
+const char kInvalidOAuth2Token[] = "{"
+ " \"error\": \"invalid_grant\""
+ "}";
+
+class SyncAuthTest : public SyncTest {
+ public:
+ SyncAuthTest() : SyncTest(SINGLE_CLIENT) {}
+ virtual ~SyncAuthTest() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyncAuthTest);
+};
+
+IN_PROC_BROWSER_TEST_F(SyncAuthTest, Sanity) {
+ ASSERT_TRUE(SetupSync());
+
+ TriggerAuthState(AUTHENTICATED_TRUE);
+ SetOAuth2TokenResponse(kValidOAuth2Token, net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+
+ ASSERT_TRUE(AddURL(0, L"Bookmark 1", GURL("http://www.foo1.com")) != NULL);
+ ASSERT_TRUE(GetClient(0)->AwaitFullSyncCompletion("Added a bookmark."));
+
+ TriggerAuthState(AUTHENTICATED_FALSE);
+ SetOAuth2TokenResponse(kInvalidOAuth2Token, net::HTTP_BAD_REQUEST,
+ net::URLRequestStatus::SUCCESS);
+
+ ASSERT_TRUE(AddURL(0, L"Bookmark 2", GURL("http://www.foo2.com")) != NULL);
+ ASSERT_FALSE(GetClient(0)->AwaitFullSyncCompletion("Added second bookmark."));
+ ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
+ GetClient(0)->service()->GetAuthError().state());
+}
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc
index 698f18d..d093d54 100644
--- a/chrome/browser/sync/test/integration/sync_errors_test.cc
+++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -140,42 +140,6 @@ IN_PROC_BROWSER_TEST_F(SyncErrorTest,
protocol_error.error_description);
}
-// TODO(pavely): Fix this test. Test needs to successfully setup sync. Then
-// setup server to trigger auth error and setup FakeURLFetcher to return
-// INVALID_CREDENTIALS failure for access token request. Then it should
-// trigger sync and verify that error surfaced through
-// ProfileSyncService::GetAuthError()
-//
-// Trigger an auth error and make sure the sync client displays a warning in the
-// UI.
-IN_PROC_BROWSER_TEST_F(SyncErrorTest, DISABLED_AuthErrorTest) {
- ASSERT_TRUE(SetupClients());
- TriggerAuthError();
-
- ASSERT_FALSE(GetClient(0)->SetupSync());
- ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
- GetClient(0)->service()->GetAuthError().state());
-}
-
-// TODO(pavely): Fix this test. Test needs to successfully setup sync. Then
-// setup server to trigger xmpp auth error and setup FakeURLFetcher to return
-// INVALID_CREDENTIALS failure for access token request. Then it should
-// trigger sync and verify that error surfaced through
-// ProfileSyncService::GetAuthError()
-//
-// Trigger an XMPP auth error, and make sure sync treats it like any
-// other auth error.
-IN_PROC_BROWSER_TEST_F(SyncErrorTest, DISABLED_XmppAuthErrorTest) {
- ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
-
- TriggerXmppAuthError();
-
- ASSERT_FALSE(GetClient(0)->SetupSync());
-
- ASSERT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
- GetClient(0)->service()->GetAuthError().state());
-}
-
// TODO(lipalani): Fix the typed_url dtc so this test case can pass.
IN_PROC_BROWSER_TEST_F(SyncErrorTest, DISABLED_DisableDatatypeWhileRunning) {
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index be97945..4ca0158 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -48,7 +48,6 @@
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/base/network_change_notifier.h"
-#include "net/http/http_status_code.h"
#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_service.h"
@@ -58,7 +57,6 @@
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
#include "sync/engine/sync_scheduler_impl.h"
#include "sync/notifier/p2p_invalidator.h"
#include "sync/protocol/sync.pb.h"
@@ -141,7 +139,8 @@ void SyncTest::SetUp() {
username_ = cl->GetSwitchValueASCII(switches::kSyncUserForTest);
password_ = cl->GetSwitchValueASCII(switches::kSyncPasswordForTest);
} else {
- SetupMockGaiaResponses();
+ username_ = "user@gmail.com";
+ password_ = "password";
}
if (!cl->HasSwitch(switches::kSyncServiceURL) &&
@@ -178,6 +177,11 @@ void SyncTest::SetUp() {
Encryptor::UseMockKeychain(true);
#endif
+ // Start up a sync test server if one is needed and setup mock gaia responses.
+ // Note: This must be done prior to the call to SetupClients() because we want
+ // the mock gaia responses to be available before GaiaUrls is initialized.
+ SetUpTestServerIfRequired();
+
// Yield control back to the InProcessBrowserTest framework.
InProcessBrowserTest::SetUp();
}
@@ -274,9 +278,6 @@ bool SyncTest::SetupClients() {
if (!profiles_.empty() || !browsers_.empty() || !clients_.empty())
LOG(FATAL) << "SetupClients() has already been called.";
- // Start up a sync test server if one is needed.
- SetUpTestServerIfRequired();
-
// Create the required number of sync profiles, browsers and clients.
profiles_.resize(num_clients_);
browsers_.resize(num_clients_);
@@ -423,16 +424,9 @@ void SyncTest::ReadPasswordFile() {
}
void SyncTest::SetupMockGaiaResponses() {
- username_ = "user@gmail.com";
- password_ = "password";
factory_.reset(new net::URLFetcherImplFactory());
fake_factory_.reset(new net::FakeURLFetcherFactory(factory_.get()));
fake_factory_->SetFakeResponse(
- GaiaUrls::GetInstance()->client_login_url(),
- "SID=sid\nLSID=lsid",
- net::HTTP_OK,
- net::URLRequestStatus::SUCCESS);
- fake_factory_->SetFakeResponse(
GaiaUrls::GetInstance()->get_user_info_url(),
"email=user@gmail.com\ndisplayEmail=user@gmail.com",
net::HTTP_OK,
@@ -469,6 +463,14 @@ void SyncTest::SetupMockGaiaResponses() {
net::URLRequestStatus::SUCCESS);
}
+void SyncTest::SetOAuth2TokenResponse(const std::string& response_data,
+ net::HttpStatusCode response_code,
+ net::URLRequestStatus::Status status) {
+ ASSERT_TRUE(NULL != fake_factory_.get());
+ fake_factory_->SetFakeResponse(GaiaUrls::GetInstance()->oauth2_token_url(),
+ response_data, response_code, status);
+}
+
void SyncTest::ClearMockGaiaResponses() {
// Clear any mock gaia responses that might have been set.
if (fake_factory_) {
@@ -488,6 +490,7 @@ void SyncTest::SetUpTestServerIfRequired() {
if (server_type_ == LOCAL_PYTHON_SERVER) {
if (!SetUpLocalPythonTestServer())
LOG(FATAL) << "Failed to set up local python sync and XMPP servers";
+ SetupMockGaiaResponses();
} else if (server_type_ == LOCAL_LIVE_SERVER) {
// Using mock gaia credentials requires the use of a mock XMPP server.
if (username_ == "user@gmail.com" && !SetUpLocalPythonTestServer())
@@ -738,9 +741,11 @@ void SyncTest::TriggerTransientError() {
GetTitle()));
}
-void SyncTest::TriggerAuthError() {
+void SyncTest::TriggerAuthState(PythonServerAuthState auth_state) {
ASSERT_TRUE(ServerSupportsErrorTriggering());
std::string path = "chromiumsync/cred";
+ path.append(auth_state == AUTHENTICATED_TRUE ? "?valid=True" :
+ "?valid=False");
ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
}
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index 0aae307..7a80b28 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -14,6 +14,8 @@
#include "base/memory/scoped_vector.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_status.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/protocol/sync_protocol_error.h"
#include "sync/test/local_sync_test_server.h"
@@ -80,6 +82,15 @@ class SyncTest : public InProcessBrowserTest {
ERROR_FREQUENCY_TWO_THIRDS
};
+ // Authentication state used by the python sync server.
+ enum PythonServerAuthState {
+ // Python server processes sync requests normally.
+ AUTHENTICATED_TRUE,
+
+ // Python server responds to sync requests with an authentication error.
+ AUTHENTICATED_FALSE
+ };
+
// A SyncTest must be associated with a particular test type.
explicit SyncTest(TestType test_type);
@@ -162,6 +173,12 @@ class SyncTest : public InProcessBrowserTest {
// only if ServerSupportsNotificationControl() returned true.
void EnableNotifications();
+ // Sets the mock gaia response for when an OAuth2 token is requested.
+ // Each call to this method will overwrite responses that were previously set.
+ void SetOAuth2TokenResponse(const std::string& response_data,
+ net::HttpStatusCode response_code,
+ net::URLRequestStatus::Status status);
+
// Trigger a notification to be sent to all clients. This operation
// is available only if ServerSupportsNotificationControl() returned
// true.
@@ -183,10 +200,11 @@ class SyncTest : public InProcessBrowserTest {
// this state until shut down.
void TriggerTransientError();
- // Triggers an auth error on the server, simulating the case when the gaia
- // password is changed at another location. Note the server will stay in
- // this state until shut down.
- void TriggerAuthError();
+ // Sets / unsets an auth error on the server. Can be used to simulate the case
+ // when the user's gaia password is changed at another location, or their
+ // OAuth2 tokens have expired. The server will stay in this state until
+ // this method is called with a different value.
+ void TriggerAuthState(PythonServerAuthState auth_state);
// Triggers an XMPP auth error on the server. Note the server will
// stay in this state until shut down.
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 0df22e2..6d764f7 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2386,6 +2386,7 @@
'browser/sync/test/integration/single_client_typed_urls_sync_test.cc',
'browser/sync/test/integration/sync_app_helper.cc',
'browser/sync/test/integration/sync_app_helper.h',
+ 'browser/sync/test/integration/sync_auth_test.cc',
'browser/sync/test/integration/sync_datatype_helper.cc',
'browser/sync/test/integration/sync_datatype_helper.h',
'browser/sync/test/integration/sync_errors_test.cc',