OLD | NEW |
| (Empty) |
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/configuration_policy_provider_test.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback.h" | |
9 #include "base/message_loop/message_loop_proxy.h" | |
10 #include "base/values.h" | |
11 #include "components/policy/core/common/configuration_policy_provider.h" | |
12 #include "components/policy/core/common/external_data_fetcher.h" | |
13 #include "components/policy/core/common/mock_configuration_policy_provider.h" | |
14 #include "components/policy/core/common/policy_bundle.h" | |
15 #include "components/policy/core/common/policy_map.h" | |
16 #include "components/policy/core/common/policy_namespace.h" | |
17 #include "testing/gmock/include/gmock/gmock.h" | |
18 | |
19 using ::testing::Mock; | |
20 using ::testing::_; | |
21 | |
22 namespace policy { | |
23 | |
24 const char kTestChromeSchema[] = | |
25 "{" | |
26 " \"type\": \"object\"," | |
27 " \"properties\": {" | |
28 " \"StringPolicy\": { \"type\": \"string\" }," | |
29 " \"BooleanPolicy\": { \"type\": \"boolean\" }," | |
30 " \"IntegerPolicy\": { \"type\": \"integer\" }," | |
31 " \"StringListPolicy\": {" | |
32 " \"type\": \"array\"," | |
33 " \"items\": { \"type\": \"string\" }" | |
34 " }," | |
35 " \"DictionaryPolicy\": {" | |
36 " \"type\": \"object\"," | |
37 " \"properties\": {" | |
38 " \"bool\": { \"type\": \"boolean\" }," | |
39 " \"double\": { \"type\": \"number\" }," | |
40 " \"int\": { \"type\": \"integer\" }," | |
41 " \"string\": { \"type\": \"string\" }," | |
42 " \"array\": {" | |
43 " \"type\": \"array\"," | |
44 " \"items\": { \"type\": \"string\" }" | |
45 " }," | |
46 " \"dictionary\": {" | |
47 " \"type\": \"object\"," | |
48 " \"properties\": {" | |
49 " \"sub\": { \"type\": \"string\" }," | |
50 " \"sublist\": {" | |
51 " \"type\": \"array\"," | |
52 " \"items\": {" | |
53 " \"type\": \"object\"," | |
54 " \"properties\": {" | |
55 " \"aaa\": { \"type\": \"integer\" }," | |
56 " \"bbb\": { \"type\": \"integer\" }," | |
57 " \"ccc\": { \"type\": \"string\" }," | |
58 " \"ddd\": { \"type\": \"string\" }" | |
59 " }" | |
60 " }" | |
61 " }" | |
62 " }" | |
63 " }," | |
64 " \"list\": {" | |
65 " \"type\": \"array\"," | |
66 " \"items\": {" | |
67 " \"type\": \"object\"," | |
68 " \"properties\": {" | |
69 " \"subdictindex\": { \"type\": \"integer\" }," | |
70 " \"subdict\": {" | |
71 " \"type\": \"object\"," | |
72 " \"properties\": {" | |
73 " \"bool\": { \"type\": \"boolean\" }," | |
74 " \"double\": { \"type\": \"number\" }," | |
75 " \"int\": { \"type\": \"integer\" }," | |
76 " \"string\": { \"type\": \"string\" }" | |
77 " }" | |
78 " }" | |
79 " }" | |
80 " }" | |
81 " }," | |
82 " \"dict\": {" | |
83 " \"type\": \"object\"," | |
84 " \"properties\": {" | |
85 " \"bool\": { \"type\": \"boolean\" }," | |
86 " \"double\": { \"type\": \"number\" }," | |
87 " \"int\": { \"type\": \"integer\" }," | |
88 " \"string\": { \"type\": \"string\" }," | |
89 " \"list\": {" | |
90 " \"type\": \"array\"," | |
91 " \"items\": {" | |
92 " \"type\": \"object\"," | |
93 " \"properties\": {" | |
94 " \"subdictindex\": { \"type\": \"integer\" }," | |
95 " \"subdict\": {" | |
96 " \"type\": \"object\"," | |
97 " \"properties\": {" | |
98 " \"bool\": { \"type\": \"boolean\" }," | |
99 " \"double\": { \"type\": \"number\" }," | |
100 " \"int\": { \"type\": \"integer\" }," | |
101 " \"string\": { \"type\": \"string\" }" | |
102 " }" | |
103 " }" | |
104 " }" | |
105 " }" | |
106 " }" | |
107 " }" | |
108 " }" | |
109 " }" | |
110 " }" | |
111 " }" | |
112 "}"; | |
113 | |
114 namespace test_keys { | |
115 | |
116 const char kKeyString[] = "StringPolicy"; | |
117 const char kKeyBoolean[] = "BooleanPolicy"; | |
118 const char kKeyInteger[] = "IntegerPolicy"; | |
119 const char kKeyStringList[] = "StringListPolicy"; | |
120 const char kKeyDictionary[] = "DictionaryPolicy"; | |
121 | |
122 } // namespace test_keys | |
123 | |
124 PolicyTestBase::PolicyTestBase() {} | |
125 | |
126 PolicyTestBase::~PolicyTestBase() {} | |
127 | |
128 void PolicyTestBase::SetUp() { | |
129 std::string error; | |
130 chrome_schema_ = Schema::Parse(kTestChromeSchema, &error); | |
131 ASSERT_TRUE(chrome_schema_.valid()) << error; | |
132 schema_registry_.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), | |
133 chrome_schema_); | |
134 } | |
135 | |
136 void PolicyTestBase::TearDown() { | |
137 loop_.RunUntilIdle(); | |
138 } | |
139 | |
140 PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level, | |
141 PolicyScope scope) | |
142 : level_(level), scope_(scope) {} | |
143 | |
144 PolicyProviderTestHarness::~PolicyProviderTestHarness() {} | |
145 | |
146 PolicyLevel PolicyProviderTestHarness::policy_level() const { | |
147 return level_; | |
148 } | |
149 | |
150 PolicyScope PolicyProviderTestHarness::policy_scope() const { | |
151 return scope_; | |
152 } | |
153 | |
154 void PolicyProviderTestHarness::Install3rdPartyPolicy( | |
155 const base::DictionaryValue* policies) { | |
156 FAIL(); | |
157 } | |
158 | |
159 ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {} | |
160 | |
161 ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {} | |
162 | |
163 void ConfigurationPolicyProviderTest::SetUp() { | |
164 PolicyTestBase::SetUp(); | |
165 | |
166 test_harness_.reset((*GetParam())()); | |
167 test_harness_->SetUp(); | |
168 | |
169 Schema extension_schema = | |
170 chrome_schema_.GetKnownProperty(test_keys::kKeyDictionary); | |
171 ASSERT_TRUE(extension_schema.valid()); | |
172 schema_registry_.RegisterComponent( | |
173 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, | |
174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), | |
175 extension_schema); | |
176 schema_registry_.RegisterComponent( | |
177 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, | |
178 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), | |
179 extension_schema); | |
180 schema_registry_.RegisterComponent( | |
181 PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, | |
182 "cccccccccccccccccccccccccccccccc"), | |
183 extension_schema); | |
184 | |
185 provider_.reset(test_harness_->CreateProvider(&schema_registry_, | |
186 loop_.message_loop_proxy())); | |
187 provider_->Init(&schema_registry_); | |
188 // Some providers do a reload on init. Make sure any notifications generated | |
189 // are fired now. | |
190 loop_.RunUntilIdle(); | |
191 | |
192 const PolicyBundle kEmptyBundle; | |
193 EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle)); | |
194 } | |
195 | |
196 void ConfigurationPolicyProviderTest::TearDown() { | |
197 // Give providers the chance to clean up after themselves on the file thread. | |
198 provider_->Shutdown(); | |
199 provider_.reset(); | |
200 | |
201 PolicyTestBase::TearDown(); | |
202 } | |
203 | |
204 void ConfigurationPolicyProviderTest::CheckValue( | |
205 const char* policy_name, | |
206 const base::Value& expected_value, | |
207 base::Closure install_value) { | |
208 // Install the value, reload policy and check the provider for the value. | |
209 install_value.Run(); | |
210 provider_->RefreshPolicies(); | |
211 loop_.RunUntilIdle(); | |
212 PolicyBundle expected_bundle; | |
213 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) | |
214 .Set(policy_name, | |
215 test_harness_->policy_level(), | |
216 test_harness_->policy_scope(), | |
217 expected_value.DeepCopy(), | |
218 NULL); | |
219 EXPECT_TRUE(provider_->policies().Equals(expected_bundle)); | |
220 // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too, | |
221 // and extend the |expected_bundle|, once all providers are ready. | |
222 } | |
223 | |
224 TEST_P(ConfigurationPolicyProviderTest, Empty) { | |
225 provider_->RefreshPolicies(); | |
226 loop_.RunUntilIdle(); | |
227 const PolicyBundle kEmptyBundle; | |
228 EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle)); | |
229 } | |
230 | |
231 TEST_P(ConfigurationPolicyProviderTest, StringValue) { | |
232 const char kTestString[] = "string_value"; | |
233 base::StringValue expected_value(kTestString); | |
234 CheckValue(test_keys::kKeyString, | |
235 expected_value, | |
236 base::Bind(&PolicyProviderTestHarness::InstallStringPolicy, | |
237 base::Unretained(test_harness_.get()), | |
238 test_keys::kKeyString, | |
239 kTestString)); | |
240 } | |
241 | |
242 TEST_P(ConfigurationPolicyProviderTest, BooleanValue) { | |
243 base::FundamentalValue expected_value(true); | |
244 CheckValue(test_keys::kKeyBoolean, | |
245 expected_value, | |
246 base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy, | |
247 base::Unretained(test_harness_.get()), | |
248 test_keys::kKeyBoolean, | |
249 true)); | |
250 } | |
251 | |
252 TEST_P(ConfigurationPolicyProviderTest, IntegerValue) { | |
253 base::FundamentalValue expected_value(42); | |
254 CheckValue(test_keys::kKeyInteger, | |
255 expected_value, | |
256 base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy, | |
257 base::Unretained(test_harness_.get()), | |
258 test_keys::kKeyInteger, | |
259 42)); | |
260 } | |
261 | |
262 TEST_P(ConfigurationPolicyProviderTest, StringListValue) { | |
263 base::ListValue expected_value; | |
264 expected_value.Set(0U, base::Value::CreateStringValue("first")); | |
265 expected_value.Set(1U, base::Value::CreateStringValue("second")); | |
266 CheckValue(test_keys::kKeyStringList, | |
267 expected_value, | |
268 base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy, | |
269 base::Unretained(test_harness_.get()), | |
270 test_keys::kKeyStringList, | |
271 &expected_value)); | |
272 } | |
273 | |
274 TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) { | |
275 base::DictionaryValue expected_value; | |
276 expected_value.SetBoolean("bool", true); | |
277 expected_value.SetDouble("double", 123.456); | |
278 expected_value.SetInteger("int", 123); | |
279 expected_value.SetString("string", "omg"); | |
280 | |
281 base::ListValue* list = new base::ListValue(); | |
282 list->Set(0U, base::Value::CreateStringValue("first")); | |
283 list->Set(1U, base::Value::CreateStringValue("second")); | |
284 expected_value.Set("array", list); | |
285 | |
286 base::DictionaryValue* dict = new base::DictionaryValue(); | |
287 dict->SetString("sub", "value"); | |
288 list = new base::ListValue(); | |
289 base::DictionaryValue* sub = new base::DictionaryValue(); | |
290 sub->SetInteger("aaa", 111); | |
291 sub->SetInteger("bbb", 222); | |
292 list->Append(sub); | |
293 sub = new base::DictionaryValue(); | |
294 sub->SetString("ccc", "333"); | |
295 sub->SetString("ddd", "444"); | |
296 list->Append(sub); | |
297 dict->Set("sublist", list); | |
298 expected_value.Set("dictionary", dict); | |
299 | |
300 CheckValue(test_keys::kKeyDictionary, | |
301 expected_value, | |
302 base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy, | |
303 base::Unretained(test_harness_.get()), | |
304 test_keys::kKeyDictionary, | |
305 &expected_value)); | |
306 } | |
307 | |
308 TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) { | |
309 PolicyBundle bundle; | |
310 EXPECT_TRUE(provider_->policies().Equals(bundle)); | |
311 | |
312 // OnUpdatePolicy is called even when there are no changes. | |
313 MockConfigurationPolicyObserver observer; | |
314 provider_->AddObserver(&observer); | |
315 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); | |
316 provider_->RefreshPolicies(); | |
317 loop_.RunUntilIdle(); | |
318 Mock::VerifyAndClearExpectations(&observer); | |
319 | |
320 EXPECT_TRUE(provider_->policies().Equals(bundle)); | |
321 | |
322 // OnUpdatePolicy is called when there are changes. | |
323 test_harness_->InstallStringPolicy(test_keys::kKeyString, "value"); | |
324 EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); | |
325 provider_->RefreshPolicies(); | |
326 loop_.RunUntilIdle(); | |
327 Mock::VerifyAndClearExpectations(&observer); | |
328 | |
329 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) | |
330 .Set(test_keys::kKeyString, | |
331 test_harness_->policy_level(), | |
332 test_harness_->policy_scope(), | |
333 base::Value::CreateStringValue("value"), | |
334 NULL); | |
335 EXPECT_TRUE(provider_->policies().Equals(bundle)); | |
336 provider_->RemoveObserver(&observer); | |
337 } | |
338 | |
339 Configuration3rdPartyPolicyProviderTest:: | |
340 Configuration3rdPartyPolicyProviderTest() {} | |
341 | |
342 Configuration3rdPartyPolicyProviderTest:: | |
343 ~Configuration3rdPartyPolicyProviderTest() {} | |
344 | |
345 TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) { | |
346 base::DictionaryValue policy_dict; | |
347 policy_dict.SetBoolean("bool", true); | |
348 policy_dict.SetDouble("double", 123.456); | |
349 policy_dict.SetInteger("int", 789); | |
350 policy_dict.SetString("string", "string value"); | |
351 | |
352 base::ListValue* list = new base::ListValue(); | |
353 for (int i = 0; i < 2; ++i) { | |
354 base::DictionaryValue* dict = new base::DictionaryValue(); | |
355 dict->SetInteger("subdictindex", i); | |
356 dict->Set("subdict", policy_dict.DeepCopy()); | |
357 list->Append(dict); | |
358 } | |
359 policy_dict.Set("list", list); | |
360 policy_dict.Set("dict", policy_dict.DeepCopy()); | |
361 | |
362 // Install these policies as a Chrome policy. | |
363 test_harness_->InstallDictionaryPolicy(test_keys::kKeyDictionary, | |
364 &policy_dict); | |
365 // Install them as 3rd party policies too. | |
366 base::DictionaryValue policy_3rdparty; | |
367 policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", | |
368 policy_dict.DeepCopy()); | |
369 policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", | |
370 policy_dict.DeepCopy()); | |
371 // Install invalid 3rd party policies that shouldn't be loaded. These also | |
372 // help detecting memory leaks in the code paths that detect invalid input. | |
373 policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy()); | |
374 policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc", | |
375 base::Value::CreateStringValue("invalid-value")); | |
376 test_harness_->Install3rdPartyPolicy(&policy_3rdparty); | |
377 | |
378 provider_->RefreshPolicies(); | |
379 loop_.RunUntilIdle(); | |
380 | |
381 PolicyMap expected_policy; | |
382 expected_policy.Set(test_keys::kKeyDictionary, | |
383 test_harness_->policy_level(), | |
384 test_harness_->policy_scope(), | |
385 policy_dict.DeepCopy(), | |
386 NULL); | |
387 PolicyBundle expected_bundle; | |
388 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) | |
389 .CopyFrom(expected_policy); | |
390 expected_policy.Clear(); | |
391 expected_policy.LoadFrom(&policy_dict, | |
392 test_harness_->policy_level(), | |
393 test_harness_->policy_scope()); | |
394 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, | |
395 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) | |
396 .CopyFrom(expected_policy); | |
397 expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, | |
398 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) | |
399 .CopyFrom(expected_policy); | |
400 EXPECT_TRUE(provider_->policies().Equals(expected_bundle)); | |
401 } | |
402 | |
403 } // namespace policy | |
OLD | NEW |