Index: chrome/browser/policy/configuration_policy_provider_test.cc |
diff --git a/chrome/browser/policy/configuration_policy_provider_test.cc b/chrome/browser/policy/configuration_policy_provider_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ff7bd619a68b32f2efd6ec600bf83d06ededa623 |
--- /dev/null |
+++ b/chrome/browser/policy/configuration_policy_provider_test.cc |
@@ -0,0 +1,403 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/policy/configuration_policy_provider_test.h" |
+ |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/message_loop/message_loop_proxy.h" |
+#include "base/values.h" |
+#include "chrome/browser/policy/configuration_policy_provider.h" |
+#include "chrome/browser/policy/mock_configuration_policy_provider.h" |
+#include "components/policy/core/common/external_data_fetcher.h" |
+#include "components/policy/core/common/policy_bundle.h" |
+#include "components/policy/core/common/policy_map.h" |
+#include "components/policy/core/common/policy_namespace.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+ |
+using ::testing::Mock; |
+using ::testing::_; |
+ |
+namespace policy { |
+ |
+const char kTestChromeSchema[] = |
+ "{" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"StringPolicy\": { \"type\": \"string\" }," |
+ " \"BooleanPolicy\": { \"type\": \"boolean\" }," |
+ " \"IntegerPolicy\": { \"type\": \"integer\" }," |
+ " \"StringListPolicy\": {" |
+ " \"type\": \"array\"," |
+ " \"items\": { \"type\": \"string\" }" |
+ " }," |
+ " \"DictionaryPolicy\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"bool\": { \"type\": \"boolean\" }," |
+ " \"double\": { \"type\": \"number\" }," |
+ " \"int\": { \"type\": \"integer\" }," |
+ " \"string\": { \"type\": \"string\" }," |
+ " \"array\": {" |
+ " \"type\": \"array\"," |
+ " \"items\": { \"type\": \"string\" }" |
+ " }," |
+ " \"dictionary\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"sub\": { \"type\": \"string\" }," |
+ " \"sublist\": {" |
+ " \"type\": \"array\"," |
+ " \"items\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"aaa\": { \"type\": \"integer\" }," |
+ " \"bbb\": { \"type\": \"integer\" }," |
+ " \"ccc\": { \"type\": \"string\" }," |
+ " \"ddd\": { \"type\": \"string\" }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }," |
+ " \"list\": {" |
+ " \"type\": \"array\"," |
+ " \"items\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"subdictindex\": { \"type\": \"integer\" }," |
+ " \"subdict\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"bool\": { \"type\": \"boolean\" }," |
+ " \"double\": { \"type\": \"number\" }," |
+ " \"int\": { \"type\": \"integer\" }," |
+ " \"string\": { \"type\": \"string\" }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }," |
+ " \"dict\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"bool\": { \"type\": \"boolean\" }," |
+ " \"double\": { \"type\": \"number\" }," |
+ " \"int\": { \"type\": \"integer\" }," |
+ " \"string\": { \"type\": \"string\" }," |
+ " \"list\": {" |
+ " \"type\": \"array\"," |
+ " \"items\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"subdictindex\": { \"type\": \"integer\" }," |
+ " \"subdict\": {" |
+ " \"type\": \"object\"," |
+ " \"properties\": {" |
+ " \"bool\": { \"type\": \"boolean\" }," |
+ " \"double\": { \"type\": \"number\" }," |
+ " \"int\": { \"type\": \"integer\" }," |
+ " \"string\": { \"type\": \"string\" }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ " }" |
+ "}"; |
+ |
+namespace test_keys { |
+ |
+const char kKeyString[] = "StringPolicy"; |
+const char kKeyBoolean[] = "BooleanPolicy"; |
+const char kKeyInteger[] = "IntegerPolicy"; |
+const char kKeyStringList[] = "StringListPolicy"; |
+const char kKeyDictionary[] = "DictionaryPolicy"; |
+ |
+} // namespace test_keys |
+ |
+PolicyTestBase::PolicyTestBase() {} |
+ |
+PolicyTestBase::~PolicyTestBase() {} |
+ |
+void PolicyTestBase::SetUp() { |
+ std::string error; |
+ chrome_schema_ = Schema::Parse(kTestChromeSchema, &error); |
+ ASSERT_TRUE(chrome_schema_.valid()) << error; |
+ schema_registry_.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), |
+ chrome_schema_); |
+} |
+ |
+void PolicyTestBase::TearDown() { |
+ loop_.RunUntilIdle(); |
+} |
+ |
+PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level, |
+ PolicyScope scope) |
+ : level_(level), scope_(scope) {} |
+ |
+PolicyProviderTestHarness::~PolicyProviderTestHarness() {} |
+ |
+PolicyLevel PolicyProviderTestHarness::policy_level() const { |
+ return level_; |
+} |
+ |
+PolicyScope PolicyProviderTestHarness::policy_scope() const { |
+ return scope_; |
+} |
+ |
+void PolicyProviderTestHarness::Install3rdPartyPolicy( |
+ const base::DictionaryValue* policies) { |
+ FAIL(); |
+} |
+ |
+ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {} |
+ |
+ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {} |
+ |
+void ConfigurationPolicyProviderTest::SetUp() { |
+ PolicyTestBase::SetUp(); |
+ |
+ test_harness_.reset((*GetParam())()); |
+ test_harness_->SetUp(); |
+ |
+ Schema extension_schema = |
+ chrome_schema_.GetKnownProperty(test_keys::kKeyDictionary); |
+ ASSERT_TRUE(extension_schema.valid()); |
+ schema_registry_.RegisterComponent( |
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, |
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), |
+ extension_schema); |
+ schema_registry_.RegisterComponent( |
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, |
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), |
+ extension_schema); |
+ schema_registry_.RegisterComponent( |
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, |
+ "cccccccccccccccccccccccccccccccc"), |
+ extension_schema); |
+ |
+ provider_.reset(test_harness_->CreateProvider(&schema_registry_, |
+ loop_.message_loop_proxy())); |
+ provider_->Init(&schema_registry_); |
+ // Some providers do a reload on init. Make sure any notifications generated |
+ // are fired now. |
+ loop_.RunUntilIdle(); |
+ |
+ const PolicyBundle kEmptyBundle; |
+ EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle)); |
+} |
+ |
+void ConfigurationPolicyProviderTest::TearDown() { |
+ // Give providers the chance to clean up after themselves on the file thread. |
+ provider_->Shutdown(); |
+ provider_.reset(); |
+ |
+ PolicyTestBase::TearDown(); |
+} |
+ |
+void ConfigurationPolicyProviderTest::CheckValue( |
+ const char* policy_name, |
+ const base::Value& expected_value, |
+ base::Closure install_value) { |
+ // Install the value, reload policy and check the provider for the value. |
+ install_value.Run(); |
+ provider_->RefreshPolicies(); |
+ loop_.RunUntilIdle(); |
+ PolicyBundle expected_bundle; |
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) |
+ .Set(policy_name, |
+ test_harness_->policy_level(), |
+ test_harness_->policy_scope(), |
+ expected_value.DeepCopy(), |
+ NULL); |
+ EXPECT_TRUE(provider_->policies().Equals(expected_bundle)); |
+ // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too, |
+ // and extend the |expected_bundle|, once all providers are ready. |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, Empty) { |
+ provider_->RefreshPolicies(); |
+ loop_.RunUntilIdle(); |
+ const PolicyBundle kEmptyBundle; |
+ EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, StringValue) { |
+ const char kTestString[] = "string_value"; |
+ base::StringValue expected_value(kTestString); |
+ CheckValue(test_keys::kKeyString, |
+ expected_value, |
+ base::Bind(&PolicyProviderTestHarness::InstallStringPolicy, |
+ base::Unretained(test_harness_.get()), |
+ test_keys::kKeyString, |
+ kTestString)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, BooleanValue) { |
+ base::FundamentalValue expected_value(true); |
+ CheckValue(test_keys::kKeyBoolean, |
+ expected_value, |
+ base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy, |
+ base::Unretained(test_harness_.get()), |
+ test_keys::kKeyBoolean, |
+ true)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, IntegerValue) { |
+ base::FundamentalValue expected_value(42); |
+ CheckValue(test_keys::kKeyInteger, |
+ expected_value, |
+ base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy, |
+ base::Unretained(test_harness_.get()), |
+ test_keys::kKeyInteger, |
+ 42)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, StringListValue) { |
+ base::ListValue expected_value; |
+ expected_value.Set(0U, base::Value::CreateStringValue("first")); |
+ expected_value.Set(1U, base::Value::CreateStringValue("second")); |
+ CheckValue(test_keys::kKeyStringList, |
+ expected_value, |
+ base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy, |
+ base::Unretained(test_harness_.get()), |
+ test_keys::kKeyStringList, |
+ &expected_value)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) { |
+ base::DictionaryValue expected_value; |
+ expected_value.SetBoolean("bool", true); |
+ expected_value.SetDouble("double", 123.456); |
+ expected_value.SetInteger("int", 123); |
+ expected_value.SetString("string", "omg"); |
+ |
+ base::ListValue* list = new base::ListValue(); |
+ list->Set(0U, base::Value::CreateStringValue("first")); |
+ list->Set(1U, base::Value::CreateStringValue("second")); |
+ expected_value.Set("array", list); |
+ |
+ base::DictionaryValue* dict = new base::DictionaryValue(); |
+ dict->SetString("sub", "value"); |
+ list = new base::ListValue(); |
+ base::DictionaryValue* sub = new base::DictionaryValue(); |
+ sub->SetInteger("aaa", 111); |
+ sub->SetInteger("bbb", 222); |
+ list->Append(sub); |
+ sub = new base::DictionaryValue(); |
+ sub->SetString("ccc", "333"); |
+ sub->SetString("ddd", "444"); |
+ list->Append(sub); |
+ dict->Set("sublist", list); |
+ expected_value.Set("dictionary", dict); |
+ |
+ CheckValue(test_keys::kKeyDictionary, |
+ expected_value, |
+ base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy, |
+ base::Unretained(test_harness_.get()), |
+ test_keys::kKeyDictionary, |
+ &expected_value)); |
+} |
+ |
+TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) { |
+ PolicyBundle bundle; |
+ EXPECT_TRUE(provider_->policies().Equals(bundle)); |
+ |
+ // OnUpdatePolicy is called even when there are no changes. |
+ MockConfigurationPolicyObserver observer; |
+ provider_->AddObserver(&observer); |
+ EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); |
+ provider_->RefreshPolicies(); |
+ loop_.RunUntilIdle(); |
+ Mock::VerifyAndClearExpectations(&observer); |
+ |
+ EXPECT_TRUE(provider_->policies().Equals(bundle)); |
+ |
+ // OnUpdatePolicy is called when there are changes. |
+ test_harness_->InstallStringPolicy(test_keys::kKeyString, "value"); |
+ EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1); |
+ provider_->RefreshPolicies(); |
+ loop_.RunUntilIdle(); |
+ Mock::VerifyAndClearExpectations(&observer); |
+ |
+ bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) |
+ .Set(test_keys::kKeyString, |
+ test_harness_->policy_level(), |
+ test_harness_->policy_scope(), |
+ base::Value::CreateStringValue("value"), |
+ NULL); |
+ EXPECT_TRUE(provider_->policies().Equals(bundle)); |
+ provider_->RemoveObserver(&observer); |
+} |
+ |
+Configuration3rdPartyPolicyProviderTest:: |
+ Configuration3rdPartyPolicyProviderTest() {} |
+ |
+Configuration3rdPartyPolicyProviderTest:: |
+ ~Configuration3rdPartyPolicyProviderTest() {} |
+ |
+TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) { |
+ base::DictionaryValue policy_dict; |
+ policy_dict.SetBoolean("bool", true); |
+ policy_dict.SetDouble("double", 123.456); |
+ policy_dict.SetInteger("int", 789); |
+ policy_dict.SetString("string", "string value"); |
+ |
+ base::ListValue* list = new base::ListValue(); |
+ for (int i = 0; i < 2; ++i) { |
+ base::DictionaryValue* dict = new base::DictionaryValue(); |
+ dict->SetInteger("subdictindex", i); |
+ dict->Set("subdict", policy_dict.DeepCopy()); |
+ list->Append(dict); |
+ } |
+ policy_dict.Set("list", list); |
+ policy_dict.Set("dict", policy_dict.DeepCopy()); |
+ |
+ // Install these policies as a Chrome policy. |
+ test_harness_->InstallDictionaryPolicy(test_keys::kKeyDictionary, |
+ &policy_dict); |
+ // Install them as 3rd party policies too. |
+ base::DictionaryValue policy_3rdparty; |
+ policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
+ policy_dict.DeepCopy()); |
+ policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", |
+ policy_dict.DeepCopy()); |
+ // Install invalid 3rd party policies that shouldn't be loaded. These also |
+ // help detecting memory leaks in the code paths that detect invalid input. |
+ policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy()); |
+ policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc", |
+ base::Value::CreateStringValue("invalid-value")); |
+ test_harness_->Install3rdPartyPolicy(&policy_3rdparty); |
+ |
+ provider_->RefreshPolicies(); |
+ loop_.RunUntilIdle(); |
+ |
+ PolicyMap expected_policy; |
+ expected_policy.Set(test_keys::kKeyDictionary, |
+ test_harness_->policy_level(), |
+ test_harness_->policy_scope(), |
+ policy_dict.DeepCopy(), |
+ NULL); |
+ PolicyBundle expected_bundle; |
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) |
+ .CopyFrom(expected_policy); |
+ expected_policy.Clear(); |
+ expected_policy.LoadFrom(&policy_dict, |
+ test_harness_->policy_level(), |
+ test_harness_->policy_scope()); |
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, |
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) |
+ .CopyFrom(expected_policy); |
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, |
+ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")) |
+ .CopyFrom(expected_policy); |
+ EXPECT_TRUE(provider_->policies().Equals(expected_bundle)); |
+} |
+ |
+} // namespace policy |