xref: /aosp_15_r20/external/libchrome/components/policy/core/common/config_dir_policy_loader_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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/config_dir_policy_loader.h"
6 #include <memory>
7 
8 #include <utility>
9 
10 #include "base/compiler_specific.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/json/json_string_value_serializer.h"
14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/sequenced_task_runner.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/values.h"
19 #include "components/policy/core/common/async_policy_provider.h"
20 #include "components/policy/core/common/configuration_policy_provider_test.h"
21 #include "components/policy/core/common/policy_bundle.h"
22 #include "components/policy/core/common/policy_map.h"
23 #include "components/policy/core/common/policy_types.h"
24 
25 namespace policy {
26 
27 namespace {
28 
29 // Subdirectory of the config dir that contains mandatory policies.
30 const base::FilePath::CharType kMandatoryPath[] = FILE_PATH_LITERAL("managed");
31 
32 class TestHarness : public PolicyProviderTestHarness {
33  public:
34   TestHarness();
35   ~TestHarness() override;
36 
37   void SetUp() override;
38 
39   ConfigurationPolicyProvider* CreateProvider(
40       SchemaRegistry* registry,
41       scoped_refptr<base::SequencedTaskRunner> task_runner) override;
42 
43   void InstallEmptyPolicy() override;
44   void InstallStringPolicy(const std::string& policy_name,
45                            const std::string& policy_value) override;
46   void InstallIntegerPolicy(const std::string& policy_name,
47                             int policy_value) override;
48   void InstallBooleanPolicy(const std::string& policy_name,
49                             bool policy_value) override;
50   void InstallStringListPolicy(const std::string& policy_name,
51                                const base::ListValue* policy_value) override;
52   void InstallDictionaryPolicy(
53       const std::string& policy_name,
54       const base::DictionaryValue* policy_value) override;
55   void Install3rdPartyPolicy(const base::DictionaryValue* policies) override;
56 
test_dir()57   const base::FilePath& test_dir() { return test_dir_.GetPath(); }
58 
59   // JSON-encode a dictionary and write it to a file.
60   void WriteConfigFile(const base::DictionaryValue& dict,
61                        const std::string& file_name);
62 
63   // Returns a unique name for a policy file. Each subsequent call returns a new
64   // name that comes lexicographically after the previous one.
65   std::string NextConfigFileName();
66 
67   static PolicyProviderTestHarness* Create();
68 
69  private:
70   base::ScopedTempDir test_dir_;
71   int next_policy_file_index_;
72 
73   DISALLOW_COPY_AND_ASSIGN(TestHarness);
74 };
75 
TestHarness()76 TestHarness::TestHarness()
77     : PolicyProviderTestHarness(POLICY_LEVEL_MANDATORY,
78                                 POLICY_SCOPE_MACHINE,
79                                 POLICY_SOURCE_PLATFORM),
80       next_policy_file_index_(100) {}
81 
~TestHarness()82 TestHarness::~TestHarness() {}
83 
SetUp()84 void TestHarness::SetUp() {
85   ASSERT_TRUE(test_dir_.CreateUniqueTempDir());
86 }
87 
CreateProvider(SchemaRegistry * registry,scoped_refptr<base::SequencedTaskRunner> task_runner)88 ConfigurationPolicyProvider* TestHarness::CreateProvider(
89     SchemaRegistry* registry,
90     scoped_refptr<base::SequencedTaskRunner> task_runner) {
91   std::unique_ptr<AsyncPolicyLoader> loader(
92       new ConfigDirPolicyLoader(task_runner, test_dir(), POLICY_SCOPE_MACHINE));
93   return new AsyncPolicyProvider(registry, std::move(loader));
94 }
95 
InstallEmptyPolicy()96 void TestHarness::InstallEmptyPolicy() {
97   base::DictionaryValue dict;
98   WriteConfigFile(dict, NextConfigFileName());
99 }
100 
InstallStringPolicy(const std::string & policy_name,const std::string & policy_value)101 void TestHarness::InstallStringPolicy(const std::string& policy_name,
102                                       const std::string& policy_value) {
103   base::DictionaryValue dict;
104   dict.SetString(policy_name, policy_value);
105   WriteConfigFile(dict, NextConfigFileName());
106 }
107 
InstallIntegerPolicy(const std::string & policy_name,int policy_value)108 void TestHarness::InstallIntegerPolicy(const std::string& policy_name,
109                                        int policy_value) {
110   base::DictionaryValue dict;
111   dict.SetInteger(policy_name, policy_value);
112   WriteConfigFile(dict, NextConfigFileName());
113 }
114 
InstallBooleanPolicy(const std::string & policy_name,bool policy_value)115 void TestHarness::InstallBooleanPolicy(const std::string& policy_name,
116                                        bool policy_value) {
117   base::DictionaryValue dict;
118   dict.SetBoolean(policy_name, policy_value);
119   WriteConfigFile(dict, NextConfigFileName());
120 }
121 
InstallStringListPolicy(const std::string & policy_name,const base::ListValue * policy_value)122 void TestHarness::InstallStringListPolicy(const std::string& policy_name,
123                                           const base::ListValue* policy_value) {
124   base::DictionaryValue dict;
125   dict.Set(policy_name, std::make_unique<base::Value>(policy_value->Clone()));
126   WriteConfigFile(dict, NextConfigFileName());
127 }
128 
InstallDictionaryPolicy(const std::string & policy_name,const base::DictionaryValue * policy_value)129 void TestHarness::InstallDictionaryPolicy(
130     const std::string& policy_name,
131     const base::DictionaryValue* policy_value) {
132   base::DictionaryValue dict;
133   dict.Set(policy_name, std::make_unique<base::Value>(policy_value->Clone()));
134   WriteConfigFile(dict, NextConfigFileName());
135 }
136 
Install3rdPartyPolicy(const base::DictionaryValue * policies)137 void TestHarness::Install3rdPartyPolicy(const base::DictionaryValue* policies) {
138   base::DictionaryValue dict;
139   dict.SetKey("3rdparty", policies->Clone());
140   WriteConfigFile(dict, NextConfigFileName());
141 }
142 
WriteConfigFile(const base::DictionaryValue & dict,const std::string & file_name)143 void TestHarness::WriteConfigFile(const base::DictionaryValue& dict,
144                                   const std::string& file_name) {
145   std::string data;
146   JSONStringValueSerializer serializer(&data);
147   serializer.Serialize(dict);
148   const base::FilePath mandatory_dir(test_dir().Append(kMandatoryPath));
149   ASSERT_TRUE(base::CreateDirectory(mandatory_dir));
150   const base::FilePath file_path(mandatory_dir.AppendASCII(file_name));
151   ASSERT_EQ((int) data.size(),
152             base::WriteFile(file_path, data.c_str(), data.size()));
153 }
154 
NextConfigFileName()155 std::string TestHarness::NextConfigFileName() {
156   EXPECT_LE(next_policy_file_index_, 999);
157   return std::string("policy") + base::IntToString(next_policy_file_index_++);
158 }
159 
160 // static
Create()161 PolicyProviderTestHarness* TestHarness::Create() {
162   return new TestHarness();
163 }
164 
165 }  // namespace
166 
167 // Instantiate abstract test case for basic policy reading tests.
168 INSTANTIATE_TEST_CASE_P(
169     ConfigDirPolicyLoaderTest,
170     ConfigurationPolicyProviderTest,
171     testing::Values(TestHarness::Create));
172 
173 // Instantiate abstract test case for 3rd party policy reading tests.
174 INSTANTIATE_TEST_CASE_P(
175     ConfigDir3rdPartyPolicyLoaderTest,
176     Configuration3rdPartyPolicyProviderTest,
177     testing::Values(TestHarness::Create));
178 
179 // Some tests that exercise special functionality in ConfigDirPolicyLoader.
180 class ConfigDirPolicyLoaderTest : public PolicyTestBase {
181  protected:
SetUp()182   void SetUp() override {
183     PolicyTestBase::SetUp();
184     harness_.SetUp();
185   }
186 
187   TestHarness harness_;
188 };
189 
190 // The preferences dictionary is expected to be empty when there are no files to
191 // load.
TEST_F(ConfigDirPolicyLoaderTest,ReadPrefsEmpty)192 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsEmpty) {
193   ConfigDirPolicyLoader loader(
194       scoped_task_environment_.GetMainThreadTaskRunner(), harness_.test_dir(),
195       POLICY_SCOPE_MACHINE);
196   std::unique_ptr<PolicyBundle> bundle(loader.Load());
197   ASSERT_TRUE(bundle.get());
198   const PolicyBundle kEmptyBundle;
199   EXPECT_TRUE(bundle->Equals(kEmptyBundle));
200 }
201 
202 // Reading from a non-existent directory should result in an empty preferences
203 // dictionary.
TEST_F(ConfigDirPolicyLoaderTest,ReadPrefsNonExistentDirectory)204 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsNonExistentDirectory) {
205   base::FilePath non_existent_dir(
206       harness_.test_dir().Append(FILE_PATH_LITERAL("not_there")));
207   ConfigDirPolicyLoader loader(
208       scoped_task_environment_.GetMainThreadTaskRunner(), non_existent_dir,
209       POLICY_SCOPE_MACHINE);
210   std::unique_ptr<PolicyBundle> bundle(loader.Load());
211   ASSERT_TRUE(bundle.get());
212   const PolicyBundle kEmptyBundle;
213   EXPECT_TRUE(bundle->Equals(kEmptyBundle));
214 }
215 
216 // Test merging values from different files.
TEST_F(ConfigDirPolicyLoaderTest,ReadPrefsMergePrefs)217 TEST_F(ConfigDirPolicyLoaderTest, ReadPrefsMergePrefs) {
218   // Write a bunch of data files in order to increase the chance to detect the
219   // provider not respecting lexicographic ordering when reading them. Since the
220   // filesystem may return files in arbitrary order, there is no way to be sure,
221   // but this is better than nothing.
222   base::DictionaryValue test_dict_bar;
223   test_dict_bar.SetString("HomepageLocation", "http://bar.com");
224   for (unsigned int i = 1; i <= 4; ++i)
225     harness_.WriteConfigFile(test_dict_bar, base::UintToString(i));
226   base::DictionaryValue test_dict_foo;
227   test_dict_foo.SetString("HomepageLocation", "http://foo.com");
228   harness_.WriteConfigFile(test_dict_foo, "9");
229   for (unsigned int i = 5; i <= 8; ++i)
230     harness_.WriteConfigFile(test_dict_bar, base::UintToString(i));
231 
232   ConfigDirPolicyLoader loader(
233       scoped_task_environment_.GetMainThreadTaskRunner(), harness_.test_dir(),
234       POLICY_SCOPE_USER);
235   std::unique_ptr<PolicyBundle> bundle(loader.Load());
236   ASSERT_TRUE(bundle.get());
237   PolicyBundle expected_bundle;
238   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
239       .LoadFrom(&test_dict_foo, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
240                 POLICY_SOURCE_PLATFORM);
241   EXPECT_TRUE(bundle->Equals(expected_bundle));
242 }
243 
244 }  // namespace policy
245