Home | History | Annotate | Download | only in policy
      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 "chrome/browser/policy/configuration_policy_provider_test.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/values.h"
     11 #include "chrome/browser/policy/configuration_policy_provider.h"
     12 #include "chrome/browser/policy/external_data_fetcher.h"
     13 #include "chrome/browser/policy/mock_configuration_policy_provider.h"
     14 #include "chrome/browser/policy/policy_bundle.h"
     15 #include "chrome/browser/policy/policy_map.h"
     16 #include "policy/policy_constants.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 
     19 using content::BrowserThread;
     20 using ::testing::Mock;
     21 using ::testing::_;
     22 
     23 namespace policy {
     24 
     25 namespace test_policy_definitions {
     26 
     27 const char kKeyString[] = "StringPolicy";
     28 const char kKeyBoolean[] = "BooleanPolicy";
     29 const char kKeyInteger[] = "IntegerPolicy";
     30 const char kKeyStringList[] = "StringListPolicy";
     31 const char kKeyDictionary[] = "DictionaryPolicy";
     32 
     33 static const PolicyDefinitionList::Entry kEntries[] = {
     34   { kKeyString,     base::Value::TYPE_STRING },
     35   { kKeyBoolean,    base::Value::TYPE_BOOLEAN },
     36   { kKeyInteger,    base::Value::TYPE_INTEGER },
     37   { kKeyStringList, base::Value::TYPE_LIST },
     38   { kKeyDictionary, base::Value::TYPE_DICTIONARY },
     39 };
     40 
     41 const PolicyDefinitionList kList = {
     42   kEntries, kEntries + arraysize(kEntries)
     43 };
     44 
     45 }  // namespace test_policy_definitions
     46 
     47 PolicyTestBase::PolicyTestBase()
     48     : ui_thread_(BrowserThread::UI, &loop_),
     49       file_thread_(BrowserThread::FILE, &loop_) {}
     50 
     51 PolicyTestBase::~PolicyTestBase() {}
     52 
     53 void PolicyTestBase::TearDown() {
     54   loop_.RunUntilIdle();
     55 }
     56 
     57 PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level,
     58                                                      PolicyScope scope)
     59     : level_(level), scope_(scope) {}
     60 
     61 PolicyProviderTestHarness::~PolicyProviderTestHarness() {}
     62 
     63 PolicyLevel PolicyProviderTestHarness::policy_level() const {
     64   return level_;
     65 }
     66 
     67 PolicyScope PolicyProviderTestHarness::policy_scope() const {
     68   return scope_;
     69 }
     70 
     71 void PolicyProviderTestHarness::Install3rdPartyPolicy(
     72     const base::DictionaryValue* policies) {
     73   FAIL();
     74 }
     75 
     76 ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {}
     77 
     78 ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {}
     79 
     80 void ConfigurationPolicyProviderTest::SetUp() {
     81   PolicyTestBase::SetUp();
     82 
     83   test_harness_.reset((*GetParam())());
     84   test_harness_->SetUp();
     85 
     86   provider_.reset(
     87       test_harness_->CreateProvider(&test_policy_definitions::kList));
     88   provider_->Init();
     89   // Some providers do a reload on init. Make sure any notifications generated
     90   // are fired now.
     91   loop_.RunUntilIdle();
     92 
     93   const PolicyBundle kEmptyBundle;
     94   EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
     95 }
     96 
     97 void ConfigurationPolicyProviderTest::TearDown() {
     98   // Give providers the chance to clean up after themselves on the file thread.
     99   provider_->Shutdown();
    100   provider_.reset();
    101 
    102   PolicyTestBase::TearDown();
    103 }
    104 
    105 void ConfigurationPolicyProviderTest::CheckValue(
    106     const char* policy_name,
    107     const base::Value& expected_value,
    108     base::Closure install_value) {
    109   // Install the value, reload policy and check the provider for the value.
    110   install_value.Run();
    111   provider_->RefreshPolicies();
    112   loop_.RunUntilIdle();
    113   PolicyBundle expected_bundle;
    114   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
    115       .Set(policy_name,
    116            test_harness_->policy_level(),
    117            test_harness_->policy_scope(),
    118            expected_value.DeepCopy(),
    119            NULL);
    120   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
    121   // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too,
    122   // and extend the |expected_bundle|, once all providers are ready.
    123 }
    124 
    125 TEST_P(ConfigurationPolicyProviderTest, Empty) {
    126   provider_->RefreshPolicies();
    127   loop_.RunUntilIdle();
    128   const PolicyBundle kEmptyBundle;
    129   EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
    130 }
    131 
    132 TEST_P(ConfigurationPolicyProviderTest, StringValue) {
    133   const char kTestString[] = "string_value";
    134   base::StringValue expected_value(kTestString);
    135   CheckValue(test_policy_definitions::kKeyString,
    136              expected_value,
    137              base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
    138                         base::Unretained(test_harness_.get()),
    139                         test_policy_definitions::kKeyString,
    140                         kTestString));
    141 }
    142 
    143 TEST_P(ConfigurationPolicyProviderTest, BooleanValue) {
    144   base::FundamentalValue expected_value(true);
    145   CheckValue(test_policy_definitions::kKeyBoolean,
    146              expected_value,
    147              base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy,
    148                         base::Unretained(test_harness_.get()),
    149                         test_policy_definitions::kKeyBoolean,
    150                         true));
    151 }
    152 
    153 TEST_P(ConfigurationPolicyProviderTest, IntegerValue) {
    154   base::FundamentalValue expected_value(42);
    155   CheckValue(test_policy_definitions::kKeyInteger,
    156              expected_value,
    157              base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy,
    158                         base::Unretained(test_harness_.get()),
    159                         test_policy_definitions::kKeyInteger,
    160                         42));
    161 }
    162 
    163 TEST_P(ConfigurationPolicyProviderTest, StringListValue) {
    164   base::ListValue expected_value;
    165   expected_value.Set(0U, base::Value::CreateStringValue("first"));
    166   expected_value.Set(1U, base::Value::CreateStringValue("second"));
    167   CheckValue(test_policy_definitions::kKeyStringList,
    168              expected_value,
    169              base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
    170                         base::Unretained(test_harness_.get()),
    171                         test_policy_definitions::kKeyStringList,
    172                         &expected_value));
    173 }
    174 
    175 TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) {
    176   base::DictionaryValue expected_value;
    177   expected_value.SetBoolean("bool", true);
    178   expected_value.SetInteger("int", 123);
    179   expected_value.SetString("str", "omg");
    180 
    181   base::ListValue* list = new base::ListValue();
    182   list->Set(0U, base::Value::CreateStringValue("first"));
    183   list->Set(1U, base::Value::CreateStringValue("second"));
    184   expected_value.Set("list", list);
    185 
    186   base::DictionaryValue* dict = new base::DictionaryValue();
    187   dict->SetString("sub", "value");
    188   list = new base::ListValue();
    189   base::DictionaryValue* sub = new base::DictionaryValue();
    190   sub->SetInteger("aaa", 111);
    191   sub->SetInteger("bbb", 222);
    192   list->Append(sub);
    193   sub = new base::DictionaryValue();
    194   sub->SetString("ccc", "333");
    195   sub->SetString("ddd", "444");
    196   list->Append(sub);
    197   dict->Set("sublist", list);
    198   expected_value.Set("dict", dict);
    199 
    200   CheckValue(test_policy_definitions::kKeyDictionary,
    201              expected_value,
    202              base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy,
    203                         base::Unretained(test_harness_.get()),
    204                         test_policy_definitions::kKeyDictionary,
    205                         &expected_value));
    206 }
    207 
    208 TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) {
    209   PolicyBundle bundle;
    210   EXPECT_TRUE(provider_->policies().Equals(bundle));
    211 
    212   // OnUpdatePolicy is called even when there are no changes.
    213   MockConfigurationPolicyObserver observer;
    214   provider_->AddObserver(&observer);
    215   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
    216   provider_->RefreshPolicies();
    217   loop_.RunUntilIdle();
    218   Mock::VerifyAndClearExpectations(&observer);
    219 
    220   EXPECT_TRUE(provider_->policies().Equals(bundle));
    221 
    222   // OnUpdatePolicy is called when there are changes.
    223   test_harness_->InstallStringPolicy(test_policy_definitions::kKeyString,
    224                                      "value");
    225   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
    226   provider_->RefreshPolicies();
    227   loop_.RunUntilIdle();
    228   Mock::VerifyAndClearExpectations(&observer);
    229 
    230   bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
    231       .Set(test_policy_definitions::kKeyString,
    232            test_harness_->policy_level(),
    233            test_harness_->policy_scope(),
    234            base::Value::CreateStringValue("value"),
    235            NULL);
    236   EXPECT_TRUE(provider_->policies().Equals(bundle));
    237   provider_->RemoveObserver(&observer);
    238 }
    239 
    240 TEST(ConfigurationPolicyProviderTest, FixDeprecatedPolicies) {
    241   PolicyMap policy_map;
    242   policy_map.Set(key::kProxyServerMode,
    243                  POLICY_LEVEL_MANDATORY,
    244                  POLICY_SCOPE_USER,
    245                  base::Value::CreateIntegerValue(3),
    246                  NULL);
    247 
    248   // Both these policies should be ignored, since there's a higher priority
    249   // policy available.
    250   policy_map.Set(key::kProxyMode,
    251                  POLICY_LEVEL_RECOMMENDED,
    252                  POLICY_SCOPE_USER,
    253                  base::Value::CreateStringValue("pac_script"),
    254                  NULL);
    255   policy_map.Set(key::kProxyPacUrl,
    256                  POLICY_LEVEL_RECOMMENDED,
    257                  POLICY_SCOPE_USER,
    258                  base::Value::CreateStringValue("http://example.com/wpad.dat"),
    259                  NULL);
    260 
    261   MockConfigurationPolicyProvider provider;
    262   provider.Init();
    263   provider.UpdateChromePolicy(policy_map);
    264 
    265   PolicyBundle expected_bundle;
    266   base::DictionaryValue* expected_value = new base::DictionaryValue();
    267   expected_value->SetInteger(key::kProxyServerMode, 3);
    268   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
    269       .Set(key::kProxySettings,
    270            POLICY_LEVEL_MANDATORY,
    271            POLICY_SCOPE_USER,
    272            expected_value,
    273            NULL);
    274   EXPECT_TRUE(provider.policies().Equals(expected_bundle));
    275   provider.Shutdown();
    276 }
    277 
    278 Configuration3rdPartyPolicyProviderTest::
    279     Configuration3rdPartyPolicyProviderTest() {}
    280 
    281 Configuration3rdPartyPolicyProviderTest::
    282     ~Configuration3rdPartyPolicyProviderTest() {}
    283 
    284 TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) {
    285   base::DictionaryValue policy_dict;
    286   policy_dict.SetBoolean("bool", true);
    287   policy_dict.SetDouble("double", 123.456);
    288   policy_dict.SetInteger("int", 789);
    289   policy_dict.SetString("str", "string value");
    290 
    291   base::ListValue* list = new base::ListValue();
    292   for (int i = 0; i < 2; ++i) {
    293     base::DictionaryValue* dict = new base::DictionaryValue();
    294     dict->SetInteger("subdictindex", i);
    295     dict->Set("subdict", policy_dict.DeepCopy());
    296     list->Append(dict);
    297   }
    298   policy_dict.Set("list", list);
    299   policy_dict.Set("dict", policy_dict.DeepCopy());
    300 
    301   // Install these policies as a Chrome policy.
    302   test_harness_->InstallDictionaryPolicy(
    303       test_policy_definitions::kKeyDictionary, &policy_dict);
    304   // Install them as 3rd party policies too.
    305   base::DictionaryValue policy_3rdparty;
    306   policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    307                       policy_dict.DeepCopy());
    308   policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    309                       policy_dict.DeepCopy());
    310   // Install invalid 3rd party policies that shouldn't be loaded. These also
    311   // help detecting memory leaks in the code paths that detect invalid input.
    312   policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy());
    313   policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc",
    314                       base::Value::CreateStringValue("invalid-value"));
    315   test_harness_->Install3rdPartyPolicy(&policy_3rdparty);
    316 
    317   provider_->RefreshPolicies();
    318   loop_.RunUntilIdle();
    319 
    320   PolicyMap expected_policy;
    321   expected_policy.Set(test_policy_definitions::kKeyDictionary,
    322                       test_harness_->policy_level(),
    323                       test_harness_->policy_scope(),
    324                       policy_dict.DeepCopy(),
    325                       NULL);
    326   PolicyBundle expected_bundle;
    327   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
    328       .CopyFrom(expected_policy);
    329   expected_policy.Clear();
    330   expected_policy.LoadFrom(&policy_dict,
    331                            test_harness_->policy_level(),
    332                            test_harness_->policy_scope());
    333   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
    334                                       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
    335       .CopyFrom(expected_policy);
    336   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
    337                                       "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
    338       .CopyFrom(expected_policy);
    339   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
    340 }
    341 
    342 }  // namespace policy
    343