blob: c0af27fe2b15b2e755697acf3537cd223dc84f5f [file] [log] [blame]
// 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/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "chrome/browser/policy/external_data_fetcher.h"
#include "chrome/browser/policy/mock_configuration_policy_provider.h"
#include "chrome/browser/policy/policy_bundle.h"
#include "chrome/browser/policy/policy_map.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
using content::BrowserThread;
using ::testing::Mock;
using ::testing::_;
namespace policy {
namespace test_policy_definitions {
const char kKeyString[] = "StringPolicy";
const char kKeyBoolean[] = "BooleanPolicy";
const char kKeyInteger[] = "IntegerPolicy";
const char kKeyStringList[] = "StringListPolicy";
const char kKeyDictionary[] = "DictionaryPolicy";
static const PolicyDefinitionList::Entry kEntries[] = {
{ kKeyString, base::Value::TYPE_STRING },
{ kKeyBoolean, base::Value::TYPE_BOOLEAN },
{ kKeyInteger, base::Value::TYPE_INTEGER },
{ kKeyStringList, base::Value::TYPE_LIST },
{ kKeyDictionary, base::Value::TYPE_DICTIONARY },
};
const PolicyDefinitionList kList = {
kEntries, kEntries + arraysize(kEntries)
};
} // namespace test_policy_definitions
PolicyTestBase::PolicyTestBase()
: ui_thread_(BrowserThread::UI, &loop_),
file_thread_(BrowserThread::FILE, &loop_) {}
PolicyTestBase::~PolicyTestBase() {}
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();
provider_.reset(
test_harness_->CreateProvider(&test_policy_definitions::kList));
provider_->Init();
// 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_policy_definitions::kKeyString,
expected_value,
base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
base::Unretained(test_harness_.get()),
test_policy_definitions::kKeyString,
kTestString));
}
TEST_P(ConfigurationPolicyProviderTest, BooleanValue) {
base::FundamentalValue expected_value(true);
CheckValue(test_policy_definitions::kKeyBoolean,
expected_value,
base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy,
base::Unretained(test_harness_.get()),
test_policy_definitions::kKeyBoolean,
true));
}
TEST_P(ConfigurationPolicyProviderTest, IntegerValue) {
base::FundamentalValue expected_value(42);
CheckValue(test_policy_definitions::kKeyInteger,
expected_value,
base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy,
base::Unretained(test_harness_.get()),
test_policy_definitions::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_policy_definitions::kKeyStringList,
expected_value,
base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
base::Unretained(test_harness_.get()),
test_policy_definitions::kKeyStringList,
&expected_value));
}
TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) {
base::DictionaryValue expected_value;
expected_value.SetBoolean("bool", true);
expected_value.SetInteger("int", 123);
expected_value.SetString("str", "omg");
base::ListValue* list = new base::ListValue();
list->Set(0U, base::Value::CreateStringValue("first"));
list->Set(1U, base::Value::CreateStringValue("second"));
expected_value.Set("list", 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("dict", dict);
CheckValue(test_policy_definitions::kKeyDictionary,
expected_value,
base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy,
base::Unretained(test_harness_.get()),
test_policy_definitions::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_policy_definitions::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_policy_definitions::kKeyString,
test_harness_->policy_level(),
test_harness_->policy_scope(),
base::Value::CreateStringValue("value"),
NULL);
EXPECT_TRUE(provider_->policies().Equals(bundle));
provider_->RemoveObserver(&observer);
}
TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) {
PolicyMap policy_map;
policy_map.Set(key::kProxyServerMode,
POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER,
base::Value::CreateIntegerValue(3),
NULL);
// Both these policies should be ignored, since there's a higher priority
// policy available.
policy_map.Set(key::kProxyMode,
POLICY_LEVEL_RECOMMENDED,
POLICY_SCOPE_USER,
base::Value::CreateStringValue("pac_script"),
NULL);
policy_map.Set(key::kProxyPacUrl,
POLICY_LEVEL_RECOMMENDED,
POLICY_SCOPE_USER,
base::Value::CreateStringValue("http://example.com/wpad.dat"),
NULL);
MockConfigurationPolicyProvider provider;
provider.Init();
provider.UpdateChromePolicy(policy_map);
PolicyBundle expected_bundle;
base::DictionaryValue* expected_value = new base::DictionaryValue();
expected_value->SetInteger(key::kProxyServerMode, 3);
expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
.Set(key::kProxySettings,
POLICY_LEVEL_MANDATORY,
POLICY_SCOPE_USER,
expected_value,
NULL);
EXPECT_TRUE(provider.policies().Equals(expected_bundle));
provider.Shutdown();
}
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("str", "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_policy_definitions::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_policy_definitions::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