summaryrefslogtreecommitdiffstats
path: root/chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc')
-rw-r--r--chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc284
1 files changed, 284 insertions, 0 deletions
diff --git a/chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc b/chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc
new file mode 100644
index 00000000000..e20ab8b3a6c
--- /dev/null
+++ b/chromium/components/policy/core/common/config_dir_policy_loader_unittest.cc
@@ -0,0 +1,284 @@
+// 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 "components/policy/core/common/config_dir_policy_loader.h"
+#include <memory>
+
+#include <utility>
+
+#include "base/compiler_specific.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/values.h"
+#include "components/policy/core/common/async_policy_provider.h"
+#include "components/policy/core/common/configuration_policy_provider_test.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 "components/policy/core/common/policy_types.h"
+#include "components/policy/policy_constants.h"
+#include "components/strings/grit/components_strings.h"
+
+namespace policy {
+
+namespace {
+
+// Subdirectory of the config dir that contains mandatory policies.
+const base::FilePath::CharType kMandatoryPath[] = FILE_PATH_LITERAL("managed");
+// The policy input supports trailing comma and c++ styled comments.
+const char PolicyWithQuirks[] = R"({
+ // Some comments here.
+ "HomepageIsNewTabPage": true,
+ /* Some more comments here */
+})";
+
+class TestHarness : public PolicyProviderTestHarness {
+ public:
+ TestHarness();
+ TestHarness(const TestHarness&) = delete;
+ TestHarness& operator=(const TestHarness&) = delete;
+ ~TestHarness() override;
+
+ void SetUp() override;
+
+ ConfigurationPolicyProvider* CreateProvider(
+ SchemaRegistry* registry,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
+
+ void InstallEmptyPolicy() override;
+ void InstallStringPolicy(const std::string& policy_name,
+ const std::string& policy_value) override;
+ void InstallIntegerPolicy(const std::string& policy_name,
+ int policy_value) override;
+ void InstallBooleanPolicy(const std::string& policy_name,
+ bool policy_value) override;
+ void InstallStringListPolicy(const std::string& policy_name,
+ const base::ListValue* policy_value) override;
+ void InstallDictionaryPolicy(const std::string& policy_name,
+ const base::Value* policy_value) override;
+ void Install3rdPartyPolicy(const base::DictionaryValue* policies) override;
+
+ const base::FilePath& test_dir() { return test_dir_.GetPath(); }
+
+ // JSON-encode a dictionary and write it to a file.
+ void WriteConfigFile(const base::DictionaryValue& dict,
+ const std::string& file_name);
+ void WriteConfigFile(const std::string& data, const std::string& file_name);
+
+ // Returns a unique name for a policy file. Each subsequent call returns a
+ // new name that comes lexicographically after the previous one.
+ std::string NextConfigFileName();
+
+ static PolicyProviderTestHarness* Create();
+
+ private:
+ base::ScopedTempDir test_dir_;
+ int next_policy_file_index_;
+};
+
+TestHarness::TestHarness()
+ : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_MACHINE,
+ POLICY_SOURCE_PLATFORM),
+ next_policy_file_index_(100) {}
+
+TestHarness::~TestHarness() = default;
+
+void TestHarness::SetUp() {
+ ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
+}
+
+ConfigurationPolicyProvider* TestHarness::CreateProvider(
+ SchemaRegistry* registry,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ std::unique_ptr<AsyncPolicyLoader> loader(
+ new ConfigDirPolicyLoader(task_runner, test_dir(), POLICY_SCOPE_MACHINE));
+ return new AsyncPolicyProvider(registry, std::move(loader));
+}
+
+void TestHarness::InstallEmptyPolicy() {
+ base::DictionaryValue dict;
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::InstallStringPolicy(const std::string& policy_name,
+ const std::string& policy_value) {
+ base::DictionaryValue dict;
+ dict.SetStringKey(policy_name, policy_value);
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
+ int policy_value) {
+ base::DictionaryValue dict;
+ dict.SetIntKey(policy_name, policy_value);
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
+ bool policy_value) {
+ base::DictionaryValue dict;
+ dict.SetBoolKey(policy_name, policy_value);
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::InstallStringListPolicy(const std::string& policy_name,
+ const base::ListValue* policy_value) {
+ base::DictionaryValue dict;
+ dict.SetKey(policy_name, policy_value->Clone());
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::InstallDictionaryPolicy(const std::string& policy_name,
+ const base::Value* policy_value) {
+ base::DictionaryValue dict;
+ dict.SetKey(policy_name, policy_value->Clone());
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::Install3rdPartyPolicy(const base::DictionaryValue* policies) {
+ base::DictionaryValue dict;
+ dict.SetKey("3rdparty", policies->Clone());
+ WriteConfigFile(dict, NextConfigFileName());
+}
+
+void TestHarness::WriteConfigFile(const base::DictionaryValue& dict,
+ const std::string& file_name) {
+ std::string data;
+ JSONStringValueSerializer serializer(&data);
+ serializer.Serialize(dict);
+ WriteConfigFile(data, file_name);
+}
+
+void TestHarness::WriteConfigFile(const std::string& data,
+ const std::string& file_name) {
+ const base::FilePath mandatory_dir(test_dir().Append(kMandatoryPath));
+ ASSERT_TRUE(base::CreateDirectory(mandatory_dir));
+ const base::FilePath file_path(mandatory_dir.AppendASCII(file_name));
+ ASSERT_EQ((int)data.size(),
+ base::WriteFile(file_path, data.c_str(), data.size()));
+}
+
+std::string TestHarness::NextConfigFileName() {
+ EXPECT_LE(next_policy_file_index_, 999);
+ return std::string("policy") +
+ base::NumberToString(next_policy_file_index_++);
+}
+
+// static
+PolicyProviderTestHarness* TestHarness::Create() {
+ return new TestHarness();
+}
+
+} // namespace
+
+// Instantiate abstract test case for basic policy reading tests.
+INSTANTIATE_TEST_SUITE_P(ConfigDirPolicyLoaderTest,
+ ConfigurationPolicyProviderTest,
+ testing::Values(TestHarness::Create));
+
+// Instantiate abstract test case for 3rd party policy reading tests.
+INSTANTIATE_TEST_SUITE_P(ConfigDir3rdPartyPolicyLoaderTest,
+ Configuration3rdPartyPolicyProviderTest,
+ testing::Values(TestHarness::Create));
+
+// Some tests that exercise special functionality in ConfigDirPolicyLoader.
+class ConfigDirPolicyLoaderTest : public PolicyTestBase {
+ protected:
+ void SetUp() override {
+ PolicyTestBase::SetUp();
+ harness_.SetUp();
+ }
+
+ TestHarness harness_;
+};
+
+// The preferences dictionary is expected to be empty when there are no files to
+// load.
+TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) {
+ ConfigDirPolicyLoader loader(task_environment_.GetMainThreadTaskRunner(),
+ harness_.test_dir(), POLICY_SCOPE_MACHINE);
+ std::unique_ptr<PolicyBundle> bundle(loader.Load());
+ ASSERT_TRUE(bundle.get());
+ const PolicyBundle kEmptyBundle;
+ EXPECT_TRUE(bundle->Equals(kEmptyBundle));
+}
+
+// Reading from a non-existent directory should result in an empty preferences
+// dictionary.
+TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsNonExistentDirectory) {
+ base::FilePath non_existent_dir(
+ harness_.test_dir().Append(FILE_PATH_LITERAL("not_there")));
+ ConfigDirPolicyLoader loader(task_environment_.GetMainThreadTaskRunner(),
+ non_existent_dir, POLICY_SCOPE_MACHINE);
+ std::unique_ptr<PolicyBundle> bundle(loader.Load());
+ ASSERT_TRUE(bundle.get());
+ const PolicyBundle kEmptyBundle;
+ EXPECT_TRUE(bundle->Equals(kEmptyBundle));
+}
+
+TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsWithComments) {
+ harness_.WriteConfigFile(PolicyWithQuirks, "policies.json");
+ ConfigDirPolicyLoader loader(task_environment_.GetMainThreadTaskRunner(),
+ harness_.test_dir(), POLICY_SCOPE_MACHINE);
+ std::unique_ptr<PolicyBundle> bundle(loader.Load());
+ ASSERT_TRUE(bundle.get());
+ PolicyBundle expected_bundle;
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .Set(key::kHomepageIsNewTabPage, POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_MACHINE, POLICY_SOURCE_PLATFORM, base::Value(true),
+ /*external_data_fetcher=*/nullptr);
+
+ EXPECT_TRUE(bundle->Equals(expected_bundle));
+}
+
+// Test merging values from different files.
+TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) {
+ // Write a bunch of data files in order to increase the chance to detect the
+ // provider not respecting lexicographic ordering when reading them. Since the
+ // filesystem may return files in arbitrary order, there is no way to be sure,
+ // but this is better than nothing.
+ base::DictionaryValue test_dict_bar;
+ const char kHomepageLocation[] = "HomepageLocation";
+ test_dict_bar.SetStringKey(kHomepageLocation, "http://bar.com");
+ for (unsigned int i = 1; i <= 4; ++i)
+ harness_.WriteConfigFile(test_dict_bar, base::NumberToString(i));
+ base::DictionaryValue test_dict_foo;
+ test_dict_foo.SetStringKey(kHomepageLocation, "http://foo.com");
+ harness_.WriteConfigFile(test_dict_foo, "9");
+ for (unsigned int i = 5; i <= 8; ++i)
+ harness_.WriteConfigFile(test_dict_bar, base::NumberToString(i));
+
+ ConfigDirPolicyLoader loader(task_environment_.GetMainThreadTaskRunner(),
+ harness_.test_dir(), POLICY_SCOPE_USER);
+ std::unique_ptr<PolicyBundle> bundle(loader.Load());
+ ASSERT_TRUE(bundle.get());
+ PolicyBundle expected_bundle;
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .LoadFrom(&test_dict_foo, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_PLATFORM);
+ for (unsigned int i = 1; i <= 8; ++i) {
+ auto conflict_policy =
+ expected_bundle
+ .Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .Get(kHomepageLocation)
+ ->DeepCopy();
+ conflict_policy.conflicts.clear();
+ conflict_policy.set_value(base::Value("http://bar.com"));
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .GetMutable(kHomepageLocation)
+ ->AddConflictingPolicy(std::move(conflict_policy));
+ expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
+ .GetMutable(kHomepageLocation)
+ ->AddMessage(PolicyMap::MessageType::kWarning,
+ IDS_POLICY_CONFLICT_DIFF_VALUE);
+ }
+ EXPECT_TRUE(bundle->Equals(expected_bundle));
+}
+
+} // namespace policy