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