cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / components / policy / core / common / policy_loader_win_unittest.cc
blobc0afc4ecf33f6cd65ab662ff7c43f073bd434d35
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.
5 #include "components/policy/core/common/policy_loader_win.h"
7 #include <windows.h>
8 #include <userenv.h>
10 #include <algorithm>
11 #include <cstring>
12 #include <functional>
13 #include <iterator>
14 #include <vector>
16 #include "base/base_paths.h"
17 #include "base/callback.h"
18 #include "base/files/file_path.h"
19 #include "base/files/file_util.h"
20 #include "base/files/scoped_temp_dir.h"
21 #include "base/json/json_writer.h"
22 #include "base/path_service.h"
23 #include "base/process/process_handle.h"
24 #include "base/strings/string16.h"
25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h"
27 #include "base/strings/stringprintf.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/sys_byteorder.h"
30 #include "base/win/registry.h"
31 #include "base/win/win_util.h"
32 #include "components/policy/core/common/async_policy_provider.h"
33 #include "components/policy/core/common/configuration_policy_provider_test.h"
34 #include "components/policy/core/common/external_data_fetcher.h"
35 #include "components/policy/core/common/policy_bundle.h"
36 #include "components/policy/core/common/policy_map.h"
37 #include "components/policy/core/common/preg_parser_win.h"
38 #include "components/policy/core/common/schema_map.h"
39 #include "testing/gtest/include/gtest/gtest.h"
41 using base::UTF8ToUTF16;
42 using base::UTF16ToUTF8;
43 using base::win::RegKey;
45 namespace policy {
47 namespace {
49 // Constants for registry key names.
50 const wchar_t kPathSep[] = L"\\";
51 const wchar_t kThirdParty[] = L"3rdparty";
52 const wchar_t kMandatory[] = L"policy";
53 const wchar_t kRecommended[] = L"recommended";
54 const char kSchema[] = "schema";
55 const wchar_t kTestPolicyKey[] = L"chrome.policy.key";
57 // Installs |value| in the given registry |path| and |hive|, under the key
58 // |name|. Returns false on errors.
59 // Some of the possible Value types are stored after a conversion (e.g. doubles
60 // are stored as strings), and can only be retrieved if a corresponding schema
61 // is written.
62 bool InstallValue(const base::Value& value,
63 HKEY hive,
64 const base::string16& path,
65 const base::string16& name) {
66 // KEY_ALL_ACCESS causes the ctor to create the key if it does not exist yet.
67 RegKey key(hive, path.c_str(), KEY_ALL_ACCESS);
68 EXPECT_TRUE(key.Valid());
69 switch (value.GetType()) {
70 case base::Value::TYPE_NULL:
71 return key.WriteValue(name.c_str(), L"") == ERROR_SUCCESS;
73 case base::Value::TYPE_BOOLEAN: {
74 bool bool_value;
75 if (!value.GetAsBoolean(&bool_value))
76 return false;
77 return key.WriteValue(name.c_str(), bool_value ? 1 : 0) == ERROR_SUCCESS;
80 case base::Value::TYPE_INTEGER: {
81 int int_value;
82 if (!value.GetAsInteger(&int_value))
83 return false;
84 return key.WriteValue(name.c_str(), int_value) == ERROR_SUCCESS;
87 case base::Value::TYPE_DOUBLE: {
88 double double_value;
89 if (!value.GetAsDouble(&double_value))
90 return false;
91 base::string16 str_value =
92 UTF8ToUTF16(base::DoubleToString(double_value));
93 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
96 case base::Value::TYPE_STRING: {
97 base::string16 str_value;
98 if (!value.GetAsString(&str_value))
99 return false;
100 return key.WriteValue(name.c_str(), str_value.c_str()) == ERROR_SUCCESS;
103 case base::Value::TYPE_DICTIONARY: {
104 const base::DictionaryValue* sub_dict = NULL;
105 if (!value.GetAsDictionary(&sub_dict))
106 return false;
107 for (base::DictionaryValue::Iterator it(*sub_dict);
108 !it.IsAtEnd(); it.Advance()) {
109 if (!InstallValue(it.value(), hive, path + kPathSep + name,
110 UTF8ToUTF16(it.key()))) {
111 return false;
114 return true;
117 case base::Value::TYPE_LIST: {
118 const base::ListValue* list = NULL;
119 if (!value.GetAsList(&list))
120 return false;
121 for (size_t i = 0; i < list->GetSize(); ++i) {
122 const base::Value* item;
123 if (!list->Get(i, &item))
124 return false;
125 if (!InstallValue(*item, hive, path + kPathSep + name,
126 base::UintToString16(i + 1))) {
127 return false;
130 return true;
133 case base::Value::TYPE_BINARY:
134 return false;
136 NOTREACHED();
137 return false;
140 // This class provides sandboxing and mocking for the parts of the Windows
141 // Registry implementing Group Policy. It prepares two temporary sandbox keys,
142 // one for HKLM and one for HKCU. A test's calls to the registry are redirected
143 // by Windows to these sandboxes, allowing the tests to manipulate and access
144 // policy as if it were active, but without actually changing the parts of the
145 // Registry that are managed by Group Policy.
146 class ScopedGroupPolicyRegistrySandbox {
147 public:
148 ScopedGroupPolicyRegistrySandbox();
149 ~ScopedGroupPolicyRegistrySandbox();
151 private:
152 void ActivateOverrides();
153 void RemoveOverrides();
155 // Deletes the sandbox keys.
156 void DeleteKeys();
158 base::string16 key_name_;
160 // Keys are created for the lifetime of a test to contain
161 // the sandboxed HKCU and HKLM hives, respectively.
162 RegKey temp_hkcu_hive_key_;
163 RegKey temp_hklm_hive_key_;
165 DISALLOW_COPY_AND_ASSIGN(ScopedGroupPolicyRegistrySandbox);
168 // A test harness that feeds policy via the Chrome GPO registry subtree.
169 class RegistryTestHarness : public PolicyProviderTestHarness,
170 public AppliedGPOListProvider {
171 public:
172 RegistryTestHarness(HKEY hive, PolicyScope scope);
173 ~RegistryTestHarness() override;
175 // PolicyProviderTestHarness:
176 void SetUp() override;
178 ConfigurationPolicyProvider* CreateProvider(
179 SchemaRegistry* registry,
180 scoped_refptr<base::SequencedTaskRunner> task_runner) override;
182 void InstallEmptyPolicy() override;
183 void InstallStringPolicy(const std::string& policy_name,
184 const std::string& policy_value) override;
185 void InstallIntegerPolicy(const std::string& policy_name,
186 int policy_value) override;
187 void InstallBooleanPolicy(const std::string& policy_name,
188 bool policy_value) override;
189 void InstallStringListPolicy(const std::string& policy_name,
190 const base::ListValue* policy_value) override;
191 void InstallDictionaryPolicy(
192 const std::string& policy_name,
193 const base::DictionaryValue* policy_value) override;
194 void Install3rdPartyPolicy(const base::DictionaryValue* policies) override;
196 // AppliedGPOListProvider:
197 DWORD GetAppliedGPOList(DWORD flags,
198 LPCTSTR machine_name,
199 PSID sid_user,
200 GUID* extension_guid,
201 PGROUP_POLICY_OBJECT* gpo_list) override;
202 BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override;
204 // Creates a harness instance that will install policy in HKCU or HKLM,
205 // respectively.
206 static PolicyProviderTestHarness* CreateHKCU();
207 static PolicyProviderTestHarness* CreateHKLM();
209 private:
210 HKEY hive_;
212 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
214 DISALLOW_COPY_AND_ASSIGN(RegistryTestHarness);
217 // A test harness that generates PReg files for the provider to read.
218 class PRegTestHarness : public PolicyProviderTestHarness,
219 public AppliedGPOListProvider {
220 public:
221 PRegTestHarness();
222 ~PRegTestHarness() override;
224 // PolicyProviderTestHarness:
225 void SetUp() override;
227 ConfigurationPolicyProvider* CreateProvider(
228 SchemaRegistry* registry,
229 scoped_refptr<base::SequencedTaskRunner> task_runner) override;
231 void InstallEmptyPolicy() override;
232 void InstallStringPolicy(const std::string& policy_name,
233 const std::string& policy_value) override;
234 void InstallIntegerPolicy(const std::string& policy_name,
235 int policy_value) override;
236 void InstallBooleanPolicy(const std::string& policy_name,
237 bool policy_value) override;
238 void InstallStringListPolicy(const std::string& policy_name,
239 const base::ListValue* policy_value) override;
240 void InstallDictionaryPolicy(
241 const std::string& policy_name,
242 const base::DictionaryValue* policy_value) override;
243 void Install3rdPartyPolicy(const base::DictionaryValue* policies) override;
245 // AppliedGPOListProvider:
246 DWORD GetAppliedGPOList(DWORD flags,
247 LPCTSTR machine_name,
248 PSID sid_user,
249 GUID* extension_guid,
250 PGROUP_POLICY_OBJECT* gpo_list) override;
251 BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override;
253 // Creates a harness instance.
254 static PolicyProviderTestHarness* Create();
256 private:
257 // Helper to append a base::string16 to an uint8 buffer.
258 static void AppendChars(std::vector<uint8>* buffer,
259 const base::string16& chars);
261 // Appends a record with the given fields to the PReg file.
262 void AppendRecordToPRegFile(const base::string16& path,
263 const std::string& key,
264 DWORD type,
265 DWORD size,
266 uint8* data);
268 // Appends the given DWORD |value| for |path| + |key| to the PReg file.
269 void AppendDWORDToPRegFile(const base::string16& path,
270 const std::string& key,
271 DWORD value);
273 // Appends the given string |value| for |path| + |key| to the PReg file.
274 void AppendStringToPRegFile(const base::string16& path,
275 const std::string& key,
276 const std::string& value);
278 // Appends the given policy |value| for |path| + |key| to the PReg file,
279 // converting and recursing as necessary.
280 void AppendPolicyToPRegFile(const base::string16& path,
281 const std::string& key,
282 const base::Value* value);
284 base::ScopedTempDir temp_dir_;
285 base::FilePath preg_file_path_;
286 GROUP_POLICY_OBJECT gpo_;
288 DISALLOW_COPY_AND_ASSIGN(PRegTestHarness);
291 ScopedGroupPolicyRegistrySandbox::ScopedGroupPolicyRegistrySandbox() {
292 // Generate a unique registry key for the override for each test. This
293 // makes sure that tests executing in parallel won't delete each other's
294 // key, at DeleteKeys().
295 key_name_ = base::ASCIIToUTF16(base::StringPrintf(
296 "SOFTWARE\\chromium unittest %d", base::GetCurrentProcId()));
297 std::wstring hklm_key_name = key_name_ + L"\\HKLM";
298 std::wstring hkcu_key_name = key_name_ + L"\\HKCU";
300 // Create the subkeys to hold the overridden HKLM and HKCU
301 // policy settings.
302 temp_hklm_hive_key_.Create(HKEY_CURRENT_USER,
303 hklm_key_name.c_str(),
304 KEY_ALL_ACCESS);
305 temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER,
306 hkcu_key_name.c_str(),
307 KEY_ALL_ACCESS);
309 ActivateOverrides();
312 ScopedGroupPolicyRegistrySandbox::~ScopedGroupPolicyRegistrySandbox() {
313 RemoveOverrides();
314 DeleteKeys();
317 void ScopedGroupPolicyRegistrySandbox::ActivateOverrides() {
318 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE,
319 temp_hklm_hive_key_.Handle()));
320 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER,
321 temp_hkcu_hive_key_.Handle()));
324 void ScopedGroupPolicyRegistrySandbox::RemoveOverrides() {
325 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_LOCAL_MACHINE, 0));
326 ASSERT_HRESULT_SUCCEEDED(RegOverridePredefKey(HKEY_CURRENT_USER, 0));
329 void ScopedGroupPolicyRegistrySandbox::DeleteKeys() {
330 RegKey key(HKEY_CURRENT_USER, key_name_.c_str(), KEY_ALL_ACCESS);
331 ASSERT_TRUE(key.Valid());
332 key.DeleteKey(L"");
335 RegistryTestHarness::RegistryTestHarness(HKEY hive, PolicyScope scope)
336 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, scope), hive_(hive) {}
338 RegistryTestHarness::~RegistryTestHarness() {}
340 void RegistryTestHarness::SetUp() {}
342 ConfigurationPolicyProvider* RegistryTestHarness::CreateProvider(
343 SchemaRegistry* registry,
344 scoped_refptr<base::SequencedTaskRunner> task_runner) {
345 base::win::SetDomainStateForTesting(true);
346 scoped_ptr<AsyncPolicyLoader> loader(
347 new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
348 return new AsyncPolicyProvider(registry, loader.Pass());
351 void RegistryTestHarness::InstallEmptyPolicy() {}
353 void RegistryTestHarness::InstallStringPolicy(
354 const std::string& policy_name,
355 const std::string& policy_value) {
356 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
357 ASSERT_TRUE(key.Valid());
358 ASSERT_HRESULT_SUCCEEDED(key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
359 UTF8ToUTF16(policy_value).c_str()));
362 void RegistryTestHarness::InstallIntegerPolicy(
363 const std::string& policy_name,
364 int policy_value) {
365 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
366 ASSERT_TRUE(key.Valid());
367 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
368 static_cast<DWORD>(policy_value));
371 void RegistryTestHarness::InstallBooleanPolicy(
372 const std::string& policy_name,
373 bool policy_value) {
374 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
375 ASSERT_TRUE(key.Valid());
376 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
377 static_cast<DWORD>(policy_value));
380 void RegistryTestHarness::InstallStringListPolicy(
381 const std::string& policy_name,
382 const base::ListValue* policy_value) {
383 RegKey key(hive_,
384 (base::string16(kTestPolicyKey) + base::ASCIIToUTF16("\\") +
385 UTF8ToUTF16(policy_name)).c_str(),
386 KEY_ALL_ACCESS);
387 ASSERT_TRUE(key.Valid());
388 int index = 1;
389 for (base::ListValue::const_iterator element(policy_value->begin());
390 element != policy_value->end();
391 ++element) {
392 std::string element_value;
393 if (!(*element)->GetAsString(&element_value))
394 continue;
395 std::string name(base::IntToString(index++));
396 key.WriteValue(UTF8ToUTF16(name).c_str(),
397 UTF8ToUTF16(element_value).c_str());
401 void RegistryTestHarness::InstallDictionaryPolicy(
402 const std::string& policy_name,
403 const base::DictionaryValue* policy_value) {
404 std::string json;
405 base::JSONWriter::Write(*policy_value, &json);
406 RegKey key(hive_, kTestPolicyKey, KEY_ALL_ACCESS);
407 ASSERT_TRUE(key.Valid());
408 key.WriteValue(UTF8ToUTF16(policy_name).c_str(),
409 UTF8ToUTF16(json).c_str());
412 void RegistryTestHarness::Install3rdPartyPolicy(
413 const base::DictionaryValue* policies) {
414 // The first level entries are domains, and the second level entries map
415 // components to their policy.
416 const base::string16 kPathPrefix =
417 base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
418 for (base::DictionaryValue::Iterator domain(*policies);
419 !domain.IsAtEnd(); domain.Advance()) {
420 const base::DictionaryValue* components = NULL;
421 if (!domain.value().GetAsDictionary(&components)) {
422 ADD_FAILURE();
423 continue;
425 for (base::DictionaryValue::Iterator component(*components);
426 !component.IsAtEnd(); component.Advance()) {
427 const base::string16 path = kPathPrefix +
428 UTF8ToUTF16(domain.key()) + kPathSep + UTF8ToUTF16(component.key());
429 InstallValue(component.value(), hive_, path, kMandatory);
434 DWORD RegistryTestHarness::GetAppliedGPOList(DWORD flags,
435 LPCTSTR machine_name,
436 PSID sid_user,
437 GUID* extension_guid,
438 PGROUP_POLICY_OBJECT* gpo_list) {
439 *gpo_list = NULL;
440 return ERROR_ACCESS_DENIED;
443 BOOL RegistryTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
444 return TRUE;
447 // static
448 PolicyProviderTestHarness* RegistryTestHarness::CreateHKCU() {
449 return new RegistryTestHarness(HKEY_CURRENT_USER, POLICY_SCOPE_USER);
452 // static
453 PolicyProviderTestHarness* RegistryTestHarness::CreateHKLM() {
454 return new RegistryTestHarness(HKEY_LOCAL_MACHINE, POLICY_SCOPE_MACHINE);
457 PRegTestHarness::PRegTestHarness()
458 : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE) {}
460 PRegTestHarness::~PRegTestHarness() {}
462 void PRegTestHarness::SetUp() {
463 base::win::SetDomainStateForTesting(false);
464 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
465 preg_file_path_ = temp_dir_.path().Append(PolicyLoaderWin::kPRegFileName);
466 ASSERT_TRUE(base::WriteFile(preg_file_path_,
467 preg_parser::kPRegFileHeader,
468 arraysize(preg_parser::kPRegFileHeader)));
470 memset(&gpo_, 0, sizeof(GROUP_POLICY_OBJECT));
471 gpo_.lpFileSysPath = const_cast<wchar_t*>(temp_dir_.path().value().c_str());
474 ConfigurationPolicyProvider* PRegTestHarness::CreateProvider(
475 SchemaRegistry* registry,
476 scoped_refptr<base::SequencedTaskRunner> task_runner) {
477 scoped_ptr<AsyncPolicyLoader> loader(
478 new PolicyLoaderWin(task_runner, kTestPolicyKey, this));
479 return new AsyncPolicyProvider(registry, loader.Pass());
482 void PRegTestHarness::InstallEmptyPolicy() {}
484 void PRegTestHarness::InstallStringPolicy(const std::string& policy_name,
485 const std::string& policy_value) {
486 AppendStringToPRegFile(kTestPolicyKey, policy_name, policy_value);
489 void PRegTestHarness::InstallIntegerPolicy(const std::string& policy_name,
490 int policy_value) {
491 AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
494 void PRegTestHarness::InstallBooleanPolicy(const std::string& policy_name,
495 bool policy_value) {
496 AppendDWORDToPRegFile(kTestPolicyKey, policy_name, policy_value);
499 void PRegTestHarness::InstallStringListPolicy(
500 const std::string& policy_name,
501 const base::ListValue* policy_value) {
502 AppendPolicyToPRegFile(kTestPolicyKey, policy_name, policy_value);
505 void PRegTestHarness::InstallDictionaryPolicy(
506 const std::string& policy_name,
507 const base::DictionaryValue* policy_value) {
508 std::string json;
509 base::JSONWriter::Write(*policy_value, &json);
510 AppendStringToPRegFile(kTestPolicyKey, policy_name, json);
513 void PRegTestHarness::Install3rdPartyPolicy(
514 const base::DictionaryValue* policies) {
515 // The first level entries are domains, and the second level entries map
516 // components to their policy.
517 const base::string16 kPathPrefix =
518 base::string16(kTestPolicyKey) + kPathSep + kThirdParty + kPathSep;
519 for (base::DictionaryValue::Iterator domain(*policies);
520 !domain.IsAtEnd(); domain.Advance()) {
521 const base::DictionaryValue* components = NULL;
522 if (!domain.value().GetAsDictionary(&components)) {
523 ADD_FAILURE();
524 continue;
526 const base::string16 domain_path = kPathPrefix + UTF8ToUTF16(domain.key());
527 for (base::DictionaryValue::Iterator component(*components);
528 !component.IsAtEnd(); component.Advance()) {
529 const base::string16 component_path =
530 domain_path + kPathSep + UTF8ToUTF16(component.key());
531 AppendPolicyToPRegFile(component_path, UTF16ToUTF8(kMandatory),
532 &component.value());
537 DWORD PRegTestHarness::GetAppliedGPOList(DWORD flags,
538 LPCTSTR machine_name,
539 PSID sid_user,
540 GUID* extension_guid,
541 PGROUP_POLICY_OBJECT* gpo_list) {
542 *gpo_list = flags & GPO_LIST_FLAG_MACHINE ? &gpo_ : NULL;
543 return ERROR_SUCCESS;
546 BOOL PRegTestHarness::FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) {
547 return TRUE;
550 // static
551 PolicyProviderTestHarness* PRegTestHarness::Create() {
552 return new PRegTestHarness();
555 // static
556 void PRegTestHarness::AppendChars(std::vector<uint8>* buffer,
557 const base::string16& chars) {
558 for (base::string16::const_iterator c(chars.begin()); c != chars.end(); ++c) {
559 buffer->push_back(*c & 0xff);
560 buffer->push_back((*c >> 8) & 0xff);
564 void PRegTestHarness::AppendRecordToPRegFile(const base::string16& path,
565 const std::string& key,
566 DWORD type,
567 DWORD size,
568 uint8* data) {
569 std::vector<uint8> buffer;
570 AppendChars(&buffer, L"[");
571 AppendChars(&buffer, path);
572 AppendChars(&buffer, base::string16(L"\0;", 2));
573 AppendChars(&buffer, UTF8ToUTF16(key));
574 AppendChars(&buffer, base::string16(L"\0;", 2));
575 type = base::ByteSwapToLE32(type);
576 uint8* type_data = reinterpret_cast<uint8*>(&type);
577 buffer.insert(buffer.end(), type_data, type_data + sizeof(DWORD));
578 AppendChars(&buffer, L";");
579 size = base::ByteSwapToLE32(size);
580 uint8* size_data = reinterpret_cast<uint8*>(&size);
581 buffer.insert(buffer.end(), size_data, size_data + sizeof(DWORD));
582 AppendChars(&buffer, L";");
583 buffer.insert(buffer.end(), data, data + size);
584 AppendChars(&buffer, L"]");
586 ASSERT_TRUE(base::AppendToFile(
587 preg_file_path_,
588 reinterpret_cast<const char*>(vector_as_array(&buffer)),
589 buffer.size()));
592 void PRegTestHarness::AppendDWORDToPRegFile(const base::string16& path,
593 const std::string& key,
594 DWORD value) {
595 value = base::ByteSwapToLE32(value);
596 AppendRecordToPRegFile(path, key, REG_DWORD, sizeof(DWORD),
597 reinterpret_cast<uint8*>(&value));
600 void PRegTestHarness::AppendStringToPRegFile(const base::string16& path,
601 const std::string& key,
602 const std::string& value) {
603 base::string16 string16_value(UTF8ToUTF16(value));
604 std::vector<base::char16> data;
605 std::transform(string16_value.begin(), string16_value.end(),
606 std::back_inserter(data), std::ptr_fun(base::ByteSwapToLE16));
607 data.push_back(base::ByteSwapToLE16(L'\0'));
609 AppendRecordToPRegFile(path, key, REG_SZ, data.size() * sizeof(base::char16),
610 reinterpret_cast<uint8*>(vector_as_array(&data)));
613 void PRegTestHarness::AppendPolicyToPRegFile(const base::string16& path,
614 const std::string& key,
615 const base::Value* value) {
616 switch (value->GetType()) {
617 case base::Value::TYPE_BOOLEAN: {
618 bool boolean_value = false;
619 ASSERT_TRUE(value->GetAsBoolean(&boolean_value));
620 AppendDWORDToPRegFile(path, key, boolean_value);
621 break;
623 case base::Value::TYPE_INTEGER: {
624 int int_value = 0;
625 ASSERT_TRUE(value->GetAsInteger(&int_value));
626 AppendDWORDToPRegFile(path, key, int_value);
627 break;
629 case base::Value::TYPE_DOUBLE: {
630 double double_value = 0;
631 ASSERT_TRUE(value->GetAsDouble(&double_value));
632 AppendStringToPRegFile(path, key, base::DoubleToString(double_value));
633 break;
635 case base::Value::TYPE_STRING: {
636 std::string string_value;
637 ASSERT_TRUE(value->GetAsString(&string_value));
638 AppendStringToPRegFile(path, key, string_value);
639 break;
641 case base::Value::TYPE_DICTIONARY: {
642 base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
643 const base::DictionaryValue* dict = NULL;
644 ASSERT_TRUE(value->GetAsDictionary(&dict));
645 for (base::DictionaryValue::Iterator entry(*dict); !entry.IsAtEnd();
646 entry.Advance()) {
647 AppendPolicyToPRegFile(subpath, entry.key(), &entry.value());
649 break;
651 case base::Value::TYPE_LIST: {
652 base::string16 subpath = path + kPathSep + UTF8ToUTF16(key);
653 const base::ListValue* list = NULL;
654 ASSERT_TRUE(value->GetAsList(&list));
655 for (size_t i = 0; i < list->GetSize(); ++i) {
656 const base::Value* entry = NULL;
657 ASSERT_TRUE(list->Get(i, &entry));
658 AppendPolicyToPRegFile(subpath, base::IntToString(i + 1), entry);
660 break;
662 case base::Value::TYPE_BINARY:
663 case base::Value::TYPE_NULL: {
664 ADD_FAILURE();
665 break;
670 } // namespace
672 // Instantiate abstract test case for basic policy reading tests.
673 INSTANTIATE_TEST_CASE_P(
674 PolicyProviderWinTest,
675 ConfigurationPolicyProviderTest,
676 testing::Values(RegistryTestHarness::CreateHKCU,
677 RegistryTestHarness::CreateHKLM,
678 PRegTestHarness::Create));
680 // Instantiate abstract test case for 3rd party policy reading tests.
681 INSTANTIATE_TEST_CASE_P(
682 ThirdPartyPolicyProviderWinTest,
683 Configuration3rdPartyPolicyProviderTest,
684 testing::Values(RegistryTestHarness::CreateHKCU,
685 RegistryTestHarness::CreateHKLM,
686 PRegTestHarness::Create));
688 // Test cases for windows policy provider specific functionality.
689 class PolicyLoaderWinTest : public PolicyTestBase,
690 public AppliedGPOListProvider {
691 protected:
692 // The policy key this tests places data under. This must match the data
693 // files in chrome/test/data/policy/gpo.
694 static const base::char16 kTestPolicyKey[];
696 PolicyLoaderWinTest()
697 : gpo_list_(NULL),
698 gpo_list_status_(ERROR_ACCESS_DENIED) {}
699 ~PolicyLoaderWinTest() override {}
701 void SetUp() override {
702 base::win::SetDomainStateForTesting(false);
703 PolicyTestBase::SetUp();
705 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_));
706 test_data_dir_ = test_data_dir_.AppendASCII("chrome")
707 .AppendASCII("test")
708 .AppendASCII("data")
709 .AppendASCII("policy")
710 .AppendASCII("gpo");
712 gpo_list_provider_ = this;
715 // AppliedGPOListProvider:
716 DWORD GetAppliedGPOList(DWORD flags,
717 LPCTSTR machine_name,
718 PSID sid_user,
719 GUID* extension_guid,
720 PGROUP_POLICY_OBJECT* gpo_list) override {
721 *gpo_list = gpo_list_;
722 return gpo_list_status_;
724 BOOL FreeGPOList(PGROUP_POLICY_OBJECT gpo_list) override {
725 return TRUE;
728 void InitGPO(GROUP_POLICY_OBJECT* gpo,
729 DWORD options,
730 const base::FilePath& path,
731 GROUP_POLICY_OBJECT* next,
732 GROUP_POLICY_OBJECT* prev) {
733 memset(gpo, 0, sizeof(GROUP_POLICY_OBJECT));
734 gpo->dwOptions = options;
735 gpo->lpFileSysPath = const_cast<wchar_t*>(path.value().c_str());
736 gpo->pNext = next;
737 gpo->pPrev = prev;
740 bool Matches(const PolicyBundle& expected) {
741 PolicyLoaderWin loader(loop_.task_runner(), kTestPolicyKey,
742 gpo_list_provider_);
743 scoped_ptr<PolicyBundle> loaded(
744 loader.InitialLoad(schema_registry_.schema_map()));
745 return loaded->Equals(expected);
748 void InstallRegistrySentinel() {
749 RegKey hklm_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
750 ASSERT_TRUE(hklm_key.Valid());
751 hklm_key.WriteValue(
752 UTF8ToUTF16(test_keys::kKeyString).c_str(),
753 UTF8ToUTF16("registry").c_str());
756 bool MatchesRegistrySentinel() {
757 base::DictionaryValue expected_policy;
758 expected_policy.SetString(test_keys::kKeyString, "registry");
759 PolicyBundle expected;
760 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
761 .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
762 return Matches(expected);
765 bool MatchesTestBundle() {
766 base::DictionaryValue expected_policy;
767 expected_policy.SetBoolean(test_keys::kKeyBoolean, true);
768 expected_policy.SetString(test_keys::kKeyString, "GPO");
769 expected_policy.SetInteger(test_keys::kKeyInteger, 42);
770 scoped_ptr<base::ListValue> list(new base::ListValue());
771 list->AppendString("GPO 1");
772 list->AppendString("GPO 2");
773 expected_policy.Set(test_keys::kKeyStringList, list.release());
774 PolicyBundle expected;
775 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
776 .LoadFrom(&expected_policy, POLICY_LEVEL_MANDATORY,
777 POLICY_SCOPE_MACHINE);
778 return Matches(expected);
781 ScopedGroupPolicyRegistrySandbox registry_sandbox_;
782 PGROUP_POLICY_OBJECT gpo_list_;
783 DWORD gpo_list_status_;
784 base::FilePath test_data_dir_;
785 AppliedGPOListProvider* gpo_list_provider_;
788 const base::char16 PolicyLoaderWinTest::kTestPolicyKey[] =
789 L"SOFTWARE\\Policies\\Chromium";
791 TEST_F(PolicyLoaderWinTest, HKLMOverHKCU) {
792 RegKey hklm_key(HKEY_LOCAL_MACHINE, kTestPolicyKey, KEY_ALL_ACCESS);
793 ASSERT_TRUE(hklm_key.Valid());
794 hklm_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
795 UTF8ToUTF16("hklm").c_str());
796 RegKey hkcu_key(HKEY_CURRENT_USER, kTestPolicyKey, KEY_ALL_ACCESS);
797 ASSERT_TRUE(hkcu_key.Valid());
798 hkcu_key.WriteValue(UTF8ToUTF16(test_keys::kKeyString).c_str(),
799 UTF8ToUTF16("hkcu").c_str());
801 PolicyBundle expected;
802 expected.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
803 .Set(test_keys::kKeyString,
804 POLICY_LEVEL_MANDATORY,
805 POLICY_SCOPE_MACHINE,
806 new base::StringValue("hklm"),
807 NULL);
808 EXPECT_TRUE(Matches(expected));
811 TEST_F(PolicyLoaderWinTest, Merge3rdPartyPolicies) {
812 // Policy for the same extension will be provided at the 4 level/scope
813 // combinations, to verify that they overlap as expected.
814 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "merge");
815 ASSERT_TRUE(RegisterSchema(
818 " \"type\": \"object\","
819 " \"properties\": {"
820 " \"a\": { \"type\": \"string\" },"
821 " \"b\": { \"type\": \"string\" },"
822 " \"c\": { \"type\": \"string\" },"
823 " \"d\": { \"type\": \"string\" }"
824 " }"
825 "}"));
827 const base::string16 kPathSuffix =
828 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\merge");
830 const char kUserMandatory[] = "user-mandatory";
831 const char kUserRecommended[] = "user-recommended";
832 const char kMachineMandatory[] = "machine-mandatory";
833 const char kMachineRecommended[] = "machine-recommended";
835 base::DictionaryValue policy;
836 policy.SetString("a", kMachineMandatory);
837 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
838 kPathSuffix, kMandatory));
839 policy.SetString("a", kUserMandatory);
840 policy.SetString("b", kUserMandatory);
841 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
842 kPathSuffix, kMandatory));
843 policy.SetString("a", kMachineRecommended);
844 policy.SetString("b", kMachineRecommended);
845 policy.SetString("c", kMachineRecommended);
846 EXPECT_TRUE(InstallValue(policy, HKEY_LOCAL_MACHINE,
847 kPathSuffix, kRecommended));
848 policy.SetString("a", kUserRecommended);
849 policy.SetString("b", kUserRecommended);
850 policy.SetString("c", kUserRecommended);
851 policy.SetString("d", kUserRecommended);
852 EXPECT_TRUE(InstallValue(policy, HKEY_CURRENT_USER,
853 kPathSuffix, kRecommended));
855 PolicyBundle expected;
856 PolicyMap& expected_policy = expected.Get(ns);
857 expected_policy.Set("a",
858 POLICY_LEVEL_MANDATORY,
859 POLICY_SCOPE_MACHINE,
860 new base::StringValue(kMachineMandatory),
861 NULL);
862 expected_policy.Set("b",
863 POLICY_LEVEL_MANDATORY,
864 POLICY_SCOPE_USER,
865 new base::StringValue(kUserMandatory),
866 NULL);
867 expected_policy.Set("c",
868 POLICY_LEVEL_RECOMMENDED,
869 POLICY_SCOPE_MACHINE,
870 new base::StringValue(kMachineRecommended),
871 NULL);
872 expected_policy.Set("d",
873 POLICY_LEVEL_RECOMMENDED,
874 POLICY_SCOPE_USER,
875 new base::StringValue(kUserRecommended),
876 NULL);
877 EXPECT_TRUE(Matches(expected));
880 TEST_F(PolicyLoaderWinTest, LoadStringEncodedValues) {
881 // Create a dictionary with all the types that can be stored encoded in a
882 // string.
883 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "string");
884 ASSERT_TRUE(RegisterSchema(
887 " \"type\": \"object\","
888 " \"id\": \"MainType\","
889 " \"properties\": {"
890 " \"null\": { \"type\": \"null\" },"
891 " \"bool\": { \"type\": \"boolean\" },"
892 " \"int\": { \"type\": \"integer\" },"
893 " \"double\": { \"type\": \"number\" },"
894 " \"list\": {"
895 " \"type\": \"array\","
896 " \"items\": { \"$ref\": \"MainType\" }"
897 " },"
898 " \"dict\": { \"$ref\": \"MainType\" }"
899 " }"
900 "}"));
902 base::DictionaryValue policy;
903 policy.Set("null", base::Value::CreateNullValue());
904 policy.SetBoolean("bool", true);
905 policy.SetInteger("int", -123);
906 policy.SetDouble("double", 456.78e9);
907 base::ListValue list;
908 list.Append(policy.DeepCopy());
909 list.Append(policy.DeepCopy());
910 policy.Set("list", list.DeepCopy());
911 // Encode |policy| before adding the "dict" entry.
912 std::string encoded_dict;
913 base::JSONWriter::Write(policy, &encoded_dict);
914 ASSERT_FALSE(encoded_dict.empty());
915 policy.Set("dict", policy.DeepCopy());
916 std::string encoded_list;
917 base::JSONWriter::Write(list, &encoded_list);
918 ASSERT_FALSE(encoded_list.empty());
919 base::DictionaryValue encoded_policy;
920 encoded_policy.SetString("null", "");
921 encoded_policy.SetString("bool", "1");
922 encoded_policy.SetString("int", "-123");
923 encoded_policy.SetString("double", "456.78e9");
924 encoded_policy.SetString("list", encoded_list);
925 encoded_policy.SetString("dict", encoded_dict);
927 const base::string16 kPathSuffix =
928 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\string");
929 EXPECT_TRUE(
930 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
932 PolicyBundle expected;
933 expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
934 EXPECT_TRUE(Matches(expected));
937 TEST_F(PolicyLoaderWinTest, LoadIntegerEncodedValues) {
938 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "int");
939 ASSERT_TRUE(RegisterSchema(
942 " \"type\": \"object\","
943 " \"properties\": {"
944 " \"bool\": { \"type\": \"boolean\" },"
945 " \"int\": { \"type\": \"integer\" },"
946 " \"double\": { \"type\": \"number\" }"
947 " }"
948 "}"));
950 base::DictionaryValue encoded_policy;
951 encoded_policy.SetInteger("bool", 1);
952 encoded_policy.SetInteger("int", 123);
953 encoded_policy.SetInteger("double", 456);
955 const base::string16 kPathSuffix =
956 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\int");
957 EXPECT_TRUE(
958 InstallValue(encoded_policy, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
960 base::DictionaryValue policy;
961 policy.SetBoolean("bool", true);
962 policy.SetInteger("int", 123);
963 policy.SetDouble("double", 456.0);
964 PolicyBundle expected;
965 expected.Get(ns).LoadFrom(&policy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
966 EXPECT_TRUE(Matches(expected));
969 TEST_F(PolicyLoaderWinTest, DefaultPropertySchemaType) {
970 // Build a schema for an "object" with a default schema for its properties.
971 // Note that the top-level object can't have "additionalProperties", so
972 // a "policy" property is used instead.
973 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, "test");
974 ASSERT_TRUE(RegisterSchema(
977 " \"type\": \"object\","
978 " \"properties\": {"
979 " \"policy\": {"
980 " \"type\": \"object\","
981 " \"properties\": {"
982 " \"special-int1\": { \"type\": \"integer\" },"
983 " \"special-int2\": { \"type\": \"integer\" }"
984 " },"
985 " \"additionalProperties\": { \"type\": \"number\" }"
986 " }"
987 " }"
988 "}"));
990 // Write some test values.
991 base::DictionaryValue policy;
992 // These special values have a specific schema for them.
993 policy.SetInteger("special-int1", 123);
994 policy.SetString("special-int2", "-456");
995 // Other values default to be loaded as doubles.
996 policy.SetInteger("double1", 789.0);
997 policy.SetString("double2", "123.456e7");
998 policy.SetString("invalid", "omg");
999 base::DictionaryValue all_policies;
1000 all_policies.Set("policy", policy.DeepCopy());
1002 const base::string16 kPathSuffix =
1003 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions\\test");
1004 EXPECT_TRUE(
1005 InstallValue(all_policies, HKEY_CURRENT_USER, kPathSuffix, kMandatory));
1007 base::DictionaryValue expected_policy;
1008 expected_policy.SetInteger("special-int1", 123);
1009 expected_policy.SetInteger("special-int2", -456);
1010 expected_policy.SetDouble("double1", 789.0);
1011 expected_policy.SetDouble("double2", 123.456e7);
1012 base::DictionaryValue expected_policies;
1013 expected_policies.Set("policy", expected_policy.DeepCopy());
1014 PolicyBundle expected;
1015 expected.Get(ns).LoadFrom(
1016 &expected_policies, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER);
1017 EXPECT_TRUE(Matches(expected));
1020 TEST_F(PolicyLoaderWinTest, AppliedPolicyNotPresent) {
1021 InstallRegistrySentinel();
1022 gpo_list_ = NULL;
1023 gpo_list_status_ = ERROR_SUCCESS;
1025 PolicyBundle empty;
1026 EXPECT_TRUE(Matches(empty));
1029 TEST_F(PolicyLoaderWinTest, AppliedPolicyEmpty) {
1030 InstallRegistrySentinel();
1031 base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1032 GROUP_POLICY_OBJECT gpo;
1033 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1034 gpo_list_ = &gpo;
1035 gpo_list_status_ = ERROR_SUCCESS;
1037 PolicyBundle empty;
1038 EXPECT_TRUE(Matches(empty));
1041 TEST_F(PolicyLoaderWinTest, AppliedPolicyInDomain) {
1042 base::win::SetDomainStateForTesting(true);
1043 InstallRegistrySentinel();
1044 base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1045 GROUP_POLICY_OBJECT gpo;
1046 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1047 gpo_list_ = &gpo;
1048 gpo_list_status_ = ERROR_SUCCESS;
1050 EXPECT_TRUE(MatchesRegistrySentinel());
1053 TEST_F(PolicyLoaderWinTest, GpoProviderNotSpecified) {
1054 base::win::SetDomainStateForTesting(false);
1055 InstallRegistrySentinel();
1056 base::FilePath gpo_dir(test_data_dir_.AppendASCII("empty"));
1057 GROUP_POLICY_OBJECT gpo;
1058 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1059 gpo_list_ = &gpo;
1060 gpo_list_status_ = ERROR_SUCCESS;
1061 gpo_list_provider_ = nullptr;
1063 EXPECT_TRUE(MatchesRegistrySentinel());
1066 TEST_F(PolicyLoaderWinTest, AppliedPolicyNonExistingFile) {
1067 InstallRegistrySentinel();
1068 GROUP_POLICY_OBJECT gpo;
1069 InitGPO(&gpo, 0, test_data_dir_, NULL, NULL);
1070 gpo_list_ = &gpo;
1071 gpo_list_status_ = ERROR_SUCCESS;
1073 EXPECT_TRUE(MatchesRegistrySentinel());
1076 TEST_F(PolicyLoaderWinTest, AppliedPolicyBadPath) {
1077 InstallRegistrySentinel();
1078 base::FilePath gpo_dir(test_data_dir_.AppendASCII("bad"));
1079 GROUP_POLICY_OBJECT gpo;
1080 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1081 gpo_list_ = &gpo;
1082 gpo_list_status_ = ERROR_SUCCESS;
1084 EXPECT_TRUE(MatchesRegistrySentinel());
1087 TEST_F(PolicyLoaderWinTest, AppliedPolicyPresent) {
1088 InstallRegistrySentinel();
1089 base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1090 GROUP_POLICY_OBJECT gpo;
1091 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1092 gpo_list_ = &gpo;
1093 gpo_list_status_ = ERROR_SUCCESS;
1095 EXPECT_TRUE(MatchesTestBundle());
1098 TEST_F(PolicyLoaderWinTest, AppliedPolicyMerged) {
1099 InstallRegistrySentinel();
1100 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test2"));
1101 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test1"));
1102 GROUP_POLICY_OBJECT gpo1;
1103 GROUP_POLICY_OBJECT gpo2;
1104 InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1105 InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1106 gpo_list_ = &gpo1;
1107 gpo_list_status_ = ERROR_SUCCESS;
1109 EXPECT_TRUE(MatchesTestBundle());
1112 TEST_F(PolicyLoaderWinTest, AppliedPolicyDisabled) {
1113 InstallRegistrySentinel();
1114 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1115 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1116 GROUP_POLICY_OBJECT gpo1;
1117 GROUP_POLICY_OBJECT gpo2;
1118 InitGPO(&gpo1, 0, gpo1_dir, &gpo2, NULL);
1119 InitGPO(&gpo2, GPO_FLAG_DISABLE, gpo2_dir, NULL, &gpo1);
1120 gpo_list_ = &gpo1;
1121 gpo_list_status_ = ERROR_SUCCESS;
1123 EXPECT_TRUE(MatchesTestBundle());
1126 TEST_F(PolicyLoaderWinTest, AppliedPolicyForcedPolicy) {
1127 InstallRegistrySentinel();
1128 base::FilePath gpo1_dir(test_data_dir_.AppendASCII("test1"));
1129 base::FilePath gpo2_dir(test_data_dir_.AppendASCII("test2"));
1130 GROUP_POLICY_OBJECT gpo1;
1131 GROUP_POLICY_OBJECT gpo2;
1132 InitGPO(&gpo1, GPO_FLAG_FORCE, gpo1_dir, &gpo2, NULL);
1133 InitGPO(&gpo2, 0, gpo2_dir, NULL, &gpo1);
1134 gpo_list_ = &gpo1;
1135 gpo_list_status_ = ERROR_SUCCESS;
1137 EXPECT_TRUE(MatchesTestBundle());
1140 TEST_F(PolicyLoaderWinTest, AppliedPolicyUNCPath) {
1141 InstallRegistrySentinel();
1142 base::FilePath gpo_dir(test_data_dir_.AppendASCII("test1"));
1143 base::FilePath unc_path(L"\\\\some_share\\GPO");
1144 GROUP_POLICY_OBJECT gpo1;
1145 GROUP_POLICY_OBJECT gpo2;
1146 InitGPO(&gpo1, 0, gpo_dir, &gpo2, NULL);
1147 InitGPO(&gpo2, 0, unc_path, NULL, &gpo1);
1148 gpo_list_ = &gpo1;
1149 gpo_list_status_ = ERROR_SUCCESS;
1151 EXPECT_TRUE(MatchesRegistrySentinel());
1154 TEST_F(PolicyLoaderWinTest, LoadExtensionPolicyAlternativeSpelling) {
1155 base::FilePath gpo_dir(
1156 test_data_dir_.AppendASCII("extension_alternative_spelling"));
1157 GROUP_POLICY_OBJECT gpo;
1158 InitGPO(&gpo, 0, gpo_dir, NULL, NULL);
1159 gpo_list_ = &gpo;
1160 gpo_list_status_ = ERROR_SUCCESS;
1162 const char kTestSchema[] =
1164 " \"type\": \"object\","
1165 " \"properties\": {"
1166 " \"policy 1\": { \"type\": \"integer\" },"
1167 " \"policy 2\": { \"type\": \"integer\" }"
1168 " }"
1169 "}";
1170 const PolicyNamespace ns_a(
1171 POLICY_DOMAIN_EXTENSIONS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1172 const PolicyNamespace ns_b(
1173 POLICY_DOMAIN_EXTENSIONS, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1174 ASSERT_TRUE(RegisterSchema(ns_a, kTestSchema));
1175 ASSERT_TRUE(RegisterSchema(ns_b, kTestSchema));
1177 PolicyBundle expected;
1178 base::DictionaryValue expected_a;
1179 expected_a.SetInteger("policy 1", 3);
1180 expected_a.SetInteger("policy 2", 3);
1181 expected.Get(ns_a).LoadFrom(
1182 &expected_a, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1183 base::DictionaryValue expected_b;
1184 expected_b.SetInteger("policy 1", 2);
1185 expected.Get(ns_b).LoadFrom(
1186 &expected_b, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE);
1187 EXPECT_TRUE(Matches(expected));
1190 TEST_F(PolicyLoaderWinTest, LBSSupport) {
1191 const PolicyNamespace ns(
1192 POLICY_DOMAIN_EXTENSIONS, "heildphpnddilhkemkielfhnkaagiabh");
1193 schema_registry_.RegisterComponent(ns, Schema());
1195 const char kIncompleteSchema[] =
1197 " \"type\": \"object\","
1198 " \"properties\": {"
1199 " \"url_list\": { \"type\": \"array\" },"
1200 " \"url_greylist\": { \"type\": \"array\" }"
1201 " }"
1202 "}";
1204 const base::string16 kPathSuffix =
1205 kTestPolicyKey + base::ASCIIToUTF16("\\3rdparty\\extensions");
1207 base::ListValue list;
1208 list.AppendString("youtube.com");
1209 base::DictionaryValue policy;
1210 policy.Set("url_list", list.DeepCopy());
1211 policy.SetString("alternative_browser_path", "c:\\legacy\\browser.exe");
1212 base::DictionaryValue root;
1213 root.Set(base::UTF16ToUTF8(kMandatory), policy.DeepCopy());
1214 root.SetString(kSchema, kIncompleteSchema);
1215 EXPECT_TRUE(InstallValue(root, HKEY_LOCAL_MACHINE,
1216 kPathSuffix, base::ASCIIToUTF16(ns.component_id)));
1218 PolicyBundle expected;
1219 PolicyMap& expected_policy = expected.Get(ns);
1220 expected_policy.Set("alternative_browser_path",
1221 POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1222 new base::StringValue("c:\\legacy\\browser.exe"), NULL);
1223 expected_policy.Set("url_list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE,
1224 list.DeepCopy(), NULL);
1225 EXPECT_TRUE(Matches(expected));
1228 } // namespace policy