15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/testing_pref_service.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/test/test_simple_task_runner.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/mock_policy_service.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "components/policy/core/common/policy_pref_names.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_statistics_collector.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/policy_test_utils.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_types.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnRef;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Arbitrary policy names used for testing.
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestPolicy1[] = "Test Policy 1";
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestPolicy2[] = "Test Policy 2";
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kTestPolicy1Id = 42;
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kTestPolicy2Id = 123;
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestChromeSchema[] =
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "{"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"type\": \"object\","
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"properties\": {"
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"Test Policy 1\": { \"type\": \"string\" },"
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"Test Policy 2\": { \"type\": \"string\" }"
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  }"
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "}";
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const PolicyDetails kTestPolicyDetails[] = {
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // is_deprecated  is_device_policy              id  max_external_data_size
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {          false,            false, kTestPolicy1Id,                      0 },
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {          false,            false, kTestPolicy2Id,                      0 },
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestPolicyStatisticsCollector : public PolicyStatisticsCollector {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestPolicyStatisticsCollector(
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const GetChromePolicyDetailsCallback& get_details,
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const Schema& chrome_schema,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PolicyService* policy_service,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PrefService* prefs,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const scoped_refptr<base::TaskRunner>& task_runner)
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : PolicyStatisticsCollector(get_details,
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  chrome_schema,
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  policy_service,
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  prefs,
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  task_runner) {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(RecordPolicyUse, void(int));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PolicyStatisticsCollectorTest : public testing::Test {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyStatisticsCollectorTest()
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : update_delay_(base::TimeDelta::FromMilliseconds(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PolicyStatisticsCollector::kStatisticsUpdateRate)),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        task_runner_(new base::TestSimpleTaskRunner()) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string error;
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    chrome_schema_ = Schema::Parse(kTestChromeSchema, &error);
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(chrome_schema_.valid()) << error;
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    policy_details_.SetDetails(kTestPolicy1, &kTestPolicyDetails[0]);
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    policy_details_.SetDetails(kTestPolicy2, &kTestPolicyDetails[1]);
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs_.registry()->RegisterInt64Pref(
898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        policy_prefs::kLastPolicyStatisticsUpdate, 0);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up default function behaviour.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(policy_service_,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetPolicies(PolicyNamespace(POLICY_DOMAIN_CHROME,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            std::string())))
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillRepeatedly(ReturnRef(policy_map_));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Arbitrary negative value (so it'll be different from |update_delay_|).
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_delay_ = base::TimeDelta::FromDays(-1);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy_map_.Clear();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    policy_statistics_collector_.reset(new TestPolicyStatisticsCollector(
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        policy_details_.GetCallback(),
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        chrome_schema_,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &policy_service_,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &prefs_,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        task_runner_));
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetPolicy(const std::string& name) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    policy_map_.Set(name,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    POLICY_LEVEL_MANDATORY,
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    POLICY_SCOPE_USER,
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    new base::FundamentalValue(true),
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    NULL);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta GetFirstDelay() const {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (task_runner_->GetPendingTasks().empty()) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ADD_FAILURE();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::TimeDelta();
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return task_runner_->GetPendingTasks().front().delay;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::TimeDelta update_delay_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta last_delay_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyDetailsMap policy_details_;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema chrome_schema_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestingPrefServiceSimple prefs_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockPolicyService policy_service_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PolicyMap policy_map_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestPolicyStatisticsCollector> policy_statistics_collector_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyStatisticsCollectorTest, CollectPending) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPolicy(kTestPolicy1);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (base::Time::Now() - update_delay_).ToInternalValue());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*policy_statistics_collector_.get(),
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              RecordPolicyUse(kTestPolicy1Id));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy_statistics_collector_->Initialize();
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(update_delay_, GetFirstDelay());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyStatisticsCollectorTest, CollectPendingVeryOld) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPolicy(kTestPolicy1);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Must not be 0.0 (read comment for Time::FromDoubleT).
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  base::Time::FromDoubleT(1.0).ToInternalValue());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*policy_statistics_collector_.get(),
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              RecordPolicyUse(kTestPolicy1Id));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy_statistics_collector_->Initialize();
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(update_delay_, GetFirstDelay());
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyStatisticsCollectorTest, CollectLater) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPolicy(kTestPolicy1);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (base::Time::Now() - update_delay_ / 2).ToInternalValue());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy_statistics_collector_->Initialize();
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LT(GetFirstDelay(), update_delay_);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PolicyStatisticsCollectorTest, MultiplePolicies) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPolicy(kTestPolicy1);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPolicy(kTestPolicy2);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  (base::Time::Now() - update_delay_).ToInternalValue());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*policy_statistics_collector_.get(),
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              RecordPolicyUse(kTestPolicy1Id));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*policy_statistics_collector_.get(),
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              RecordPolicyUse(kTestPolicy2Id));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  policy_statistics_collector_->Initialize();
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
195