Chromium Code Reviews| Index: chrome/browser/chromeos/login/parallel_authenticator_unittest.cc |
| diff --git a/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5595b2d43df299facacb8a3361338798e6aa2a75 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc |
| @@ -0,0 +1,662 @@ |
| +// Copyright (c) 2010 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 "chrome/browser/chromeos/login/parallel_authenticator.h" |
| + |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/file_path.h" |
| +#include "base/file_util.h" |
| +#include "base/message_loop.h" |
| +#include "base/path_service.h" |
| +#include "base/scoped_ptr.h" |
| +#include "base/string_util.h" |
| +#include "base/stringprintf.h" |
| +#include "chrome/browser/chrome_thread.h" |
| +#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" |
| +#include "chrome/browser/chromeos/cros/mock_library_loader.h" |
| +#include "chrome/browser/chromeos/login/mock_auth_response_handler.h" |
| +#include "chrome/browser/chromeos/login/mock_login_status_consumer.h" |
| +#include "chrome/browser/chromeos/login/mock_url_fetchers.h" |
| +#include "chrome/browser/chromeos/login/test_attempt_state.h" |
| +#include "chrome/common/chrome_paths.h" |
| +#include "chrome/common/net/gaia/gaia_authenticator2_unittest.h" |
| +#include "chrome/common/net/url_fetcher.h" |
| +#include "chrome/test/testing_profile.h" |
| +#include "googleurl/src/gurl.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/url_request/url_request_status.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +using namespace file_util; |
| +using ::testing::AnyNumber; |
| +using ::testing::DoAll; |
| +using ::testing::Invoke; |
| +using ::testing::Return; |
| +using ::testing::SetArgumentPointee; |
| +using ::testing::_; |
| + |
| +namespace chromeos { |
| + |
| +class ParallelAuthenticatorTest : public ::testing::Test { |
| + public: |
| + ParallelAuthenticatorTest() |
| + : message_loop_(MessageLoop::TYPE_UI), |
| + ui_thread_(ChromeThread::UI, &message_loop_), |
| + file_thread_(ChromeThread::FILE), |
| + io_thread_(ChromeThread::IO), |
| + username_("me@nowhere.org") { |
| + hash_ascii_.assign("0a010000000000a0"); |
| + hash_ascii_.append(std::string(16, '0')); |
| + } |
| + |
| + ~ParallelAuthenticatorTest() {} |
| + |
| + virtual void SetUp() { |
| + chromeos::CrosLibrary::TestApi* test_api = |
| + chromeos::CrosLibrary::Get()->GetTestApi(); |
| + |
| + loader_ = new MockLibraryLoader(); |
| + ON_CALL(*loader_, Load(_)) |
| + .WillByDefault(Return(true)); |
| + EXPECT_CALL(*loader_, Load(_)) |
| + .Times(AnyNumber()); |
| + |
| + test_api->SetLibraryLoader(loader_, true); |
| + |
| + mock_library_ = new MockCryptohomeLibrary(); |
| + test_api->SetCryptohomeLibrary(mock_library_, true); |
| + file_thread_.Start(); |
| + io_thread_.Start(); |
| + |
| + auth_ = new ParallelAuthenticator(&consumer_); |
| + state_ = new TestAttemptState(username_, "", hash_ascii_, "", ""); |
| + } |
| + |
| + // Tears down the test fixture. |
| + virtual void TearDown() { |
| + // Prevent bogus gMock leak check from firing. |
| + chromeos::CrosLibrary::TestApi* test_api = |
| + chromeos::CrosLibrary::Get()->GetTestApi(); |
| + test_api->SetLibraryLoader(NULL, false); |
| + test_api->SetCryptohomeLibrary(NULL, false); |
| + } |
| + |
| + FilePath PopulateTempFile(const char* data, int data_len) { |
| + FilePath out; |
| + FILE* tmp_file = CreateAndOpenTemporaryFile(&out); |
| + EXPECT_NE(tmp_file, reinterpret_cast<FILE*>(NULL)); |
| + EXPECT_EQ(WriteFile(out, data, data_len), data_len); |
| + EXPECT_TRUE(CloseFile(tmp_file)); |
| + return out; |
| + } |
| + |
| + FilePath FakeLocalaccountFile(const std::string& ascii) { |
| + FilePath exe_dir; |
| + FilePath local_account_file; |
| + PathService::Get(base::DIR_EXE, &exe_dir); |
| + FILE* tmp_file = CreateAndOpenTemporaryFileInDir(exe_dir, |
| + &local_account_file); |
| + int ascii_len = ascii.length(); |
| + EXPECT_NE(tmp_file, reinterpret_cast<FILE*>(NULL)); |
| + EXPECT_EQ(WriteFile(local_account_file, ascii.c_str(), ascii_len), |
| + ascii_len); |
| + EXPECT_TRUE(CloseFile(tmp_file)); |
| + return local_account_file; |
| + } |
| + |
| + void ReadLocalaccountFile(ParallelAuthenticator* auth, |
| + const std::string& filename) { |
| + ChromeThread::PostTask( |
| + ChromeThread::FILE, FROM_HERE, |
| + NewRunnableMethod(auth, |
| + &ParallelAuthenticator::LoadLocalaccount, |
| + filename)); |
| + file_thread_.Stop(); |
| + file_thread_.Start(); |
| + } |
| + |
| + // Allow test to fail and exit gracefully, even if OnLoginFailure() |
| + // wasn't supposed to happen. |
| + void FailOnLoginFailure() { |
| + ON_CALL(consumer_, OnLoginFailure(_)) |
| + .WillByDefault(Invoke(MockConsumer::OnFailQuitAndFail)); |
| + } |
| + |
| + // Allow test to fail and exit gracefully, even if OnLoginSuccess() |
| + // wasn't supposed to happen. |
| + void FailOnLoginSuccess() { |
| + ON_CALL(consumer_, OnLoginSuccess(_, _, _)) |
| + .WillByDefault(Invoke(MockConsumer::OnSuccessQuitAndFail)); |
| + } |
| + |
| + // Allow test to fail and exit gracefully, even if |
| + // OnOffTheRecordLoginSuccess() wasn't supposed to happen. |
| + void FailOnGuestLoginSuccess() { |
| + ON_CALL(consumer_, OnOffTheRecordLoginSuccess()) |
| + .WillByDefault(Invoke(MockConsumer::OnGuestSuccessQuitAndFail)); |
| + } |
| + |
| + void ExpectLoginFailure(const LoginFailure& failure) { |
| + EXPECT_CALL(consumer_, OnLoginFailure(failure)) |
| + .WillOnce(Invoke(MockConsumer::OnFailQuit)) |
| + .RetiresOnSaturation(); |
| + } |
| + |
| + void ExpectLoginSuccess(const std::string& username, |
| + const GaiaAuthConsumer::ClientLoginResult& result, |
| + bool pending) { |
| + EXPECT_CALL(consumer_, OnLoginSuccess(username, result, pending)) |
| + .WillOnce(Invoke(MockConsumer::OnSuccessQuit)) |
| + .RetiresOnSaturation(); |
| + } |
| + |
| + void ExpectGuestLoginSuccess() { |
| + EXPECT_CALL(consumer_, OnOffTheRecordLoginSuccess()) |
| + .WillOnce(Invoke(MockConsumer::OnGuestSuccessQuit)) |
| + .RetiresOnSaturation(); |
| + } |
| + |
| + void ExpectPasswordChange() { |
| + EXPECT_CALL(consumer_, OnPasswordChangeDetected(result_)) |
| + .WillOnce(Invoke(MockConsumer::OnMigrateQuit)) |
| + .RetiresOnSaturation(); |
| + } |
| + |
| + void RunResolve(ParallelAuthenticator* auth, MessageLoop* loop) { |
| + ChromeThread::PostTask( |
| + ChromeThread::IO, FROM_HERE, |
| + NewRunnableMethod(auth, &ParallelAuthenticator::Resolve)); |
| + loop->Run(); |
| + } |
| + |
| + void SetAttemptState(ParallelAuthenticator* auth, TestAttemptState* state) { |
| + auth->set_attempt_state(state); |
| + } |
| + |
| + static void CheckResolve(TestAttemptState* state, |
| + ParallelAuthenticator* auth, |
| + ParallelAuthenticator::AuthState expected) { |
| + auth->set_attempt_state(state); |
| + EXPECT_EQ(expected, auth->ResolveState()); |
| + } |
| + |
| + MessageLoop message_loop_; |
| + ChromeThread ui_thread_; |
| + ChromeThread file_thread_; |
| + ChromeThread io_thread_; |
| + |
| + std::string username_; |
| + std::string hash_ascii_; |
| + GaiaAuthConsumer::ClientLoginResult result_; |
| + |
| + // Mocks, destroyed by CrosLibrary class. |
| + MockCryptohomeLibrary* mock_library_; |
| + MockLibraryLoader* loader_; |
| + |
| + MockConsumer consumer_; |
| + scoped_refptr<ParallelAuthenticator> auth_; |
| + TestAttemptState* state_; |
| +}; |
| + |
| +TEST_F(ParallelAuthenticatorTest, SaltToAscii) { |
| + unsigned char fake_salt[8] = { 0 }; |
| + fake_salt[0] = 10; |
| + fake_salt[1] = 1; |
| + fake_salt[7] = 10 << 4; |
| + std::vector<unsigned char> salt_v(fake_salt, fake_salt + sizeof(fake_salt)); |
| + |
| + ON_CALL(*mock_library_, GetSystemSalt()) |
| + .WillByDefault(Return(salt_v)); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + EXPECT_EQ("0a010000000000a0", auth_->SaltAsAscii()); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ReadLocalaccount) { |
| + FilePath tmp_file_path = FakeLocalaccountFile(username_); |
| + |
| + ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); |
| + EXPECT_EQ(auth_->localaccount_, username_); |
| + Delete(tmp_file_path, false); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ReadLocalaccountTrailingWS) { |
| + FilePath tmp_file_path = |
| + FakeLocalaccountFile(base::StringPrintf("%s\n", username_.c_str())); |
| + |
| + ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); |
| + EXPECT_EQ(auth_->localaccount_, username_); |
| + Delete(tmp_file_path, false); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ReadNoLocalaccount) { |
| + FilePath tmp_file_path = FakeLocalaccountFile(username_); |
| + EXPECT_TRUE(Delete(tmp_file_path, false)); // Ensure non-existent file. |
| + |
| + ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); |
| + EXPECT_EQ(auth_->localaccount_, std::string()); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, OnLoginSuccess) { |
| + EXPECT_CALL(consumer_, OnLoginSuccess(username_, result_, false)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + SetAttemptState(auth_, state_); |
| + auth_->OnLoginSuccess(result_, false); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, OnPasswordChangeDetected) { |
| + EXPECT_CALL(consumer_, OnPasswordChangeDetected(result_)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + SetAttemptState(auth_, state_); |
| + auth_->OnPasswordChangeDetected(result_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ResolveNothingDone) { |
| + ChromeThread::PostTask( |
| + ChromeThread::IO, FROM_HERE, |
| + NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, |
| + state_, |
| + auth_.get(), |
| + ParallelAuthenticator::CONTINUE)); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ResolvePossiblePwChange) { |
| + // Set up state as though a cryptohome mount attempt has occurred |
| + // and been rejected. |
| + state_->PresetCryptohomeStatus(false, |
| + chromeos::kCryptohomeMountErrorKeyFailure); |
| + ChromeThread::PostTask( |
| + ChromeThread::IO, FROM_HERE, |
| + NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, |
| + state_, |
| + auth_.get(), |
| + ParallelAuthenticator::POSSIBLE_PW_CHANGE)); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveFailedMount) { |
| + FailOnLoginSuccess(); |
| + ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME)); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred |
| + // and failed. |
| + state_->PresetCryptohomeStatus(false, 0); |
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveGuestLogin) { |
| + ExpectGuestLoginSuccess(); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond as though a tmpfs mount |
| + // attempt has occurred and succeeded. |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + auth_->LoginOffTheRecord(); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveGuestLoginButFail) { |
| + FailOnGuestLoginSuccess(); |
| + ExpectLoginFailure(LoginFailure(LoginFailure::COULD_NOT_MOUNT_TMPFS)); |
| + |
| + // Set up mock cryptohome library to respond as though a tmpfs mount |
| + // attempt has occurred and failed. |
| + mock_library_->SetUp(false, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + auth_->LoginOffTheRecord(); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveDataResync) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond successfully to a cryptohome |
| + // remove attempt and a cryptohome create attempt (specified by the |true| |
| + // argument to AsyncMount). |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncRemove(username_, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, true, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); |
| + SetAttemptState(auth_, state_); |
| + |
| + auth_->ResyncEncryptedData(result_); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveResyncFail) { |
| + FailOnLoginSuccess(); |
| + ExpectLoginFailure(LoginFailure(LoginFailure::DATA_REMOVAL_FAILED)); |
| + |
| + // Set up mock cryptohome library to fail a cryptohome remove attempt. |
| + mock_library_->SetUp(false, 0); |
| + EXPECT_CALL(*mock_library_, AsyncRemove(username_, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + SetAttemptState(auth_, state_); |
| + |
| + auth_->ResyncEncryptedData(result_); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveRequestOldPassword) { |
| + FailOnLoginSuccess(); |
| + ExpectPasswordChange(); |
| + |
| + state_->PresetCryptohomeStatus(false, |
| + chromeos::kCryptohomeMountErrorKeyFailure); |
|
Nikita (slow)
2010/10/07 22:43:06
nit: indent
|
| + state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); |
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveDataRecover) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond successfully to a key migration. |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, hash_ascii_, _)) |
|
Nikita (slow)
2010/10/07 22:43:06
It's possible to test correct sequence of calls to
|
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, false, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .WillOnce(Return(CryptohomeBlob(2, 0))) |
| + .RetiresOnSaturation(); |
| + |
| + state_->PresetOnlineLoginStatus(result_, LoginFailure::None()); |
| + SetAttemptState(auth_, state_); |
| + |
| + auth_->RecoverEncryptedData(std::string(), result_); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveDataRecoverButFail) { |
| + FailOnLoginSuccess(); |
| + ExpectPasswordChange(); |
| + |
| + // Set up mock cryptohome library to fail a key migration attempt, |
| + // asserting that the wrong password was used. |
| + mock_library_->SetUp(false, chromeos::kCryptohomeMountErrorKeyFailure); |
| + EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, hash_ascii_, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .WillOnce(Return(CryptohomeBlob(2, 0))) |
| + .RetiresOnSaturation(); |
| + |
| + SetAttemptState(auth_, state_); |
| + |
| + auth_->RecoverEncryptedData(std::string(), result_); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ResolveNoMount) { |
| + // Set up state as though a cryptohome mount attempt has occurred |
| + // and been rejected because the user doesn't exist. |
| + state_->PresetCryptohomeStatus( |
| + false, |
| + chromeos::kCryptohomeMountErrorUserDoesNotExist); |
| + |
| + ChromeThread::PostTask( |
| + ChromeThread::IO, FROM_HERE, |
| + NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, |
| + state_, |
| + auth_.get(), |
| + ParallelAuthenticator::NO_MOUNT)); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, ResolveCreateNew) { |
| + // Set up state as though a cryptohome mount attempt has occurred |
| + // and been rejected because the user doesn't exist; additionally, |
| + // an online auth attempt has completed successfully. |
| + state_->PresetCryptohomeStatus( |
| + false, |
| + chromeos::kCryptohomeMountErrorUserDoesNotExist); |
| + state_->PresetOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), |
| + LoginFailure::None()); |
|
Nikita (slow)
2010/10/07 22:43:06
nit: indent
|
| + |
| + ChromeThread::PostTask( |
| + ChromeThread::IO, FROM_HERE, |
| + NewRunnableFunction(&ParallelAuthenticatorTest::CheckResolve, |
| + state_, |
| + auth_.get(), |
| + ParallelAuthenticator::CREATE_NEW)); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveCreateForNewUser) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond successfully to a cryptohome |
| + // create attempt (specified by the |true| argument to AsyncMount). |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMount(username_, hash_ascii_, true, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred |
| + // and been rejected because the user doesn't exist; additionally, |
| + // an online auth attempt has completed successfully. |
| + state_->PresetCryptohomeStatus( |
| + false, |
| + chromeos::kCryptohomeMountErrorUserDoesNotExist); |
| + state_->PresetOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), |
| + LoginFailure::None()); |
|
Nikita (slow)
2010/10/07 22:43:06
nit: indent
|
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveOfflineLogin) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred and |
| + // succeeded. |
| + state_->PresetCryptohomeStatus(true, 0); |
| + GoogleServiceAuthError error = |
| + GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET); |
| + state_->PresetOnlineLoginStatus(result_, |
| + LoginFailure::FromNetworkAuthFailure(error)); |
|
Nikita (slow)
2010/10/07 22:43:06
nit: indent
|
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginDelayedOnline) { |
| + ExpectLoginSuccess(username_, result_, true); |
| + FailOnLoginFailure(); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred and |
| + // succeeded. |
| + state_->PresetCryptohomeStatus(true, 0); |
| + SetAttemptState(auth_, state_); |
| + RunResolve(auth_.get(), &message_loop_); |
| + |
| + // Offline login has completed, so now we "complete" the online request. |
| + GoogleServiceAuthError error( |
| + GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| + LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); |
| + state_->PresetOnlineLoginStatus(result_, failure); |
| + ExpectLoginFailure(failure); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveOfflineLoginGetNewPassword) { |
| + ExpectLoginSuccess(username_, result_, true); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond successfully to a key migration. |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMigrateKey(username_, _, _, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .WillOnce(Return(CryptohomeBlob(2, 0))) |
| + .RetiresOnSaturation(); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred and |
| + // succeeded; also, an online request that never made it. |
| + state_->PresetCryptohomeStatus(true, 0); |
| + SetAttemptState(auth_, state_); |
| + RunResolve(auth_.get(), &message_loop_); |
| + |
| + // Offline login has completed, so now we "complete" the online request. |
| + GoogleServiceAuthError error( |
| + GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| + LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); |
| + state_->PresetOnlineLoginStatus(result_, failure); |
| + ExpectLoginFailure(failure); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| + |
| + // After the request below completes, OnLoginSuccess gets called again. |
| + ExpectLoginSuccess(username_, result_, false); |
| + |
| + MockFactory<SuccessFetcher> factory; |
| + URLFetcher::set_factory(&factory); |
| + TestingProfile profile; |
| + |
| + auth_->RetryAuth(&profile, |
|
Nikita (slow)
2010/10/07 22:43:06
I'd add here another failure and then finally Logi
Chris Masone
2010/10/07 22:45:37
As in, do a RetryAuth, make it fail, do another on
|
| + username_, |
| + std::string(), |
| + std::string(), |
| + std::string()); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveOnlineLogin) { |
| + GaiaAuthConsumer::ClientLoginResult success("sid", "lsid", "", ""); |
| + ExpectLoginSuccess(username_, success, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred and |
| + // succeeded. |
| + state_->PresetCryptohomeStatus(true, 0); |
| + state_->PresetOnlineLoginStatus(success, LoginFailure::None()); |
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveNeedNewPassword) { |
| + FailOnLoginSuccess(); // Set failing on success as the default... |
| + // ...but expect ONE successful login first. |
| + ExpectLoginSuccess(username_, result_, true); |
| + GoogleServiceAuthError error( |
| + GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| + LoginFailure failure = LoginFailure::FromNetworkAuthFailure(error); |
| + ExpectLoginFailure(failure); |
| + |
| + // Set up state as though a cryptohome mount attempt has occurred and |
| + // succeeded. |
| + state_->PresetCryptohomeStatus(true, 0); |
| + state_->PresetOnlineLoginStatus(result_, failure); |
| + SetAttemptState(auth_, state_); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveLocalLogin) { |
| + ExpectGuestLoginSuccess(); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond as though a tmpfs mount |
| + // attempt has occurred and succeeded. |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncMountForBwsi(_)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + |
| + // Pre-set test state as though an online login attempt failed to complete, |
| + // and that a cryptohome mount attempt failed because the user doesn't exist. |
| + GoogleServiceAuthError error = |
| + GoogleServiceAuthError::FromConnectionError(net::ERR_CONNECTION_RESET); |
| + LoginFailure failure = |
| + LoginFailure::FromNetworkAuthFailure(error); |
| + state_->PresetOnlineLoginStatus(result_, failure); |
| + state_->PresetCryptohomeStatus( |
| + false, |
| + chromeos::kCryptohomeMountErrorUserDoesNotExist); |
| + SetAttemptState(auth_, state_); |
| + |
| + // Deal with getting the localaccount file |
| + FilePath tmp_file_path = FakeLocalaccountFile(username_); |
| + ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); |
| + |
| + RunResolve(auth_.get(), &message_loop_); |
| + |
| + Delete(tmp_file_path, false); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveUnlock) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to respond successfully to a cryptohome |
| + // key-check attempt. |
| + mock_library_->SetUp(true, 0); |
| + EXPECT_CALL(*mock_library_, AsyncCheckKey(username_, _, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .WillOnce(Return(CryptohomeBlob(2, 0))) |
| + .RetiresOnSaturation(); |
| + |
| + auth_->AuthenticateToUnlock(username_, ""); |
| + message_loop_.Run(); |
| +} |
| + |
| +TEST_F(ParallelAuthenticatorTest, DriveLocalUnlock) { |
| + ExpectLoginSuccess(username_, result_, false); |
| + FailOnLoginFailure(); |
| + |
| + // Set up mock cryptohome library to fail a cryptohome key-check |
| + // attempt. |
| + mock_library_->SetUp(false, 0); |
| + EXPECT_CALL(*mock_library_, AsyncCheckKey(username_, _, _)) |
| + .Times(1) |
| + .RetiresOnSaturation(); |
| + EXPECT_CALL(*mock_library_, GetSystemSalt()) |
| + .WillOnce(Return(CryptohomeBlob(2, 0))) |
| + .RetiresOnSaturation(); |
| + |
| + // Deal with getting the localaccount file |
| + FilePath tmp_file_path = FakeLocalaccountFile(username_); |
| + ReadLocalaccountFile(auth_.get(), tmp_file_path.BaseName().value()); |
| + |
| + auth_->AuthenticateToUnlock(username_, ""); |
| + message_loop_.Run(); |
| + |
| + Delete(tmp_file_path, false); |
| +} |
| + |
| +} // namespace chromeos |