• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/login/cryptohome_op.h"
6 
7 #include <string>
8 
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop.h"
11 #include "chrome/browser/chromeos/cros/mock_library_loader.h"
12 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h"
13 #include "chrome/browser/chromeos/login/auth_attempt_state.h"
14 #include "chrome/browser/chromeos/login/mock_auth_attempt_state_resolver.h"
15 #include "chrome/browser/chromeos/login/test_attempt_state.h"
16 #include "content/browser/browser_thread.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 
20 using ::testing::AnyNumber;
21 using ::testing::Invoke;
22 using ::testing::Return;
23 using ::testing::_;
24 
25 namespace chromeos {
26 
27 class CryptohomeOpTest : public ::testing::Test {
28  public:
CryptohomeOpTest()29   CryptohomeOpTest()
30       : message_loop_(MessageLoop::TYPE_UI),
31         ui_thread_(BrowserThread::UI, &message_loop_),
32         io_thread_(BrowserThread::IO),
33         username_("me@nowhere.org"),
34         hash_ascii_("0a010000000000a0"),
35         state_(username_, "", hash_ascii_, "", "", false),
36         resolver_(new MockAuthAttemptStateResolver),
37         mock_library_(new MockCryptohomeLibrary) {
38   }
39 
~CryptohomeOpTest()40   virtual ~CryptohomeOpTest() {}
41 
SetUp()42   virtual void SetUp() {
43     CrosLibrary::TestApi* test_api = CrosLibrary::Get()->GetTestApi();
44 
45     MockLibraryLoader* loader = new MockLibraryLoader();
46     ON_CALL(*loader, Load(_))
47         .WillByDefault(Return(true));
48     EXPECT_CALL(*loader, Load(_))
49         .Times(AnyNumber());
50 
51     // Passes ownership of |loader| to CrosLibrary.
52     test_api->SetLibraryLoader(loader, true);
53     // |mock_library_| is mine, though.
54     test_api->SetCryptohomeLibrary(mock_library_.get(), false);
55     mock_library_->SetUp(false, 0);
56 
57     io_thread_.Start();
58   }
59 
TearDown()60   virtual void TearDown() {
61     // Prevent bogus gMock leak check from firing.
62     chromeos::CrosLibrary::TestApi* test_api =
63         chromeos::CrosLibrary::Get()->GetTestApi();
64     test_api->SetLibraryLoader(NULL, false);
65   }
66 
ExpectMigrate(bool passing_old_hash,const std::string & hash)67   void ExpectMigrate(bool passing_old_hash, const std::string& hash) {
68     if (passing_old_hash) {
69       EXPECT_CALL(*(mock_library_.get()), AsyncMigrateKey(username_,
70                                                           hash,
71                                                           hash_ascii_,
72                                                           _))
73           .Times(1)
74           .RetiresOnSaturation();
75     } else {
76       EXPECT_CALL(*(mock_library_.get()), AsyncMigrateKey(username_,
77                                                           hash_ascii_,
78                                                           hash,
79                                                           _))
80           .Times(1)
81           .RetiresOnSaturation();
82     }
83   }
84 
ExpectMount()85   void ExpectMount() {
86     EXPECT_CALL(*(mock_library_.get()),
87                 AsyncMount(username_, hash_ascii_, true, _))
88         .Times(1)
89         .RetiresOnSaturation();
90   }
91 
ExpectMountGuest()92   void ExpectMountGuest() {
93     EXPECT_CALL(*(mock_library_.get()), AsyncMountForBwsi(_))
94         .Times(1)
95         .RetiresOnSaturation();
96   }
97 
ExpectRemove()98   void ExpectRemove() {
99     EXPECT_CALL(*(mock_library_.get()), AsyncRemove(username_, _))
100         .Times(1)
101         .RetiresOnSaturation();
102   }
103 
ExpectCheckKey()104   void ExpectCheckKey() {
105     EXPECT_CALL(*(mock_library_.get()),
106                 AsyncCheckKey(username_, hash_ascii_, _))
107         .Times(1)
108         .RetiresOnSaturation();
109   }
110 
RunTest(CryptohomeOp * op,bool outcome,int code)111   void RunTest(CryptohomeOp* op, bool outcome, int code) {
112     mock_library_->SetAsyncBehavior(outcome, code);
113 
114     EXPECT_CALL(*(resolver_.get()), Resolve())
115         .Times(1)
116         .RetiresOnSaturation();
117 
118     EXPECT_TRUE(op->Initiate());
119     // Force IO thread to finish tasks so I can verify |state_|.
120     io_thread_.Stop();
121 
122     EXPECT_EQ(outcome, state_.cryptohome_outcome());
123     EXPECT_EQ(code, state_.cryptohome_code());
124   }
125 
126   MessageLoop message_loop_;
127   BrowserThread ui_thread_;
128   BrowserThread io_thread_;
129   std::string username_;
130   std::string hash_ascii_;
131   TestAttemptState state_;
132   scoped_ptr<MockAuthAttemptStateResolver> resolver_;
133   scoped_refptr<CryptohomeOp> op_;
134   scoped_ptr<MockCryptohomeLibrary> mock_library_;
135 
136 };
137 
TEST_F(CryptohomeOpTest,MountSuccess)138 TEST_F(CryptohomeOpTest, MountSuccess) {
139   ExpectMount();
140   scoped_refptr<CryptohomeOp> op(
141       CryptohomeOp::CreateMountAttempt(&state_, resolver_.get(), true));
142   RunTest(op.get(), true, kCryptohomeMountErrorNone);
143 }
144 
TEST_F(CryptohomeOpTest,MountFatal)145 TEST_F(CryptohomeOpTest, MountFatal) {
146   ExpectMount();
147   scoped_refptr<CryptohomeOp> op(
148       CryptohomeOp::CreateMountAttempt(&state_, resolver_.get(), true));
149   RunTest(op.get(), false, kCryptohomeMountErrorFatal);
150 }
151 
TEST_F(CryptohomeOpTest,MountKeyFailure)152 TEST_F(CryptohomeOpTest, MountKeyFailure) {
153   ExpectMount();
154   scoped_refptr<CryptohomeOp> op(
155       CryptohomeOp::CreateMountAttempt(&state_, resolver_.get(), true));
156   RunTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
157 }
158 
TEST_F(CryptohomeOpTest,MountRecreated)159 TEST_F(CryptohomeOpTest, MountRecreated) {
160   ExpectMount();
161   scoped_refptr<CryptohomeOp> op(
162       CryptohomeOp::CreateMountAttempt(&state_, resolver_.get(), true));
163   RunTest(op.get(), true, kCryptohomeMountErrorRecreated);
164 }
165 
TEST_F(CryptohomeOpTest,MountGuestSuccess)166 TEST_F(CryptohomeOpTest, MountGuestSuccess) {
167   ExpectMountGuest();
168   scoped_refptr<CryptohomeOp> op(
169       CryptohomeOp::CreateMountGuestAttempt(&state_, resolver_.get()));
170   RunTest(op.get(), true, kCryptohomeMountErrorNone);
171 }
172 
TEST_F(CryptohomeOpTest,MountGuestFatal)173 TEST_F(CryptohomeOpTest, MountGuestFatal) {
174   ExpectMountGuest();
175   scoped_refptr<CryptohomeOp> op(
176       CryptohomeOp::CreateMountGuestAttempt(&state_, resolver_.get()));
177   RunTest(op.get(), false, kCryptohomeMountErrorFatal);
178 }
179 
TEST_F(CryptohomeOpTest,MigrateSuccessPassOld)180 TEST_F(CryptohomeOpTest, MigrateSuccessPassOld) {
181   ExpectMigrate(true, "");
182   scoped_refptr<CryptohomeOp> op(
183       CryptohomeOp::CreateMigrateAttempt(&state_, resolver_.get(), true, ""));
184   RunTest(op.get(), true, kCryptohomeMountErrorNone);
185 }
186 
TEST_F(CryptohomeOpTest,MigrateSuccessPassNew)187 TEST_F(CryptohomeOpTest, MigrateSuccessPassNew) {
188   ExpectMigrate(false, "");
189   scoped_refptr<CryptohomeOp> op(
190       CryptohomeOp::CreateMigrateAttempt(&state_, resolver_.get(), false, ""));
191   RunTest(op.get(), true, kCryptohomeMountErrorNone);
192 }
193 
TEST_F(CryptohomeOpTest,MigrateKeyFailure)194 TEST_F(CryptohomeOpTest, MigrateKeyFailure) {
195   ExpectMigrate(true, "");
196   scoped_refptr<CryptohomeOp> op(
197       CryptohomeOp::CreateMigrateAttempt(&state_, resolver_.get(), true, ""));
198   RunTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
199 }
200 
TEST_F(CryptohomeOpTest,RemoveSuccess)201 TEST_F(CryptohomeOpTest, RemoveSuccess) {
202   ExpectRemove();
203   scoped_refptr<CryptohomeOp> op(
204       CryptohomeOp::CreateRemoveAttempt(&state_, resolver_.get()));
205   RunTest(op.get(), true, kCryptohomeMountErrorNone);
206 }
207 
TEST_F(CryptohomeOpTest,RemoveFailure)208 TEST_F(CryptohomeOpTest, RemoveFailure) {
209   ExpectRemove();
210   scoped_refptr<CryptohomeOp> op(
211       CryptohomeOp::CreateRemoveAttempt(&state_, resolver_.get()));
212   RunTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
213 }
214 
TEST_F(CryptohomeOpTest,CheckKeySuccess)215 TEST_F(CryptohomeOpTest, CheckKeySuccess) {
216   ExpectCheckKey();
217   scoped_refptr<CryptohomeOp> op(
218       CryptohomeOp::CreateCheckKeyAttempt(&state_, resolver_.get()));
219   RunTest(op.get(), true, kCryptohomeMountErrorNone);
220 }
221 
TEST_F(CryptohomeOpTest,CheckKeyFailure)222 TEST_F(CryptohomeOpTest, CheckKeyFailure) {
223   ExpectCheckKey();
224   scoped_refptr<CryptohomeOp> op(
225       CryptohomeOp::CreateCheckKeyAttempt(&state_, resolver_.get()));
226   RunTest(op.get(), false, kCryptohomeMountErrorKeyFailure);
227 }
228 
229 }  // namespace chromeos
230