| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/login_utils.h" | 5 #include "chrome/browser/chromeos/login/login_utils.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| 11 #include "base/scoped_temp_dir.h" | 11 #include "base/scoped_temp_dir.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/threading/sequenced_worker_pool.h" |
| 13 #include "chrome/browser/chromeos/cros/cros_library.h" | 14 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 14 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" | 15 #include "chrome/browser/chromeos/cros/mock_cryptohome_library.h" |
| 15 #include "chrome/browser/chromeos/cros/mock_library_loader.h" | 16 #include "chrome/browser/chromeos/cros/mock_library_loader.h" |
| 16 #include "chrome/browser/chromeos/cryptohome/mock_async_method_caller.h" | 17 #include "chrome/browser/chromeos/cryptohome/mock_async_method_caller.h" |
| 17 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" | 18 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" |
| 18 #include "chrome/browser/chromeos/login/authenticator.h" | 19 #include "chrome/browser/chromeos/login/authenticator.h" |
| 19 #include "chrome/browser/chromeos/login/login_status_consumer.h" | 20 #include "chrome/browser/chromeos/login/login_status_consumer.h" |
| 20 #include "chrome/browser/chromeos/login/user_manager.h" | 21 #include "chrome/browser/chromeos/login/user_manager.h" |
| 21 #include "chrome/browser/io_thread.h" | 22 #include "chrome/browser/io_thread.h" |
| 22 #include "chrome/browser/net/predictor.h" | 23 #include "chrome/browser/net/predictor.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 const char kDMToken[] = "1234"; | 83 const char kDMToken[] = "1234"; |
| 83 | 84 |
| 84 ACTION_P(MockSessionManagerClientRetrievePolicyCallback, policy) { | 85 ACTION_P(MockSessionManagerClientRetrievePolicyCallback, policy) { |
| 85 arg0.Run(*policy); | 86 arg0.Run(*policy); |
| 86 } | 87 } |
| 87 | 88 |
| 88 ACTION_P(MockSessionManagerClientStorePolicyCallback, success) { | 89 ACTION_P(MockSessionManagerClientStorePolicyCallback, success) { |
| 89 arg1.Run(success); | 90 arg1.Run(success); |
| 90 } | 91 } |
| 91 | 92 |
| 92 template<typename TESTBASE> | 93 class LoginUtilsTest : public testing::Test, |
| 93 class LoginUtilsTestBase : public TESTBASE, | 94 public LoginUtils::Delegate, |
| 94 public LoginUtils::Delegate, | 95 public LoginStatusConsumer { |
| 95 public LoginStatusConsumer { | |
| 96 public: | 96 public: |
| 97 // Initialization here is important. The UI thread gets the test's | 97 // Initialization here is important. The UI thread gets the test's |
| 98 // message loop, as does the file thread (which never actually gets | 98 // message loop, as does the file thread (which never actually gets |
| 99 // started - so this is a way to fake multiple threads on a single | 99 // started - so this is a way to fake multiple threads on a single |
| 100 // test thread). The IO thread does not get the message loop set, | 100 // test thread). The IO thread does not get the message loop set, |
| 101 // and is never started. This is necessary so that we skip various | 101 // and is never started. This is necessary so that we skip various |
| 102 // bits of initialization that get posted to the IO thread. We do | 102 // bits of initialization that get posted to the IO thread. We do |
| 103 // however, at one point in the test, temporarily set the message | 103 // however, at one point in the test, temporarily set the message |
| 104 // loop for the IO thread. | 104 // loop for the IO thread. |
| 105 LoginUtilsTestBase() | 105 LoginUtilsTest() |
| 106 : loop_(MessageLoop::TYPE_IO), | 106 : loop_(MessageLoop::TYPE_IO), |
| 107 browser_process_( | 107 browser_process_( |
| 108 static_cast<TestingBrowserProcess*>(g_browser_process)), | 108 static_cast<TestingBrowserProcess*>(g_browser_process)), |
| 109 local_state_(browser_process_), | 109 local_state_(browser_process_), |
| 110 ui_thread_(content::BrowserThread::UI, &loop_), | 110 ui_thread_(content::BrowserThread::UI, &loop_), |
| 111 file_thread_(content::BrowserThread::FILE, &loop_), | 111 file_thread_(content::BrowserThread::FILE, &loop_), |
| 112 io_thread_(content::BrowserThread::IO), | 112 io_thread_(content::BrowserThread::IO), |
| 113 mock_async_method_caller_(NULL), | 113 mock_async_method_caller_(NULL), |
| 114 connector_(NULL), | 114 connector_(NULL), |
| 115 cryptohome_(NULL), | 115 cryptohome_(NULL), |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDeviceId, _)) | 204 EXPECT_CALL(*cryptohome_, InstallAttributesGet(kAttrEnterpriseDeviceId, _)) |
| 205 .WillRepeatedly(DoAll(SetArgPointee<1>(kDeviceId), | 205 .WillRepeatedly(DoAll(SetArgPointee<1>(kDeviceId), |
| 206 Return(true))); | 206 Return(true))); |
| 207 test_api->SetCryptohomeLibrary(cryptohome_, true); | 207 test_api->SetCryptohomeLibrary(cryptohome_, true); |
| 208 | 208 |
| 209 browser_process_->SetProfileManager( | 209 browser_process_->SetProfileManager( |
| 210 new ProfileManagerWithoutInit(scoped_temp_dir_.path())); | 210 new ProfileManagerWithoutInit(scoped_temp_dir_.path())); |
| 211 connector_ = browser_process_->browser_policy_connector(); | 211 connector_ = browser_process_->browser_policy_connector(); |
| 212 connector_->Init(); | 212 connector_->Init(); |
| 213 | 213 |
| 214 loop_.RunAllPending(); | 214 RunAllPending(); |
| 215 } | 215 } |
| 216 | 216 |
| 217 virtual void TearDown() OVERRIDE { | 217 virtual void TearDown() OVERRIDE { |
| 218 cryptohome::AsyncMethodCaller::Shutdown(); | 218 cryptohome::AsyncMethodCaller::Shutdown(); |
| 219 mock_async_method_caller_ = NULL; | 219 mock_async_method_caller_ = NULL; |
| 220 | 220 |
| 221 loop_.RunAllPending(); | 221 RunAllPending(); |
| 222 { | 222 { |
| 223 // chrome_browser_net::Predictor usually skips its shutdown routines on | 223 // chrome_browser_net::Predictor usually skips its shutdown routines on |
| 224 // unit_tests, but does the full thing when | 224 // unit_tests, but does the full thing when |
| 225 // g_browser_process->profile_manager() is valid during initialization. | 225 // g_browser_process->profile_manager() is valid during initialization. |
| 226 // Run a task on a temporary BrowserThread::IO that allows skipping | 226 // Run a task on a temporary BrowserThread::IO that allows skipping |
| 227 // these routines. | 227 // these routines. |
| 228 // | 228 // |
| 229 // It is important to not have a fake message loop on the IO | 229 // It is important to not have a fake message loop on the IO |
| 230 // thread for the whole test, see comment on LoginUtilsTestBase | 230 // thread for the whole test, see comment on LoginUtilsTest |
| 231 // constructor for details. | 231 // constructor for details. |
| 232 io_thread_.DeprecatedSetMessageLoop(&loop_); | 232 io_thread_.DeprecatedSetMessageLoop(&loop_); |
| 233 loop_.PostTask(FROM_HERE, | 233 loop_.PostTask(FROM_HERE, |
| 234 base::Bind(&LoginUtilsTestBase::TearDownOnIO, | 234 base::Bind(&LoginUtilsTest::TearDownOnIO, |
| 235 base::Unretained(this))); | 235 base::Unretained(this))); |
| 236 loop_.RunAllPending(); | 236 RunAllPending(); |
| 237 io_thread_.DeprecatedSetMessageLoop(NULL); | 237 io_thread_.DeprecatedSetMessageLoop(NULL); |
| 238 } | 238 } |
| 239 | 239 |
| 240 // These trigger some tasks that have to run while BrowserThread::UI | 240 // These trigger some tasks that have to run while BrowserThread::UI |
| 241 // exists. | 241 // exists. |
| 242 connector_ = NULL; | 242 connector_ = NULL; |
| 243 browser_process_->SetBrowserPolicyConnector(NULL); | 243 browser_process_->SetBrowserPolicyConnector(NULL); |
| 244 browser_process_->SetProfileManager(NULL); | 244 browser_process_->SetProfileManager(NULL); |
| 245 loop_.RunAllPending(); | 245 RunAllPending(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 void TearDownOnIO() { | 248 void TearDownOnIO() { |
| 249 std::vector<Profile*> profiles = | 249 std::vector<Profile*> profiles = |
| 250 browser_process_->profile_manager()->GetLoadedProfiles(); | 250 browser_process_->profile_manager()->GetLoadedProfiles(); |
| 251 for (size_t i = 0; i < profiles.size(); ++i) { | 251 for (size_t i = 0; i < profiles.size(); ++i) { |
| 252 chrome_browser_net::Predictor* predictor = | 252 chrome_browser_net::Predictor* predictor = |
| 253 profiles[i]->GetNetworkPredictor(); | 253 profiles[i]->GetNetworkPredictor(); |
| 254 if (predictor) { | 254 if (predictor) { |
| 255 predictor->EnablePredictorOnIOThread(false); | 255 predictor->EnablePredictorOnIOThread(false); |
| 256 predictor->Shutdown(); | 256 predictor->Shutdown(); |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 } | 259 } |
| 260 | 260 |
| 261 void RunAllPending() { |
| 262 loop_.RunAllPending(); |
| 263 BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 264 loop_.RunAllPending(); |
| 265 } |
| 266 |
| 261 virtual void OnProfilePrepared(Profile* profile) OVERRIDE { | 267 virtual void OnProfilePrepared(Profile* profile) OVERRIDE { |
| 262 EXPECT_FALSE(prepared_profile_); | 268 EXPECT_FALSE(prepared_profile_); |
| 263 prepared_profile_ = profile; | 269 prepared_profile_ = profile; |
| 264 } | 270 } |
| 265 | 271 |
| 266 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE { | 272 virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE { |
| 267 FAIL() << "OnLoginFailure not expected"; | 273 FAIL() << "OnLoginFailure not expected"; |
| 268 } | 274 } |
| 269 | 275 |
| 270 virtual void OnLoginSuccess(const std::string& username, | 276 virtual void OnLoginSuccess(const std::string& username, |
| 271 const std::string& password, | 277 const std::string& password, |
| 272 bool pending_requests, | 278 bool pending_requests, |
| 273 bool using_oauth) OVERRIDE { | 279 bool using_oauth) OVERRIDE { |
| 274 FAIL() << "OnLoginSuccess not expected"; | 280 FAIL() << "OnLoginSuccess not expected"; |
| 275 } | 281 } |
| 276 | 282 |
| 277 void LockDevice(const std::string& username) { | 283 void LockDevice(const std::string& username) { |
| 278 EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall()) | 284 EXPECT_CALL(*cryptohome_, InstallAttributesIsFirstInstall()) |
| 279 .WillOnce(Return(true)) | 285 .WillOnce(Return(true)) |
| 280 .WillRepeatedly(Return(false)); | 286 .WillRepeatedly(Return(false)); |
| 281 policy::CloudPolicyDataStore* device_data_store = | 287 policy::CloudPolicyDataStore* device_data_store = |
| 282 connector_->GetDeviceCloudPolicyDataStore(); | 288 connector_->GetDeviceCloudPolicyDataStore(); |
| 283 device_data_store->set_device_mode(policy::DEVICE_MODE_ENTERPRISE); | 289 device_data_store->set_device_mode(policy::DEVICE_MODE_ENTERPRISE); |
| 284 device_data_store->set_device_id(kDeviceId); | 290 device_data_store->set_device_id(kDeviceId); |
| 285 EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, | 291 EXPECT_EQ(policy::EnterpriseInstallAttributes::LOCK_SUCCESS, |
| 286 connector_->LockDevice(username)); | 292 connector_->LockDevice(username)); |
| 287 loop_.RunAllPending(); | 293 RunAllPending(); |
| 288 } | 294 } |
| 289 | 295 |
| 290 void PrepareProfile(const std::string& username) { | 296 void PrepareProfile(const std::string& username) { |
| 291 MockSessionManagerClient* session_managed_client = | 297 MockSessionManagerClient* session_managed_client = |
| 292 mock_dbus_thread_manager_.mock_session_manager_client(); | 298 mock_dbus_thread_manager_.mock_session_manager_client(); |
| 293 EXPECT_CALL(*session_managed_client, StartSession(_)); | 299 EXPECT_CALL(*session_managed_client, StartSession(_)); |
| 294 EXPECT_CALL(*cryptohome_, GetSystemSalt()) | 300 EXPECT_CALL(*cryptohome_, GetSystemSalt()) |
| 295 .WillRepeatedly(Return(std::string("stub_system_salt"))); | 301 .WillRepeatedly(Return(std::string("stub_system_salt"))); |
| 296 EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _)) | 302 EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _)) |
| 297 .WillRepeatedly(Return()); | 303 .WillRepeatedly(Return()); |
| 298 | 304 |
| 299 scoped_refptr<Authenticator> authenticator = | 305 scoped_refptr<Authenticator> authenticator = |
| 300 LoginUtils::Get()->CreateAuthenticator(this); | 306 LoginUtils::Get()->CreateAuthenticator(this); |
| 301 authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(), | 307 authenticator->CompleteLogin(ProfileManager::GetDefaultProfile(), |
| 302 username, | 308 username, |
| 303 "password"); | 309 "password"); |
| 304 | 310 |
| 305 LoginUtils::Get()->PrepareProfile(username, std::string(), "password", | 311 LoginUtils::Get()->PrepareProfile(username, std::string(), "password", |
| 306 false, true, false, this); | 312 false, true, false, this); |
| 307 loop_.RunAllPending(); | 313 RunAllPending(); |
| 308 } | 314 } |
| 309 | 315 |
| 310 TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) { | 316 TestURLFetcher* PrepareOAuthFetcher(const std::string& expected_url) { |
| 311 TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); | 317 TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); |
| 312 EXPECT_TRUE(fetcher); | 318 EXPECT_TRUE(fetcher); |
| 313 EXPECT_TRUE(fetcher->delegate()); | 319 EXPECT_TRUE(fetcher->delegate()); |
| 314 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(), | 320 EXPECT_TRUE(StartsWithASCII(fetcher->GetOriginalURL().spec(), |
| 315 expected_url, | 321 expected_url, |
| 316 true)); | 322 true)); |
| 317 fetcher->set_url(fetcher->GetOriginalURL()); | 323 fetcher->set_url(fetcher->GetOriginalURL()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 policy::BrowserPolicyConnector* connector_; | 381 policy::BrowserPolicyConnector* connector_; |
| 376 MockCryptohomeLibrary* cryptohome_; | 382 MockCryptohomeLibrary* cryptohome_; |
| 377 Profile* prepared_profile_; | 383 Profile* prepared_profile_; |
| 378 | 384 |
| 379 private: | 385 private: |
| 380 ScopedTempDir scoped_temp_dir_; | 386 ScopedTempDir scoped_temp_dir_; |
| 381 | 387 |
| 382 std::string device_policy_; | 388 std::string device_policy_; |
| 383 std::string user_policy_; | 389 std::string user_policy_; |
| 384 | 390 |
| 385 DISALLOW_COPY_AND_ASSIGN(LoginUtilsTestBase); | 391 DISALLOW_COPY_AND_ASSIGN(LoginUtilsTest); |
| 386 }; | |
| 387 | |
| 388 class LoginUtilsTest : public LoginUtilsTestBase<testing::Test> { | |
| 389 }; | 392 }; |
| 390 | 393 |
| 391 class LoginUtilsBlockingLoginTest | 394 class LoginUtilsBlockingLoginTest |
| 392 : public LoginUtilsTestBase<testing::TestWithParam<int> > { | 395 : public LoginUtilsTest, |
| 393 }; | 396 public testing::WithParamInterface<int> {}; |
| 394 | 397 |
| 395 TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) { | 398 TEST_F(LoginUtilsTest, NormalLoginDoesntBlock) { |
| 396 UserManager* user_manager = UserManager::Get(); | 399 UserManager* user_manager = UserManager::Get(); |
| 397 ASSERT_TRUE(!user_manager->IsUserLoggedIn() || | 400 ASSERT_TRUE(!user_manager->IsUserLoggedIn() || |
| 398 user_manager->IsLoggedInAsStub()); | 401 user_manager->IsLoggedInAsStub()); |
| 399 EXPECT_FALSE(connector_->IsEnterpriseManaged()); | 402 EXPECT_FALSE(connector_->IsEnterpriseManaged()); |
| 400 EXPECT_FALSE(prepared_profile_); | 403 EXPECT_FALSE(prepared_profile_); |
| 401 | 404 |
| 402 // The profile will be created without waiting for a policy response. | 405 // The profile will be created without waiting for a policy response. |
| 403 PrepareProfile(kUsername); | 406 PrepareProfile(kUsername); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 fetcher->delegate()->OnURLFetchComplete(fetcher); | 484 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 482 if (steps < 3) break; | 485 if (steps < 3) break; |
| 483 | 486 |
| 484 // Fake OAuth service token retrieval: | 487 // Fake OAuth service token retrieval: |
| 485 fetcher = PrepareOAuthFetcher(gaia_urls->oauth_wrap_bridge_url()); | 488 fetcher = PrepareOAuthFetcher(gaia_urls->oauth_wrap_bridge_url()); |
| 486 fetcher->SetResponseString(kOAuthServiceTokenData); | 489 fetcher->SetResponseString(kOAuthServiceTokenData); |
| 487 fetcher->delegate()->OnURLFetchComplete(fetcher); | 490 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 488 | 491 |
| 489 // The cloud policy subsystem is now ready to fetch the dmtoken and the user | 492 // The cloud policy subsystem is now ready to fetch the dmtoken and the user |
| 490 // policy. | 493 // policy. |
| 491 loop_.RunAllPending(); | 494 RunAllPending(); |
| 492 if (steps < 4) break; | 495 if (steps < 4) break; |
| 493 | 496 |
| 494 fetcher = PrepareDMRegisterFetcher(); | 497 fetcher = PrepareDMRegisterFetcher(); |
| 495 fetcher->delegate()->OnURLFetchComplete(fetcher); | 498 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 496 // The policy fetch job has now been scheduled, run it: | 499 // The policy fetch job has now been scheduled, run it: |
| 497 loop_.RunAllPending(); | 500 RunAllPending(); |
| 498 if (steps < 5) break; | 501 if (steps < 5) break; |
| 499 | 502 |
| 500 // Verify that there is no profile prepared just before the policy fetch. | 503 // Verify that there is no profile prepared just before the policy fetch. |
| 501 EXPECT_FALSE(prepared_profile_); | 504 EXPECT_FALSE(prepared_profile_); |
| 502 | 505 |
| 503 fetcher = PrepareDMPolicyFetcher(); | 506 fetcher = PrepareDMPolicyFetcher(); |
| 504 fetcher->delegate()->OnURLFetchComplete(fetcher); | 507 fetcher->delegate()->OnURLFetchComplete(fetcher); |
| 505 } while (0); | 508 } while (0); |
| 506 | 509 |
| 507 if (steps < 5) { | 510 if (steps < 5) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 522 } | 525 } |
| 523 | 526 |
| 524 INSTANTIATE_TEST_CASE_P( | 527 INSTANTIATE_TEST_CASE_P( |
| 525 LoginUtilsBlockingLoginTestInstance, | 528 LoginUtilsBlockingLoginTestInstance, |
| 526 LoginUtilsBlockingLoginTest, | 529 LoginUtilsBlockingLoginTest, |
| 527 testing::Values(0, 1, 2, 3, 4, 5)); | 530 testing::Values(0, 1, 2, 3, 4, 5)); |
| 528 | 531 |
| 529 } // namespace | 532 } // namespace |
| 530 | 533 |
| 531 } | 534 } |
| OLD | NEW |