This source file includes following definitions.
- network_change_notifier_
- SetUp
- CreateRefreshScheduler
- NotifyIPAddressChanged
- GetLastDelay
- CheckTiming
- CheckTimingWithAge
- CheckInitialRefresh
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- SetUp
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_P
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/test/test_simple_task_runner.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace em = enterprise_management;
using testing::Mock;
namespace policy {
namespace {
const int64 kPolicyRefreshRate = 4 * 60 * 60 * 1000;
const int64 kInitialCacheAgeMinutes = 1;
}
class CloudPolicyRefreshSchedulerTest : public testing::Test {
protected:
CloudPolicyRefreshSchedulerTest()
: task_runner_(new base::TestSimpleTaskRunner()),
network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {}
virtual void SetUp() OVERRIDE {
client_.SetDMToken("token");
store_.policy_.reset(new em::PolicyData());
base::Time now = base::Time::NowFromSystemTime();
base::TimeDelta initial_age =
base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes);
store_.policy_->set_timestamp(
((now - initial_age) - base::Time::UnixEpoch()).InMilliseconds());
last_update_ =
base::Time::UnixEpoch() +
base::TimeDelta::FromMilliseconds(store_.policy_->timestamp());
}
CloudPolicyRefreshScheduler* CreateRefreshScheduler() {
EXPECT_EQ(0u, task_runner_->GetPendingTasks().size());
CloudPolicyRefreshScheduler* scheduler =
new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_);
scheduler->SetRefreshDelay(kPolicyRefreshRate);
return scheduler;
}
void NotifyIPAddressChanged() {
net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
loop_.RunUntilIdle();
}
base::TimeDelta GetLastDelay() const {
const std::deque<base::TestPendingTask>& pending_tasks =
task_runner_->GetPendingTasks();
return
pending_tasks.empty() ? base::TimeDelta() : pending_tasks.back().delay;
}
void CheckTiming(int64 expected_delay_ms) const {
CheckTimingWithAge(base::TimeDelta::FromMilliseconds(expected_delay_ms),
base::TimeDelta());
}
void CheckTimingWithAge(const base::TimeDelta& offset_from_last_refresh,
const base::TimeDelta& cache_age) const {
EXPECT_FALSE(task_runner_->GetPendingTasks().empty());
base::Time now(base::Time::NowFromSystemTime());
EXPECT_GE(GetLastDelay(), offset_from_last_refresh - (now - last_update_));
EXPECT_LE(GetLastDelay(), offset_from_last_refresh - cache_age);
}
void CheckInitialRefresh(bool with_invalidations) const {
#if defined(OS_ANDROID) || defined(OS_IOS)
base::TimeDelta rate = base::TimeDelta::FromMilliseconds(
with_invalidations
? CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs
: kPolicyRefreshRate);
CheckTimingWithAge(rate,
base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes));
#else
EXPECT_EQ(base::TimeDelta(), GetLastDelay());
#endif
}
base::MessageLoop loop_;
MockCloudPolicyClient client_;
MockCloudPolicyStore store_;
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
base::Time last_update_;
};
TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshNoPolicy) {
store_.policy_.reset();
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
EXPECT_FALSE(task_runner_->GetPendingTasks().empty());
EXPECT_EQ(GetLastDelay(), base::TimeDelta());
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
}
TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshUnmanaged) {
store_.policy_->set_state(em::PolicyData::UNMANAGED);
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
CheckTiming(CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
}
TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedNotYetFetched) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
EXPECT_FALSE(task_runner_->GetPendingTasks().empty());
CheckInitialRefresh(false);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
}
TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedAlreadyFetched) {
last_update_ = base::Time::NowFromSystemTime();
client_.SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType,
std::string()),
em::PolicyFetchResponse());
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
CheckTiming(kPolicyRefreshRate);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
}
TEST_F(CloudPolicyRefreshSchedulerTest, Unregistered) {
client_.SetDMToken(std::string());
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
client_.NotifyPolicyFetched();
client_.NotifyRegistrationStateChanged();
client_.NotifyClientError();
scheduler->SetRefreshDelay(12 * 60 * 60 * 1000);
store_.NotifyStoreLoaded();
store_.NotifyStoreError();
EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
}
TEST_F(CloudPolicyRefreshSchedulerTest, RefreshSoonRateLimit) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler());
for (int i = 0; i < 5; ++i) {
EXPECT_CALL(client_, FetchPolicy()).Times(1);
scheduler->RefreshSoon();
task_runner_->RunUntilIdle();
Mock::VerifyAndClearExpectations(&client_);
}
EXPECT_CALL(client_, FetchPolicy()).Times(0);
scheduler->RefreshSoon();
task_runner_->RunPendingTasks();
Mock::VerifyAndClearExpectations(&client_);
}
TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsAvailable) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(
new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_));
scheduler->SetRefreshDelay(kPolicyRefreshRate);
EXPECT_EQ(2u, task_runner_->GetPendingTasks().size());
scheduler->SetInvalidationServiceAvailability(true);
EXPECT_EQ(3u, task_runner_->GetPendingTasks().size());
CheckInitialRefresh(true);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunPendingTasks();
Mock::VerifyAndClearExpectations(&client_);
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyPolicyFetched();
EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs);
}
TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsNotAvailable) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(
new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_));
scheduler->SetRefreshDelay(kPolicyRefreshRate);
for (int i = 0; i < 10; ++i) {
scheduler->SetInvalidationServiceAvailability(false);
EXPECT_EQ(2u, task_runner_->GetPendingTasks().size());
}
CheckInitialRefresh(false);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunPendingTasks();
Mock::VerifyAndClearExpectations(&client_);
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyPolicyFetched();
EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
CheckTiming(kPolicyRefreshRate);
}
TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsOffAndOn) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(
new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_));
scheduler->SetRefreshDelay(kPolicyRefreshRate);
scheduler->SetInvalidationServiceAvailability(true);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
Mock::VerifyAndClearExpectations(&client_);
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyPolicyFetched();
CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs);
scheduler->SetInvalidationServiceAvailability(false);
scheduler->SetInvalidationServiceAvailability(true);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs);
task_runner_->RunPendingTasks();
Mock::VerifyAndClearExpectations(&client_);
}
TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsDisconnected) {
scoped_ptr<CloudPolicyRefreshScheduler> scheduler(
new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_));
scheduler->SetRefreshDelay(kPolicyRefreshRate);
scheduler->SetInvalidationServiceAvailability(true);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunUntilIdle();
Mock::VerifyAndClearExpectations(&client_);
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyPolicyFetched();
CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs);
EXPECT_CALL(client_, FetchPolicy()).Times(1);
task_runner_->RunPendingTasks();
Mock::VerifyAndClearExpectations(&client_);
scheduler->SetInvalidationServiceAvailability(false);
CheckTiming(kPolicyRefreshRate);
}
class CloudPolicyRefreshSchedulerSteadyStateTest
: public CloudPolicyRefreshSchedulerTest {
protected:
CloudPolicyRefreshSchedulerSteadyStateTest() {}
virtual void SetUp() OVERRIDE {
refresh_scheduler_.reset(CreateRefreshScheduler());
refresh_scheduler_->SetRefreshDelay(kPolicyRefreshRate);
CloudPolicyRefreshSchedulerTest::SetUp();
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyPolicyFetched();
CheckTiming(kPolicyRefreshRate);
}
scoped_ptr<CloudPolicyRefreshScheduler> refresh_scheduler_;
};
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnPolicyFetched) {
client_.NotifyPolicyFetched();
CheckTiming(kPolicyRefreshRate);
}
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnRegistrationStateChanged) {
client_.SetDMToken("new_token");
client_.NotifyRegistrationStateChanged();
EXPECT_EQ(GetLastDelay(), base::TimeDelta());
task_runner_->ClearPendingTasks();
client_.SetDMToken(std::string());
client_.NotifyRegistrationStateChanged();
EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
}
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreLoaded) {
store_.NotifyStoreLoaded();
CheckTiming(kPolicyRefreshRate);
}
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreError) {
task_runner_->ClearPendingTasks();
store_.NotifyStoreError();
EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
}
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, RefreshDelayChange) {
const int delay_short_ms = 5 * 60 * 1000;
refresh_scheduler_->SetRefreshDelay(delay_short_ms);
CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMinMs);
const int delay_ms = 12 * 60 * 60 * 1000;
refresh_scheduler_->SetRefreshDelay(delay_ms);
CheckTiming(delay_ms);
const int delay_long_ms = 20 * 24 * 60 * 60 * 1000;
refresh_scheduler_->SetRefreshDelay(delay_long_ms);
CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMaxMs);
}
TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnIPAddressChanged) {
NotifyIPAddressChanged();
CheckTiming(kPolicyRefreshRate);
client_.SetStatus(DM_STATUS_REQUEST_FAILED);
NotifyIPAddressChanged();
EXPECT_EQ(GetLastDelay(), base::TimeDelta());
}
struct ClientErrorTestParam {
DeviceManagementStatus client_error;
int64 expected_delay_ms;
int backoff_factor;
};
static const ClientErrorTestParam kClientErrorTestCases[] = {
{ DM_STATUS_REQUEST_INVALID,
CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 },
{ DM_STATUS_REQUEST_FAILED,
CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 },
{ DM_STATUS_TEMPORARY_UNAVAILABLE,
CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 },
{ DM_STATUS_HTTP_STATUS_ERROR,
CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 },
{ DM_STATUS_RESPONSE_DECODING_ERROR,
CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 },
{ DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED,
CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 },
{ DM_STATUS_SERVICE_DEVICE_NOT_FOUND,
-1, 1 },
{ DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID,
-1, 1 },
{ DM_STATUS_SERVICE_ACTIVATION_PENDING,
kPolicyRefreshRate, 1 },
{ DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER,
-1, 1 },
{ DM_STATUS_SERVICE_MISSING_LICENSES,
-1, 1 },
{ DM_STATUS_SERVICE_DEVICE_ID_CONFLICT,
-1, 1 },
{ DM_STATUS_SERVICE_POLICY_NOT_FOUND,
kPolicyRefreshRate, 1 },
};
class CloudPolicyRefreshSchedulerClientErrorTest
: public CloudPolicyRefreshSchedulerSteadyStateTest,
public testing::WithParamInterface<ClientErrorTestParam> {
};
TEST_P(CloudPolicyRefreshSchedulerClientErrorTest, OnClientError) {
client_.SetStatus(GetParam().client_error);
task_runner_->ClearPendingTasks();
int64 expected_delay_ms = GetParam().expected_delay_ms;
client_.NotifyClientError();
if (expected_delay_ms >= 0) {
CheckTiming(expected_delay_ms);
do {
expected_delay_ms *= GetParam().backoff_factor;
last_update_ = base::Time::NowFromSystemTime();
client_.NotifyClientError();
CheckTiming(std::max(std::min(expected_delay_ms, kPolicyRefreshRate),
GetParam().expected_delay_ms));
} while (GetParam().backoff_factor > 1 &&
expected_delay_ms <= kPolicyRefreshRate);
} else {
EXPECT_EQ(base::TimeDelta(), GetLastDelay());
EXPECT_TRUE(task_runner_->GetPendingTasks().empty());
}
}
INSTANTIATE_TEST_CASE_P(CloudPolicyRefreshSchedulerClientErrorTest,
CloudPolicyRefreshSchedulerClientErrorTest,
testing::ValuesIn(kClientErrorTestCases));
}