Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3622)

Unified Diff: chrome/browser/chromeos/login/owner_manager_unittest.cc

Issue 3058021: OwnerManager, allows use of OwnerKeyUtils to take ownership of a device (Closed)
Patch Set: added a lot of comments per gauravsh Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/login/owner_manager.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/chromeos/login/owner_manager_unittest.cc
diff --git a/chrome/browser/chromeos/login/owner_manager_unittest.cc b/chrome/browser/chromeos/login/owner_manager_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1db81e91d8d2b5ea724a6449b1e6a72b78c8fa3a
--- /dev/null
+++ b/chrome/browser/chromeos/login/owner_manager_unittest.cc
@@ -0,0 +1,352 @@
+// 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/owner_manager.h"
+
+#include <cert.h>
+#include <keyhi.h>
+#include <keythi.h> // KeyType enum
+#include <pk11pub.h>
+#include <stdlib.h>
+
+#include <string>
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/nss_util_internal.h"
+#include "base/nss_util.h"
+#include "base/scoped_temp_dir.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::Return;
+using ::testing::SetArgumentPointee;
+using ::testing::_;
+
+namespace chromeos {
+
+namespace {
+
+class MockKeyUtils : public OwnerKeyUtils {
+ public:
+ MockKeyUtils() {}
+ ~MockKeyUtils() {}
+ MOCK_METHOD2(GenerateKeyPair, bool(SECKEYPrivateKey** private_key_out,
+ SECKEYPublicKey** public_key_out));
+ MOCK_METHOD1(ExportPublicKeyViaDbus, bool(SECKEYPublicKey* key));
+ MOCK_METHOD2(ExportPublicKeyToFile, bool(SECKEYPublicKey* key,
+ const FilePath& key_file));
+ MOCK_METHOD1(ImportPublicKey, SECKEYPublicKey*(const FilePath& key_file));
+ MOCK_METHOD1(FindPrivateKey, SECKEYPrivateKey*(SECKEYPublicKey* key));
+ MOCK_METHOD2(DestroyKeys, void(SECKEYPrivateKey* private_key,
+ SECKEYPublicKey* public_key));
+ MOCK_METHOD0(GetOwnerKeyFilePath, FilePath());
+};
+
+class MockInjector : public OwnerKeyUtils::Factory {
+ public:
+ // Takes ownership of |mock|.
+ explicit MockInjector(MockKeyUtils* mock) :
+ transient_(mock),
+ delete_transient_(true) {
+ }
+
+ virtual ~MockInjector() {
+ if (delete_transient_)
+ delete transient_;
+ }
+
+ // If this is called, its caller takes ownership of |transient_|.
+ // If it's never called, |transient_| remains our problem.
+ OwnerKeyUtils* CreateOwnerKeyUtils() {
+ delete_transient_ = false;
+ return transient_;
+ }
+
+ private:
+ MockKeyUtils* transient_;
+ bool delete_transient_;
+};
+
+class KeyUser : public OwnerManager::Delegate {
+ public:
+ explicit KeyUser(const OwnerManager::KeyOpCode expected)
+ : expected_(expected) {
+ }
+
+ virtual ~KeyUser() {}
+
+ void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
+ const std::string& payload) {
+ MessageLoop::current()->Quit();
+ EXPECT_EQ(expected_, return_code);
+ }
+
+ const OwnerManager::KeyOpCode expected_;
+};
+
+static bool Win(SECKEYPublicKey* key) {
+ MessageLoop::current()->Quit();
+ return true;
+}
+
+static bool Fail(SECKEYPublicKey* key) {
+ MessageLoop::current()->Quit();
+ return false;
+}
+
+} // anonymous namespace
+
+class OwnerManagerTest : public ::testing::Test,
+ public NotificationObserver {
+ public:
+ OwnerManagerTest()
+ : message_loop_(MessageLoop::TYPE_UI),
+ ui_thread_(ChromeThread::UI, &message_loop_),
+ file_thread_(ChromeThread::FILE),
+ fake_public_key_(reinterpret_cast<SECKEYPublicKey*>(7)),
+ fake_private_key_(reinterpret_cast<SECKEYPrivateKey*>(7)),
+ success_expected_(false),
+ quit_on_observe_(true),
+ mock_(new MockKeyUtils),
+ injector_(mock_) /* injector_ takes ownership of mock_ */ {
+ registrar_.Add(
+ this,
+ NotificationType::OWNER_KEY_FETCH_ATTEMPT_COMPLETE,
+ NotificationService::AllSources());
+ }
+ virtual ~OwnerManagerTest() {}
+
+ virtual void SetUp() {
+ // Mimic ownership.
+ ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
+ ASSERT_TRUE(file_util::CreateTemporaryFileInDir(tmpdir_.path(), &tmpfile_));
+
+ file_thread_.Start();
+ OwnerKeyUtils::set_factory(&injector_);
+ }
+
+ virtual void TearDown() {
+ OwnerKeyUtils::set_factory(NULL);
+ }
+
+ void StartUnowned() {
+ file_util::Delete(tmpfile_, false);
+ }
+
+ void InjectKeys(OwnerManager* manager) {
+ manager->public_key_ = fake_public_key_;
+ manager->private_key_ = fake_private_key_;
+ }
+
+ // NotificationObserver implementation.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::OWNER_KEY_FETCH_ATTEMPT_COMPLETE) {
+ EXPECT_EQ(success_expected_,
+ NULL != *Details<SECKEYPublicKey*>(details).ptr());
+ if (quit_on_observe_)
+ MessageLoop::current()->Quit();
+ }
+ }
+
+ void ExpectKeyFetchSuccess(bool should_succeed) {
+ success_expected_ = should_succeed;
+ }
+ void SetQuitOnKeyFetch(bool should_quit) { quit_on_observe_ = should_quit; }
+
+ ScopedTempDir tmpdir_;
+ FilePath tmpfile_;
+
+ MessageLoop message_loop_;
+ ChromeThread ui_thread_;
+ ChromeThread file_thread_;
+
+ SECKEYPublicKey* fake_public_key_;
+ SECKEYPrivateKey* fake_private_key_;
+
+ NotificationRegistrar registrar_;
+ bool success_expected_;
+ bool quit_on_observe_;
+
+ MockKeyUtils* mock_;
+ MockInjector injector_;
+};
+
+TEST_F(OwnerManagerTest, LoadKeyUnowned) {
+ StartUnowned();
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_FALSE(manager->StartLoadOwnerKeyAttempt());
+}
+
+TEST_F(OwnerManagerTest, LoadOwnerKeyFail) {
+ SECKEYPublicKey* to_return = NULL;
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+ EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
+ .WillOnce(Return(to_return))
+ .RetiresOnSaturation();
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_TRUE(manager->StartLoadOwnerKeyAttempt());
+
+ // Run remaining events, until ExportPublicKeyViaDbus().
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, LoadOwnerKey) {
+ ExpectKeyFetchSuccess(true);
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+ EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
+ .WillOnce(Return(fake_public_key_))
+ .RetiresOnSaturation();
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_TRUE(manager->StartLoadOwnerKeyAttempt());
+
+ // Run remaining events, until ExportPublicKeyViaDbus().
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, TakeOwnershipAlreadyOwned) {
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_FALSE(manager->StartTakeOwnershipAttempt());
+}
+
+TEST_F(OwnerManagerTest, KeyGenerationFail) {
+ StartUnowned();
+
+ EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
+ .WillOnce(Return(false))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
+
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, KeyExportFail) {
+ StartUnowned();
+
+ EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
+ .WillOnce(Return(true))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, ExportPublicKeyViaDbus(_))
+ .WillOnce(Invoke(Fail))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, DestroyKeys(_, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
+
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, TakeOwnership) {
+ StartUnowned();
+ ExpectKeyFetchSuccess(true);
+
+ EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
+ Return(true)))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, ExportPublicKeyViaDbus(_))
+ .WillOnce(Invoke(Win))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
+
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, NotYetOwnedVerify) {
+ StartUnowned();
+
+ // Since this shouldn't happen, don't want it to end the test if it does.
+ SetQuitOnKeyFetch(false);
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ KeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
+ EXPECT_FALSE(manager->StartVerifyAttempt("", "", &delegate));
+}
+
+TEST_F(OwnerManagerTest, AlreadyHaveKeysVerify) {
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ InjectKeys(manager.get());
+ KeyUser delegate(OwnerManager::SUCCESS);
+ EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
+
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, GetKeyFailDuringVerify) {
+ ExpectKeyFetchSuccess(false);
+ SECKEYPublicKey* to_return = NULL;
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+ EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
+ .WillOnce(Return(to_return))
+ .RetiresOnSaturation();
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ KeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
+ EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
+
+ message_loop_.Run();
+}
+
+TEST_F(OwnerManagerTest, GetKeyAndVerify) {
+ ExpectKeyFetchSuccess(true);
+ SetQuitOnKeyFetch(false);
+
+ EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
+ .WillRepeatedly(Return(tmpfile_));
+ EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
+ .WillOnce(Return(fake_public_key_))
+ .RetiresOnSaturation();
+
+ scoped_refptr<OwnerManager> manager(new OwnerManager);
+ KeyUser delegate(OwnerManager::SUCCESS);
+ EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
+
+ message_loop_.Run();
+}
+
+} // namespace chromeos
« no previous file with comments | « chrome/browser/chromeos/login/owner_manager.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698