| Index: chrome/browser/chromeos/login/cryptohome_op_unittest.cc
|
| diff --git a/chrome/browser/chromeos/login/cryptohome_op_unittest.cc b/chrome/browser/chromeos/login/cryptohome_op_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..36a4bf2f6c8321a13f4ff57f2f0c7c025d196da4
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/login/cryptohome_op_unittest.cc
|
| @@ -0,0 +1,226 @@
|
| +// 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/cryptohome_op.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/message_loop.h"
|
| +#include "base/ref_counted.h"
|
| +#include "chrome/browser/chrome_thread.h"
|
| +#include "chrome/browser/chromeos/cros/mock_library_loader.h"
|
| +#include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
|
| +#include "chrome/browser/chromeos/login/auth_attempt_state.h"
|
| +#include "chrome/browser/chromeos/login/mock_auth_attempt_state_resolver.h"
|
| +#include "chrome/browser/chromeos/login/test_attempt_state.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using ::testing::AnyNumber;
|
| +using ::testing::Invoke;
|
| +using ::testing::Return;
|
| +using ::testing::_;
|
| +
|
| +namespace chromeos {
|
| +
|
| +class CryptohomeOpTest : public ::testing::Test {
|
| + public:
|
| + CryptohomeOpTest()
|
| + : message_loop_(MessageLoop::TYPE_UI),
|
| + ui_thread_(ChromeThread::UI, &message_loop_),
|
| + io_thread_(ChromeThread::IO),
|
| + username_("me@nowhere.org"),
|
| + hash_ascii_("0a010000000000a0"),
|
| + state_(username_, "", hash_ascii_, "", ""),
|
| + resolver_(new MockAuthAttemptStateResolver),
|
| + mock_library_(new MockCryptohomeLibrary) {
|
| + }
|
| +
|
| + virtual ~CryptohomeOpTest() {}
|
| +
|
| + virtual void SetUp() {
|
| + CrosLibrary::TestApi* test_api = CrosLibrary::Get()->GetTestApi();
|
| +
|
| + MockLibraryLoader* loader = new MockLibraryLoader();
|
| + ON_CALL(*loader, Load(_))
|
| + .WillByDefault(Return(true));
|
| + EXPECT_CALL(*loader, Load(_))
|
| + .Times(AnyNumber());
|
| +
|
| + // Passes ownership of |loader| to CrosLibrary.
|
| + test_api->SetLibraryLoader(loader, true);
|
| + // |mock_library_| is mine, though.
|
| + test_api->SetCryptohomeLibrary(mock_library_.get(), false);
|
| +
|
| + io_thread_.Start();
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + // Prevent bogus gMock leak check from firing.
|
| + chromeos::CrosLibrary::TestApi* test_api =
|
| + chromeos::CrosLibrary::Get()->GetTestApi();
|
| + test_api->SetLibraryLoader(NULL, false);
|
| + }
|
| +
|
| + void ExpectMigrate(bool passing_old_hash, const std::string& hash) {
|
| + if (passing_old_hash) {
|
| + EXPECT_CALL(*(mock_library_.get()), AsyncMigrateKey(username_,
|
| + hash,
|
| + hash_ascii_,
|
| + _))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + } else {
|
| + EXPECT_CALL(*(mock_library_.get()), AsyncMigrateKey(username_,
|
| + hash_ascii_,
|
| + hash,
|
| + _))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + }
|
| + }
|
| +
|
| + void ExpectMount() {
|
| + EXPECT_CALL(*(mock_library_.get()), AsyncMount(username_, hash_ascii_, _))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + }
|
| +
|
| + void ExpectMountGuest() {
|
| + EXPECT_CALL(*(mock_library_.get()), AsyncMountForBwsi(_))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + }
|
| +
|
| + void ExpectRemove() {
|
| + EXPECT_CALL(*(mock_library_.get()), AsyncRemove(username_, _))
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| + }
|
| +
|
| + void RunTest(CryptohomeOp* op) {
|
| + EXPECT_CALL(*(resolver_.get()), Resolve())
|
| + .Times(1)
|
| + .RetiresOnSaturation();
|
| +
|
| + EXPECT_TRUE(op->Initiate());
|
| + // Force IO thread to finish tasks so I can verify |state_|.
|
| + io_thread_.Stop();
|
| + }
|
| +
|
| + void RunMountTest(CryptohomeOp* op, bool outcome, int code) {
|
| + mock_library_->SetAsyncBehavior(outcome, code);
|
| +
|
| + RunTest(op);
|
| +
|
| + EXPECT_EQ(outcome, state_.offline_outcome());
|
| + EXPECT_EQ(code, state_.offline_code());
|
| + }
|
| +
|
| + void RunNonMountTest(CryptohomeOp* op, bool outcome, int code) {
|
| + mock_library_->SetAsyncBehavior(outcome, code);
|
| +
|
| + RunTest(op);
|
| +
|
| + if (outcome) {
|
| + EXPECT_EQ(false, state_.offline_complete());
|
| + EXPECT_EQ(false, state_.offline_outcome());
|
| + EXPECT_EQ(kCryptohomeMountErrorNone, state_.offline_code());
|
| + } else {
|
| + EXPECT_EQ(true, state_.offline_complete());
|
| + EXPECT_EQ(outcome, state_.offline_outcome());
|
| + EXPECT_EQ(code, state_.offline_code());
|
| + }
|
| + }
|
| +
|
| + MessageLoop message_loop_;
|
| + ChromeThread ui_thread_;
|
| + ChromeThread io_thread_;
|
| + std::string username_;
|
| + std::string hash_ascii_;
|
| + TestAttemptState state_;
|
| + scoped_ptr<MockAuthAttemptStateResolver> resolver_;
|
| + scoped_refptr<CryptohomeOp> op_;
|
| + scoped_ptr<MockCryptohomeLibrary> mock_library_;
|
| +
|
| +};
|
| +
|
| +TEST_F(CryptohomeOpTest, MountSuccess) {
|
| + ExpectMount();
|
| + scoped_refptr<CryptohomeOp> op(new MountAttempt(&state_, resolver_.get()));
|
| + RunMountTest(op.get(), true, kCryptohomeMountErrorNone);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MountFatal) {
|
| + ExpectMount();
|
| + scoped_refptr<CryptohomeOp> op(new MountAttempt(&state_, resolver_.get()));
|
| + RunMountTest(op.get(), false, kCryptohomeMountErrorFatal);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MountKeyFailure) {
|
| + ExpectMount();
|
| + scoped_refptr<CryptohomeOp> op(new MountAttempt(&state_, resolver_.get()));
|
| + RunMountTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MountRecreated) {
|
| + ExpectMount();
|
| + scoped_refptr<CryptohomeOp> op(new MountAttempt(&state_, resolver_.get()));
|
| + RunMountTest(op.get(), true, kCryptohomeMountErrorRecreated);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MountGuestSuccess) {
|
| + ExpectMountGuest();
|
| + scoped_refptr<CryptohomeOp> op(new MountGuestAttempt(&state_,
|
| + resolver_.get()));
|
| + RunMountTest(op.get(), true, kCryptohomeMountErrorNone);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MountGuestFatal) {
|
| + ExpectMountGuest();
|
| + scoped_refptr<CryptohomeOp> op(new MountGuestAttempt(&state_,
|
| + resolver_.get()));
|
| + RunMountTest(op.get(), false, kCryptohomeMountErrorFatal);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MigrateSuccessPassOld) {
|
| + ExpectMigrate(true, "");
|
| + scoped_refptr<CryptohomeOp> op(new MigrateAttempt(&state_,
|
| + resolver_.get(),
|
| + true,
|
| + ""));
|
| + RunNonMountTest(op.get(), true, kCryptohomeMountErrorNone);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MigrateSuccessPassNew) {
|
| + ExpectMigrate(false, "");
|
| + scoped_refptr<CryptohomeOp> op(new MigrateAttempt(&state_,
|
| + resolver_.get(),
|
| + false,
|
| + ""));
|
| + RunNonMountTest(op.get(), true, kCryptohomeMountErrorNone);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, MigrateKeyFailure) {
|
| + ExpectMigrate(true, "");
|
| + scoped_refptr<CryptohomeOp> op(new MigrateAttempt(&state_,
|
| + resolver_.get(),
|
| + true,
|
| + ""));
|
| + RunNonMountTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, RemoveSuccess) {
|
| + ExpectRemove();
|
| + scoped_refptr<CryptohomeOp> op(new RemoveAttempt(&state_, resolver_.get()));
|
| + RunNonMountTest(op.get(), true, kCryptohomeMountErrorNone);
|
| +}
|
| +
|
| +TEST_F(CryptohomeOpTest, RemoveFailure) {
|
| + ExpectRemove();
|
| + scoped_refptr<CryptohomeOp> op(new RemoveAttempt(&state_, resolver_.get()));
|
| + RunNonMountTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|