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
3// found in the LICENSE file.
4
5#include <cstring>
6#include <string>
7
8#include "base/callback.h"
9#include "base/compiler_specific.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/prefs/pref_registry_simple.h"
12#include "base/prefs/testing_pref_service.h"
13#include "base/test/test_simple_task_runner.h"
14#include "base/values.h"
15#include "components/policy/core/common/external_data_fetcher.h"
16#include "components/policy/core/common/mock_policy_service.h"
17#include "components/policy/core/common/policy_map.h"
18#include "components/policy/core/common/policy_pref_names.h"
19#include "components/policy/core/common/policy_statistics_collector.h"
20#include "components/policy/core/common/policy_test_utils.h"
21#include "components/policy/core/common/policy_types.h"
22#include "testing/gmock/include/gmock/gmock.h"
23#include "testing/gtest/include/gtest/gtest.h"
24
25namespace policy {
26
27namespace {
28
29using testing::ReturnRef;
30
31// Arbitrary policy names used for testing.
32const char kTestPolicy1[] = "Test Policy 1";
33const char kTestPolicy2[] = "Test Policy 2";
34
35const int kTestPolicy1Id = 42;
36const int kTestPolicy2Id = 123;
37
38const char kTestChromeSchema[] =
39    "{"
40    "  \"type\": \"object\","
41    "  \"properties\": {"
42    "    \"Test Policy 1\": { \"type\": \"string\" },"
43    "    \"Test Policy 2\": { \"type\": \"string\" }"
44    "  }"
45    "}";
46
47const PolicyDetails kTestPolicyDetails[] = {
48  // is_deprecated  is_device_policy              id  max_external_data_size
49  {          false,            false, kTestPolicy1Id,                      0 },
50  {          false,            false, kTestPolicy2Id,                      0 },
51};
52
53class TestPolicyStatisticsCollector : public PolicyStatisticsCollector {
54 public:
55  TestPolicyStatisticsCollector(
56      const GetChromePolicyDetailsCallback& get_details,
57      const Schema& chrome_schema,
58      PolicyService* policy_service,
59      PrefService* prefs,
60      const scoped_refptr<base::TaskRunner>& task_runner)
61      : PolicyStatisticsCollector(get_details,
62                                  chrome_schema,
63                                  policy_service,
64                                  prefs,
65                                  task_runner) {}
66
67  MOCK_METHOD1(RecordPolicyUse, void(int));
68};
69
70}  // namespace
71
72class PolicyStatisticsCollectorTest : public testing::Test {
73 protected:
74  PolicyStatisticsCollectorTest()
75      : update_delay_(base::TimeDelta::FromMilliseconds(
76            PolicyStatisticsCollector::kStatisticsUpdateRate)),
77        task_runner_(new base::TestSimpleTaskRunner()) {
78  }
79
80  virtual void SetUp() OVERRIDE {
81    std::string error;
82    chrome_schema_ = Schema::Parse(kTestChromeSchema, &error);
83    ASSERT_TRUE(chrome_schema_.valid()) << error;
84
85    policy_details_.SetDetails(kTestPolicy1, &kTestPolicyDetails[0]);
86    policy_details_.SetDetails(kTestPolicy2, &kTestPolicyDetails[1]);
87
88    prefs_.registry()->RegisterInt64Pref(
89        policy_prefs::kLastPolicyStatisticsUpdate, 0);
90
91    // Set up default function behaviour.
92    EXPECT_CALL(policy_service_,
93                GetPolicies(PolicyNamespace(POLICY_DOMAIN_CHROME,
94                                            std::string())))
95        .WillRepeatedly(ReturnRef(policy_map_));
96
97    // Arbitrary negative value (so it'll be different from |update_delay_|).
98    last_delay_ = base::TimeDelta::FromDays(-1);
99    policy_map_.Clear();
100    policy_statistics_collector_.reset(new TestPolicyStatisticsCollector(
101        policy_details_.GetCallback(),
102        chrome_schema_,
103        &policy_service_,
104        &prefs_,
105        task_runner_));
106  }
107
108  void SetPolicy(const std::string& name) {
109    policy_map_.Set(name,
110                    POLICY_LEVEL_MANDATORY,
111                    POLICY_SCOPE_USER,
112                    new base::FundamentalValue(true),
113                    NULL);
114  }
115
116  base::TimeDelta GetFirstDelay() const {
117    if (task_runner_->GetPendingTasks().empty()) {
118      ADD_FAILURE();
119      return base::TimeDelta();
120    }
121    return task_runner_->GetPendingTasks().front().delay;
122  }
123
124  const base::TimeDelta update_delay_;
125
126  base::TimeDelta last_delay_;
127
128  PolicyDetailsMap policy_details_;
129  Schema chrome_schema_;
130  TestingPrefServiceSimple prefs_;
131  MockPolicyService policy_service_;
132  PolicyMap policy_map_;
133
134  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
135  scoped_ptr<TestPolicyStatisticsCollector> policy_statistics_collector_;
136};
137
138TEST_F(PolicyStatisticsCollectorTest, CollectPending) {
139  SetPolicy(kTestPolicy1);
140
141  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
142                  (base::Time::Now() - update_delay_).ToInternalValue());
143
144  EXPECT_CALL(*policy_statistics_collector_.get(),
145              RecordPolicyUse(kTestPolicy1Id));
146
147  policy_statistics_collector_->Initialize();
148  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
149  EXPECT_EQ(update_delay_, GetFirstDelay());
150}
151
152TEST_F(PolicyStatisticsCollectorTest, CollectPendingVeryOld) {
153  SetPolicy(kTestPolicy1);
154
155  // Must not be 0.0 (read comment for Time::FromDoubleT).
156  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
157                  base::Time::FromDoubleT(1.0).ToInternalValue());
158
159  EXPECT_CALL(*policy_statistics_collector_.get(),
160              RecordPolicyUse(kTestPolicy1Id));
161
162  policy_statistics_collector_->Initialize();
163  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
164  EXPECT_EQ(update_delay_, GetFirstDelay());
165}
166
167TEST_F(PolicyStatisticsCollectorTest, CollectLater) {
168  SetPolicy(kTestPolicy1);
169
170  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
171                  (base::Time::Now() - update_delay_ / 2).ToInternalValue());
172
173  policy_statistics_collector_->Initialize();
174  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
175  EXPECT_LT(GetFirstDelay(), update_delay_);
176}
177
178TEST_F(PolicyStatisticsCollectorTest, MultiplePolicies) {
179  SetPolicy(kTestPolicy1);
180  SetPolicy(kTestPolicy2);
181
182  prefs_.SetInt64(policy_prefs::kLastPolicyStatisticsUpdate,
183                  (base::Time::Now() - update_delay_).ToInternalValue());
184
185  EXPECT_CALL(*policy_statistics_collector_.get(),
186              RecordPolicyUse(kTestPolicy1Id));
187  EXPECT_CALL(*policy_statistics_collector_.get(),
188              RecordPolicyUse(kTestPolicy2Id));
189
190  policy_statistics_collector_->Initialize();
191  EXPECT_EQ(1u, task_runner_->GetPendingTasks().size());
192}
193
194}  // namespace policy
195