blob: 80d24980f8a30a8c3137a914d93c40094ee6cfc5 [file] [log] [blame]
// Copyright (c) 2012 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 "components/policy/core/common/policy_statistics_collector.h"
#include <cstring>
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/test/test_simple_task_runner.h"
#include "base/values.h"
#include "components/policy/core/common/external_data_fetcher.h"
#include "components/policy/core/common/mock_policy_service.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/core/common/policy_test_utils.h"
#include "components/policy/core/common/policy_types.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace policy {
namespace {
using testing::ReturnRef;
// Arbitrary policy names used for testing.
const char kTestPolicy1[] = "Test Policy 1";
const char kTestPolicy2[] = "Test Policy 2";
const int kTestPolicy1Id = 42;
const int kTestPolicy2Id = 123;
const char kTestChromeSchema[] =
"{"
" \"type\": \"object\","
" \"properties\": {"
" \"Test Policy 1\": { \"type\": \"string\" },"
" \"Test Policy 2\": { \"type\": \"string\" }"
" }"
"}";
const PolicyDetails kTestPolicyDetails[] = {
// is_deprecated is_device_policy id max_external_data_size
{ false, false, kTestPolicy1Id, 0 },
{ false, false, kTestPolicy2Id, 0 },
};
class TestPolicyStatisticsCollector : public PolicyStatisticsCollector {
public:
TestPolicyStatisticsCollector(
const GetChromePolicyDetailsCallback& get_details,
const Schema& chrome_schema,
PolicyService* policy_service,
PrefService* prefs,
const scoped_refptr<base::TaskRunner>& task_runner)
: PolicyStatisticsCollector(get_details,
chrome_schema,
policy_service,
prefs,
task_runner) {}
MOCK_METHOD1(RecordPolicyUse, void(int));
};
} // namespace
class PolicyStatisticsCollectorTest : public testing::Test {
protected:
PolicyStatisticsCollectorTest()
: update_delay_(base::TimeDelta::FromMilliseconds(
PolicyStatisticsCollector::kStatisticsUpdateRate)),
task_runner_(new base::TestSimpleTaskRunner()) {
}
void SetUp() override {
std::string error;
chrome_schema_ = Schema::Parse(kTestChromeSchema, &error);
ASSERT_TRUE(chrome_schema_.valid()) << error;
policy_details_.SetDetails(kTestPolicy1, &kTestPolicyDetails[0]);
policy_details_.SetDetails(kTestPolicy2, &kTestPolicyDetails[1]);
prefs_.registry()->RegisterInt64Pref(
policy_prefs::kLastPolicyStatisticsUpdate, 0);
// Set up default function behaviour.
EXPECT_CALL(policy_service_,
GetPolicies(PolicyNamespace(POLICY_DOMAIN_CHROME,
std::string())))
.WillRepeatedly(ReturnRef(policy_map_));
// Arbitrary negative value (so it'll be different from |update_delay_|).
last_delay_ = base::TimeDelta::FromDays(-1);
policy_map_.Clear();
policy_statistics_collector_.reset(new TestPolicyStatisticsCollector(
policy_details_.GetCallback(),
chrome_schema_,
&policy_service_,
&prefs_,
task_runner_));
}
void SetPolicy(const std::string& name) {
policy_map_.Set(name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true),
nullptr);
}
base::TimeDelta GetFirstDelay() const {
if (!task_runner_->HasPendingTask()) {
ADD_FAILURE();
return base::TimeDelta();
}
return task_runner_->NextPendingTaskDelay();
}
const base::TimeDelta update_delay_;
base::TimeDelta last_delay_;
PolicyDetailsMap policy_details_;
Schema chrome_schema_;
TestingPrefServiceSimple prefs_;
MockPolicyService policy_service_;
PolicyMap policy_map_;
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
std::unique_ptr<TestPolicyStatisticsCollector> policy_statistics_collector_;
};
TEST_F(PolicyStatisticsCollectorTest, CollectPending) {
SetPolicy(kTestPolicy1);
prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
(base::Time::Now() - update_delay_).ToInternalValue());
EXPECT_CALL(*policy_statistics_collector_, RecordPolicyUse(kTestPolicy1Id));
policy_statistics_collector_->Initialize();
EXPECT_EQ(1u, task_runner_->NumPendingTasks());
EXPECT_EQ(update_delay_, GetFirstDelay());
}
TEST_F(PolicyStatisticsCollectorTest, CollectPendingVeryOld) {
SetPolicy(kTestPolicy1);
// Must not be 0.0 (read comment for Time::FromDoubleT).
prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
base::Time::FromDoubleT(1.0).ToInternalValue());
EXPECT_CALL(*policy_statistics_collector_, RecordPolicyUse(kTestPolicy1Id));
policy_statistics_collector_->Initialize();
EXPECT_EQ(1u, task_runner_->NumPendingTasks());
EXPECT_EQ(update_delay_, GetFirstDelay());
}
TEST_F(PolicyStatisticsCollectorTest, CollectLater) {
SetPolicy(kTestPolicy1);
prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
(base::Time::Now() - update_delay_ / 2).ToInternalValue());
policy_statistics_collector_->Initialize();
EXPECT_EQ(1u, task_runner_->NumPendingTasks());
EXPECT_LT(GetFirstDelay(), update_delay_);
}
TEST_F(PolicyStatisticsCollectorTest, MultiplePolicies) {
SetPolicy(kTestPolicy1);
SetPolicy(kTestPolicy2);
prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
(base::Time::Now() - update_delay_).ToInternalValue());
EXPECT_CALL(*policy_statistics_collector_, RecordPolicyUse(kTestPolicy1Id));
EXPECT_CALL(*policy_statistics_collector_, RecordPolicyUse(kTestPolicy2Id));
policy_statistics_collector_->Initialize();
EXPECT_EQ(1u, task_runner_->NumPendingTasks());
}
} // namespace policy