Commit 630710f0 authored by mnissler@chromium.org's avatar mnissler@chromium.org

Put a hard limit on initial policy fetch wait time.

This assures that we're not hanging for a long time at login on the
initial policy fetch for Chrome OS user policy to happen.

BUG=chromium:285694
TEST=See bug, unit tests.

Review URL: https://chromiumcodereview.appspot.com/23450022

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221723 0039d316-1c4b-4281-b951-d872f2087c98
parent 723b891a
...@@ -51,13 +51,22 @@ const char kUMAInitialFetchOAuth2NetworkError[] = ...@@ -51,13 +51,22 @@ const char kUMAInitialFetchOAuth2NetworkError[] =
UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS( UserCloudPolicyManagerChromeOS::UserCloudPolicyManagerChromeOS(
scoped_ptr<CloudPolicyStore> store, scoped_ptr<CloudPolicyStore> store,
scoped_ptr<ResourceCache> resource_cache, scoped_ptr<ResourceCache> resource_cache,
bool wait_for_policy_fetch) bool wait_for_policy_fetch,
base::TimeDelta initial_policy_fetch_timeout)
: CloudPolicyManager( : CloudPolicyManager(
PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()), PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
store.get()), store.get()),
store_(store.Pass()), store_(store.Pass()),
wait_for_policy_fetch_(wait_for_policy_fetch) { wait_for_policy_fetch_(wait_for_policy_fetch),
policy_fetch_timeout_(false, false) {
time_init_started_ = base::Time::Now(); time_init_started_ = base::Time::Now();
if (wait_for_policy_fetch_) {
policy_fetch_timeout_.Start(
FROM_HERE,
initial_policy_fetch_timeout,
base::Bind(&UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch,
base::Unretained(this)));
}
if (resource_cache) { if (resource_cache) {
// TODO(joaodasilva): Move the backend from the FILE thread to the blocking // TODO(joaodasilva): Move the backend from the FILE thread to the blocking
// pool. // pool.
...@@ -306,6 +315,9 @@ void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete( ...@@ -306,6 +315,9 @@ void UserCloudPolicyManagerChromeOS::OnInitialPolicyFetchComplete(
} }
void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() { void UserCloudPolicyManagerChromeOS::CancelWaitForPolicyFetch() {
if (!wait_for_policy_fetch_)
return;
wait_for_policy_fetch_ = false; wait_for_policy_fetch_ = false;
CheckAndPublishPolicy(); CheckAndPublishPolicy();
// Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler // Now that |wait_for_policy_fetch_| is guaranteed to be false, the scheduler
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/policy/cloud/cloud_policy_client.h" #include "chrome/browser/policy/cloud/cloud_policy_client.h"
#include "chrome/browser/policy/cloud/cloud_policy_constants.h" #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
#include "chrome/browser/policy/cloud/cloud_policy_manager.h" #include "chrome/browser/policy/cloud/cloud_policy_manager.h"
...@@ -46,7 +47,8 @@ class UserCloudPolicyManagerChromeOS ...@@ -46,7 +47,8 @@ class UserCloudPolicyManagerChromeOS
UserCloudPolicyManagerChromeOS( UserCloudPolicyManagerChromeOS(
scoped_ptr<CloudPolicyStore> store, scoped_ptr<CloudPolicyStore> store,
scoped_ptr<ResourceCache> resource_cache, scoped_ptr<ResourceCache> resource_cache,
bool wait_for_policy_fetch); bool wait_for_policy_fetch,
base::TimeDelta initial_policy_fetch_timeout);
virtual ~UserCloudPolicyManagerChromeOS(); virtual ~UserCloudPolicyManagerChromeOS();
// Initializes the cloud connection. |local_state| and // Initializes the cloud connection. |local_state| and
...@@ -124,6 +126,10 @@ class UserCloudPolicyManagerChromeOS ...@@ -124,6 +126,10 @@ class UserCloudPolicyManagerChromeOS
// IsInitializationComplete(). // IsInitializationComplete().
bool wait_for_policy_fetch_; bool wait_for_policy_fetch_;
// A timer that puts a hard limit on the maximum time to wait for the intial
// policy fetch.
base::Timer policy_fetch_timeout_;
// The pref service to pass to the refresh scheduler on initialization. // The pref service to pass to the refresh scheduler on initialization.
PrefService* local_state_; PrefService* local_state_;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/policy/cloud/cloud_policy_constants.h" #include "chrome/browser/policy/cloud/cloud_policy_constants.h"
...@@ -143,13 +144,14 @@ class UserCloudPolicyManagerChromeOSTest : public testing::Test { ...@@ -143,13 +144,14 @@ class UserCloudPolicyManagerChromeOSTest : public testing::Test {
profile_manager_->DeleteTestingProfile(chrome::kInitialProfile); profile_manager_->DeleteTestingProfile(chrome::kInitialProfile);
} }
void CreateManager(bool wait_for_fetch) { void CreateManager(bool wait_for_fetch, int fetch_timeout) {
store_ = new MockCloudPolicyStore(); store_ = new MockCloudPolicyStore();
EXPECT_CALL(*store_, Load()); EXPECT_CALL(*store_, Load());
manager_.reset(new UserCloudPolicyManagerChromeOS( manager_.reset(new UserCloudPolicyManagerChromeOS(
scoped_ptr<CloudPolicyStore>(store_), scoped_ptr<CloudPolicyStore>(store_),
scoped_ptr<ResourceCache>(), scoped_ptr<ResourceCache>(),
wait_for_fetch)); wait_for_fetch,
base::TimeDelta::FromSeconds(fetch_timeout)));
manager_->Init(); manager_->Init();
manager_->AddObserver(&observer_); manager_->AddObserver(&observer_);
manager_->Connect(&prefs_, &device_management_service_, NULL, manager_->Connect(&prefs_, &device_management_service_, NULL,
...@@ -306,7 +308,7 @@ const char UserCloudPolicyManagerChromeOSTest::kSigninProfile[] = ...@@ -306,7 +308,7 @@ const char UserCloudPolicyManagerChromeOSTest::kSigninProfile[] =
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when the policy cache is empty. // initial fetch, when the policy cache is empty.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Initialize the CloudPolicyService without any stored data. // Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
...@@ -329,7 +331,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) { ...@@ -329,7 +331,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFirstFetch) {
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when a previously cached policy and DMToken already exist. // initial fetch, when a previously cached policy and DMToken already exist.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Set the initially cached data and initialize the CloudPolicyService. // Set the initially cached data and initialize the CloudPolicyService.
// The initial policy fetch is issued using the cached DMToken. // The initial policy fetch is issued using the cached DMToken.
...@@ -341,7 +343,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) { ...@@ -341,7 +343,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingRefreshFetch) {
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when the initial store load fails. // initial fetch, when the initial store load fails.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Initialize the CloudPolicyService without any stored data. // Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
...@@ -364,7 +366,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) { ...@@ -364,7 +366,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchStoreError) {
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when the OAuth2 token fetch fails. // initial fetch, when the OAuth2 token fetch fails.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Initialize the CloudPolicyService without any stored data. // Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
...@@ -393,7 +395,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) { ...@@ -393,7 +395,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchOAuthError) {
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when the device management registration fails. // initial fetch, when the device management registration fails.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Initialize the CloudPolicyService without any stored data. // Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
...@@ -419,7 +421,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) { ...@@ -419,7 +421,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchRegisterError) {
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) { TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) {
// Tests the initialization of a manager whose Profile is waiting for the // Tests the initialization of a manager whose Profile is waiting for the
// initial fetch, when the policy fetch request fails. // initial fetch, when the policy fetch request fails.
ASSERT_NO_FATAL_FAILURE(CreateManager(true)); ASSERT_NO_FATAL_FAILURE(CreateManager(true, 1000));
// Initialize the CloudPolicyService without any stored data. // Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete()); EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
...@@ -457,9 +459,29 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) { ...@@ -457,9 +459,29 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchPolicyFetchError) {
EXPECT_TRUE(PolicyBundle().Equals(manager_->policies())); EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
} }
TEST_F(UserCloudPolicyManagerChromeOSTest, BlockingFetchTimeout) {
// The blocking fetch should be abandoned after the timeout.
ASSERT_NO_FATAL_FAILURE(CreateManager(true, 0));
// Initialize the CloudPolicyService without any stored data.
EXPECT_FALSE(manager_->core()->service()->IsInitializationComplete());
store_->NotifyStoreLoaded();
EXPECT_TRUE(manager_->core()->service()->IsInitializationComplete());
EXPECT_FALSE(manager_->core()->client()->is_registered());
// Running the message loop should trigger the timeout.
EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get())).Times(AtLeast(1));
EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(&observer_);
EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
EXPECT_TRUE(PolicyBundle().Equals(manager_->policies()));
}
TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) { TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) {
// Tests the first policy fetch request by a Profile that isn't managed. // Tests the first policy fetch request by a Profile that isn't managed.
ASSERT_NO_FATAL_FAILURE(CreateManager(false)); ASSERT_NO_FATAL_FAILURE(CreateManager(false, 1000));
// Initialize the CloudPolicyService without any stored data. Since the // Initialize the CloudPolicyService without any stored data. Since the
// manager is not waiting for the initial fetch, it will become initialized // manager is not waiting for the initial fetch, it will become initialized
...@@ -502,7 +524,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) { ...@@ -502,7 +524,7 @@ TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingFirstFetch) {
TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingRefreshFetch) { TEST_F(UserCloudPolicyManagerChromeOSTest, NonBlockingRefreshFetch) {
// Tests a non-blocking initial policy fetch for a Profile that already has // Tests a non-blocking initial policy fetch for a Profile that already has
// a cached DMToken. // a cached DMToken.
ASSERT_NO_FATAL_FAILURE(CreateManager(false)); ASSERT_NO_FATAL_FAILURE(CreateManager(false, 1000));
// Set the initially cached data and initialize the CloudPolicyService. // Set the initially cached data and initialize the CloudPolicyService.
// The initial policy fetch is issued using the cached DMToken. // The initial policy fetch is issued using the cached DMToken.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/user.h" #include "chrome/browser/chromeos/login/user.h"
#include "chrome/browser/chromeos/login/user_manager.h" #include "chrome/browser/chromeos/login/user_manager.h"
...@@ -42,6 +43,10 @@ const base::FilePath::CharType kPolicy[] = FILE_PATH_LITERAL("Policy"); ...@@ -42,6 +43,10 @@ const base::FilePath::CharType kPolicy[] = FILE_PATH_LITERAL("Policy");
// resources are stored. // resources are stored.
const base::FilePath::CharType kResourceDir[] = FILE_PATH_LITERAL("Resources"); const base::FilePath::CharType kResourceDir[] = FILE_PATH_LITERAL("Resources");
// Timeout in seconds after which to abandon the initial policy fetch and start
// the session regardless.
const int kInitialPolicyFetchTimeoutSeconds = 10;
} // namespace } // namespace
// static // static
...@@ -147,9 +152,11 @@ scoped_ptr<UserCloudPolicyManagerChromeOS> ...@@ -147,9 +152,11 @@ scoped_ptr<UserCloudPolicyManagerChromeOS>
resource_cache.reset(new ResourceCache(resource_cache_dir)); resource_cache.reset(new ResourceCache(resource_cache_dir));
scoped_ptr<UserCloudPolicyManagerChromeOS> manager( scoped_ptr<UserCloudPolicyManagerChromeOS> manager(
new UserCloudPolicyManagerChromeOS(store.PassAs<CloudPolicyStore>(), new UserCloudPolicyManagerChromeOS(
store.PassAs<CloudPolicyStore>(),
resource_cache.Pass(), resource_cache.Pass(),
wait_for_initial_policy)); wait_for_initial_policy,
base::TimeDelta::FromSeconds(kInitialPolicyFetchTimeoutSeconds)));
manager->Init(); manager->Init();
manager->Connect(g_browser_process->local_state(), manager->Connect(g_browser_process->local_state(),
device_management_service, device_management_service,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment