• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "components/policy/core/common/cloud/cloud_policy_manager.h"
6 
7 #include "base/basictypes.h"
8 #include "base/callback.h"
9 #include "base/compiler_specific.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
13 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
14 #include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
15 #include "components/policy/core/common/cloud/policy_builder.h"
16 #include "components/policy/core/common/configuration_policy_provider_test.h"
17 #include "components/policy/core/common/external_data_fetcher.h"
18 #include "components/policy/core/common/mock_configuration_policy_provider.h"
19 #include "components/policy/core/common/schema_registry.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 using testing::Mock;
24 using testing::_;
25 
26 namespace em = enterprise_management;
27 
28 namespace policy {
29 namespace {
30 
31 class TestHarness : public PolicyProviderTestHarness {
32  public:
33   explicit TestHarness(PolicyLevel level);
34   virtual ~TestHarness();
35 
36   virtual void SetUp() OVERRIDE;
37 
38   virtual ConfigurationPolicyProvider* CreateProvider(
39       SchemaRegistry* registry,
40       scoped_refptr<base::SequencedTaskRunner> task_runner) OVERRIDE;
41 
42   virtual void InstallEmptyPolicy() OVERRIDE;
43   virtual void InstallStringPolicy(const std::string& policy_name,
44                                    const std::string& policy_value) OVERRIDE;
45   virtual void InstallIntegerPolicy(const std::string& policy_name,
46                                     int policy_value) OVERRIDE;
47   virtual void InstallBooleanPolicy(const std::string& policy_name,
48                                     bool policy_value) OVERRIDE;
49   virtual void InstallStringListPolicy(
50       const std::string& policy_name,
51       const base::ListValue* policy_value) OVERRIDE;
52   virtual void InstallDictionaryPolicy(
53       const std::string& policy_name,
54       const base::DictionaryValue* policy_value) OVERRIDE;
55 
56   // Creates harnesses for mandatory and recommended levels, respectively.
57   static PolicyProviderTestHarness* CreateMandatory();
58   static PolicyProviderTestHarness* CreateRecommended();
59 
60  private:
61   MockCloudPolicyStore store_;
62 
63   DISALLOW_COPY_AND_ASSIGN(TestHarness);
64 };
65 
TestHarness(PolicyLevel level)66 TestHarness::TestHarness(PolicyLevel level)
67     : PolicyProviderTestHarness(level, POLICY_SCOPE_USER) {}
68 
~TestHarness()69 TestHarness::~TestHarness() {}
70 
SetUp()71 void TestHarness::SetUp() {}
72 
CreateProvider(SchemaRegistry * registry,scoped_refptr<base::SequencedTaskRunner> task_runner)73 ConfigurationPolicyProvider* TestHarness::CreateProvider(
74     SchemaRegistry* registry,
75     scoped_refptr<base::SequencedTaskRunner> task_runner) {
76   // Create and initialize the store.
77   store_.NotifyStoreLoaded();
78   ConfigurationPolicyProvider* provider = new CloudPolicyManager(
79       PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, std::string()),
80       &store_,
81       task_runner,
82       task_runner,
83       task_runner);
84   Mock::VerifyAndClearExpectations(&store_);
85   return provider;
86 }
87 
InstallEmptyPolicy()88 void TestHarness::InstallEmptyPolicy() {}
89 
InstallStringPolicy(const std::string & policy_name,const std::string & policy_value)90 void TestHarness::InstallStringPolicy(const std::string& policy_name,
91                                       const std::string& policy_value) {
92   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
93                          base::Value::CreateStringValue(policy_value), NULL);
94 }
95 
InstallIntegerPolicy(const std::string & policy_name,int policy_value)96 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
97                                        int policy_value) {
98   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
99                          base::Value::CreateIntegerValue(policy_value), NULL);
100 }
101 
InstallBooleanPolicy(const std::string & policy_name,bool policy_value)102 void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
103                                        bool policy_value) {
104   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
105                          base::Value::CreateBooleanValue(policy_value), NULL);
106 }
107 
InstallStringListPolicy(const std::string & policy_name,const base::ListValue * policy_value)108 void TestHarness::InstallStringListPolicy(const std::string& policy_name,
109                                           const base::ListValue* policy_value) {
110   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
111                          policy_value->DeepCopy(), NULL);
112 }
113 
InstallDictionaryPolicy(const std::string & policy_name,const base::DictionaryValue * policy_value)114 void TestHarness::InstallDictionaryPolicy(
115     const std::string& policy_name,
116     const base::DictionaryValue* policy_value) {
117   store_.policy_map_.Set(policy_name, policy_level(), policy_scope(),
118                          policy_value->DeepCopy(), NULL);
119 }
120 
121 // static
CreateMandatory()122 PolicyProviderTestHarness* TestHarness::CreateMandatory() {
123   return new TestHarness(POLICY_LEVEL_MANDATORY);
124 }
125 
126 // static
CreateRecommended()127 PolicyProviderTestHarness* TestHarness::CreateRecommended() {
128   return new TestHarness(POLICY_LEVEL_RECOMMENDED);
129 }
130 
131 // Instantiate abstract test case for basic policy reading tests.
132 INSTANTIATE_TEST_CASE_P(
133     UserCloudPolicyManagerProviderTest,
134     ConfigurationPolicyProviderTest,
135     testing::Values(TestHarness::CreateMandatory,
136                     TestHarness::CreateRecommended));
137 
138 class TestCloudPolicyManager : public CloudPolicyManager {
139  public:
TestCloudPolicyManager(CloudPolicyStore * store,const scoped_refptr<base::SequencedTaskRunner> & task_runner)140   TestCloudPolicyManager(
141       CloudPolicyStore* store,
142       const scoped_refptr<base::SequencedTaskRunner>& task_runner)
143       : CloudPolicyManager(PolicyNamespaceKey(
144                                dm_protocol::kChromeUserPolicyType,
145                                std::string()),
146                            store,
147                            task_runner,
148                            task_runner,
149                            task_runner) {}
~TestCloudPolicyManager()150   virtual ~TestCloudPolicyManager() {}
151 
152   // Publish the protected members for testing.
153   using CloudPolicyManager::client;
154   using CloudPolicyManager::store;
155   using CloudPolicyManager::service;
156   using CloudPolicyManager::CheckAndPublishPolicy;
157 
158  private:
159   DISALLOW_COPY_AND_ASSIGN(TestCloudPolicyManager);
160 };
161 
162 MATCHER_P(ProtoMatches, proto, "") {
163   return arg.SerializePartialAsString() == proto.SerializePartialAsString();
164 }
165 
166 class CloudPolicyManagerTest : public testing::Test {
167  protected:
CloudPolicyManagerTest()168   CloudPolicyManagerTest()
169       : policy_ns_key_(dm_protocol::kChromeUserPolicyType, std::string()) {}
170 
SetUp()171   virtual void SetUp() OVERRIDE {
172     // Set up a policy map for testing.
173     policy_map_.Set("key", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
174                     base::Value::CreateStringValue("value"), NULL);
175     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
176         .CopyFrom(policy_map_);
177 
178     policy_.payload().mutable_passwordmanagerenabled()->set_value(false);
179     policy_.Build();
180 
181     EXPECT_CALL(store_, Load());
182     manager_.reset(new TestCloudPolicyManager(&store_,
183                                               loop_.message_loop_proxy()));
184     manager_->Init(&schema_registry_);
185     Mock::VerifyAndClearExpectations(&store_);
186     manager_->AddObserver(&observer_);
187   }
188 
TearDown()189   virtual void TearDown() OVERRIDE {
190     manager_->RemoveObserver(&observer_);
191     manager_->Shutdown();
192   }
193 
194   // Required by the refresh scheduler that's created by the manager.
195   base::MessageLoop loop_;
196 
197   // Testing policy.
198   const PolicyNamespaceKey policy_ns_key_;
199   UserPolicyBuilder policy_;
200   PolicyMap policy_map_;
201   PolicyBundle expected_bundle_;
202 
203   // Policy infrastructure.
204   SchemaRegistry schema_registry_;
205   MockConfigurationPolicyObserver observer_;
206   MockCloudPolicyStore store_;
207   scoped_ptr<TestCloudPolicyManager> manager_;
208 
209  private:
210   DISALLOW_COPY_AND_ASSIGN(CloudPolicyManagerTest);
211 };
212 
TEST_F(CloudPolicyManagerTest,InitAndShutdown)213 TEST_F(CloudPolicyManagerTest, InitAndShutdown) {
214   PolicyBundle empty_bundle;
215   EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));
216   EXPECT_FALSE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
217 
218   EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
219   manager_->CheckAndPublishPolicy();
220   Mock::VerifyAndClearExpectations(&observer_);
221 
222   store_.policy_map_.CopyFrom(policy_map_);
223   store_.policy_.reset(new em::PolicyData(policy_.policy_data()));
224   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
225   store_.NotifyStoreLoaded();
226   Mock::VerifyAndClearExpectations(&observer_);
227   EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
228   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
229 
230   MockCloudPolicyClient* client = new MockCloudPolicyClient();
231   EXPECT_CALL(*client, SetupRegistration(_, _));
232   manager_->core()->Connect(scoped_ptr<CloudPolicyClient>(client));
233   Mock::VerifyAndClearExpectations(client);
234   EXPECT_TRUE(manager_->client());
235   EXPECT_TRUE(manager_->service());
236 
237   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
238   manager_->CheckAndPublishPolicy();
239   Mock::VerifyAndClearExpectations(&observer_);
240 
241   manager_->core()->Disconnect();
242   EXPECT_FALSE(manager_->client());
243   EXPECT_FALSE(manager_->service());
244 }
245 
TEST_F(CloudPolicyManagerTest,RegistrationAndFetch)246 TEST_F(CloudPolicyManagerTest, RegistrationAndFetch) {
247   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
248   store_.NotifyStoreLoaded();
249   Mock::VerifyAndClearExpectations(&observer_);
250   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
251 
252   MockCloudPolicyClient* client = new MockCloudPolicyClient();
253   manager_->core()->Connect(scoped_ptr<CloudPolicyClient>(client));
254 
255   client->SetDMToken(policy_.policy_data().request_token());
256   client->NotifyRegistrationStateChanged();
257 
258   client->SetPolicy(policy_ns_key_, policy_.policy());
259   EXPECT_CALL(store_, Store(ProtoMatches(policy_.policy())));
260   client->NotifyPolicyFetched();
261   Mock::VerifyAndClearExpectations(&store_);
262 
263   store_.policy_map_.CopyFrom(policy_map_);
264   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
265   store_.NotifyStoreLoaded();
266   Mock::VerifyAndClearExpectations(&observer_);
267   EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
268 }
269 
TEST_F(CloudPolicyManagerTest,Update)270 TEST_F(CloudPolicyManagerTest, Update) {
271   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
272   store_.NotifyStoreLoaded();
273   Mock::VerifyAndClearExpectations(&observer_);
274   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
275   PolicyBundle empty_bundle;
276   EXPECT_TRUE(empty_bundle.Equals(manager_->policies()));
277 
278   store_.policy_map_.CopyFrom(policy_map_);
279   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
280   store_.NotifyStoreLoaded();
281   Mock::VerifyAndClearExpectations(&observer_);
282   EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
283   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
284 }
285 
TEST_F(CloudPolicyManagerTest,RefreshNotRegistered)286 TEST_F(CloudPolicyManagerTest, RefreshNotRegistered) {
287   MockCloudPolicyClient* client = new MockCloudPolicyClient();
288   manager_->core()->Connect(scoped_ptr<CloudPolicyClient>(client));
289 
290   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
291   store_.NotifyStoreLoaded();
292   Mock::VerifyAndClearExpectations(&observer_);
293 
294   // A refresh on a non-registered store should not block.
295   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
296   manager_->RefreshPolicies();
297   Mock::VerifyAndClearExpectations(&observer_);
298 }
299 
TEST_F(CloudPolicyManagerTest,RefreshSuccessful)300 TEST_F(CloudPolicyManagerTest, RefreshSuccessful) {
301   MockCloudPolicyClient* client = new MockCloudPolicyClient();
302   manager_->core()->Connect(scoped_ptr<CloudPolicyClient>(client));
303 
304   // Simulate a store load.
305   store_.policy_.reset(new em::PolicyData(policy_.policy_data()));
306   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
307   EXPECT_CALL(*client, SetupRegistration(_, _));
308   store_.NotifyStoreLoaded();
309   Mock::VerifyAndClearExpectations(client);
310   Mock::VerifyAndClearExpectations(&observer_);
311 
312   // Acknowledge registration.
313   client->SetDMToken(policy_.policy_data().request_token());
314 
315   // Start a refresh.
316   EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
317   EXPECT_CALL(*client, FetchPolicy());
318   manager_->RefreshPolicies();
319   Mock::VerifyAndClearExpectations(client);
320   Mock::VerifyAndClearExpectations(&observer_);
321   store_.policy_map_.CopyFrom(policy_map_);
322 
323   // A stray reload should be suppressed until the refresh completes.
324   EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
325   store_.NotifyStoreLoaded();
326   Mock::VerifyAndClearExpectations(&observer_);
327 
328   // Respond to the policy fetch, which should trigger a write to |store_|.
329   EXPECT_CALL(observer_, OnUpdatePolicy(_)).Times(0);
330   EXPECT_CALL(store_, Store(_));
331   client->SetPolicy(policy_ns_key_, policy_.policy());
332   client->NotifyPolicyFetched();
333   Mock::VerifyAndClearExpectations(&observer_);
334   Mock::VerifyAndClearExpectations(&store_);
335 
336   // The load notification from |store_| should trigger the policy update.
337   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
338   store_.NotifyStoreLoaded();
339   EXPECT_TRUE(expected_bundle_.Equals(manager_->policies()));
340   Mock::VerifyAndClearExpectations(&observer_);
341 }
342 
TEST_F(CloudPolicyManagerTest,SignalOnError)343 TEST_F(CloudPolicyManagerTest, SignalOnError) {
344   // Simulate a failed load and verify that it triggers OnUpdatePolicy().
345   store_.policy_.reset(new em::PolicyData(policy_.policy_data()));
346   EXPECT_CALL(observer_, OnUpdatePolicy(manager_.get()));
347   store_.NotifyStoreError();
348   Mock::VerifyAndClearExpectations(&observer_);
349 
350   EXPECT_TRUE(manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME));
351 }
352 
353 }  // namespace
354 }  // namespace policy
355