Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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/cloud_policy_provider.h" | |
| 6 | |
| 7 #include <set> | |
| 8 | |
| 9 #include "base/values.h" | |
| 10 #include "chrome/browser/policy/cloud_policy_cache_base.h" | |
| 11 #include "chrome/browser/policy/cloud_policy_provider.h" | |
| 12 #include "chrome/browser/policy/configuration_policy_pref_store.h" | |
| 13 #include "chrome/browser/policy/mock_configuration_policy_store.h" | |
| 14 #include "testing/gmock/include/gmock/gmock.h" | |
| 15 | |
| 16 | |
| 17 namespace policy { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 ConfigurationPolicyType proxy_policies[]= { kPolicyProxyMode, | |
| 22 kPolicyProxyServerMode, | |
| 23 kPolicyProxyServer, | |
| 24 kPolicyProxyPacUrl, | |
| 25 kPolicyProxyBypassList }; | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 MATCHER_P(IntegerValueMatcher, expect, "Matcher for IntegerValue-types") { | |
| 30 DCHECK(arg); | |
| 31 int value; | |
| 32 DCHECK(reinterpret_cast<const Value*>(arg)->GetAsInteger(&value)); | |
|
Joao da Silva
2011/05/31 14:50:23
DCHECK will be removed on non-debug builds, and th
sfeuz
2011/06/03 08:30:35
Done. Nice catch.
| |
| 33 return value == expect; | |
| 34 } | |
| 35 | |
| 36 class MockCloudPolicyCacheBase : public CloudPolicyCacheBase { | |
| 37 public: | |
| 38 MockCloudPolicyCacheBase() {} | |
| 39 virtual ~MockCloudPolicyCacheBase() {} | |
| 40 | |
| 41 // CloudPolicyCacheBase Implementation. | |
| 42 void Load(){} | |
| 43 void SetPolicy(const em::PolicyFetchResponse& policy) {} | |
| 44 bool DecodePolicyData(const em::PolicyData& policy_data, | |
| 45 PolicyMap* mandatory, | |
| 46 PolicyMap* recommended) { | |
| 47 return true; | |
| 48 } | |
| 49 void SetUnmanaged() { | |
| 50 is_unmanaged_ = true; | |
| 51 } | |
| 52 | |
| 53 void set_initialized() { | |
| 54 initialization_complete_ = true; | |
| 55 } | |
| 56 | |
| 57 void set_uninitialized() { | |
| 58 initialization_complete_ = false; | |
| 59 } | |
| 60 | |
| 61 }; | |
| 62 class CombiningCloudPolicyProviderTest : public testing::Test { | |
| 63 public: | |
| 64 void CreateCombiningCloudPolicyProvider( | |
| 65 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list) { | |
| 66 combining_cloud_policy_provider_.reset( | |
| 67 new CombiningCloudPolicyProvider(policy_list)); | |
| 68 } | |
| 69 | |
| 70 void CreateCombiningCloudPolicyProvider() { | |
| 71 CreateCombiningCloudPolicyProvider( | |
| 72 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList()); | |
| 73 } | |
| 74 | |
| 75 void Provide(ConfigurationPolicyStoreInterface* store) { | |
| 76 DCHECK(combining_cloud_policy_provider_.get()); | |
| 77 combining_cloud_policy_provider_.get()->Provide(store); | |
| 78 } | |
| 79 | |
| 80 void AddCloudPolicyProvider(CloudPolicyProvider* cloud_policy_provider) { | |
| 81 DCHECK(combining_cloud_policy_provider_.get()); | |
| 82 combining_cloud_policy_provider_.get()->AddCloudPolicyProvider( | |
| 83 cloud_policy_provider); | |
| 84 } | |
| 85 | |
| 86 private: | |
| 87 scoped_ptr<CombiningCloudPolicyProvider> combining_cloud_policy_provider_; | |
| 88 | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: remove extra line?
sfeuz
2011/06/03 08:30:35
Done.
| |
| 89 }; | |
| 90 | |
| 91 // Proxy setting distributed over multiple caches. | |
| 92 TEST_F(CombiningCloudPolicyProviderTest, | |
| 93 ProxySettingDistributedOverMultipleCaches) { | |
| 94 | |
| 95 const unsigned int proxy_related_policies = arraysize(proxy_policies); | |
| 96 | |
| 97 // There are |proxy_related_policies|+1 instances of CloudPolicyProvider, | |
| 98 // which are mixed together by one instance of CombiningCloudPolicyProvider. | |
| 99 // The first CloudPolicyProvider has some policies but no proxy-related ones. | |
| 100 // The following ones have each one proxy-policy set. | |
| 101 const unsigned int n = proxy_related_policies + 1; | |
| 102 | |
| 103 scoped_ptr<CloudPolicyProvider> providers[n]; | |
| 104 MockCloudPolicyCacheBase caches[n]; | |
| 105 | |
| 106 const ConfigurationPolicyProvider::PolicyDefinitionList* list = | |
| 107 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); | |
| 108 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; | |
| 109 | |
| 110 // Prepare |cache[0]| to serve some non-proxy policies. | |
| 111 caches[0].set_initialized(); | |
| 112 caches[0].mandatory_policy()->Set(kPolicyShowHomeButton, | |
| 113 Value::CreateBooleanValue(true)); | |
| 114 caches[0].recommended_policy()->Set(kPolicyShowHomeButton, | |
| 115 Value::CreateBooleanValue(true)); | |
| 116 | |
| 117 caches[0].mandatory_policy()->Set(kPolicyIncognitoEnabled, | |
| 118 Value::CreateBooleanValue(true)); | |
| 119 caches[0].recommended_policy()->Set(kPolicyIncognitoEnabled, | |
| 120 Value::CreateBooleanValue(true)); | |
| 121 | |
| 122 caches[0].mandatory_policy()->Set(kPolicyTranslateEnabled, | |
| 123 Value::CreateBooleanValue(true)); | |
| 124 caches[0].recommended_policy()->Set(kPolicyTranslateEnabled, | |
| 125 Value::CreateBooleanValue(true)); | |
| 126 | |
| 127 // Prepare the other caches to serve one proxy-policy each. | |
| 128 caches[1].set_initialized(); | |
| 129 caches[1].mandatory_policy()->Set(kPolicyProxyMode, | |
| 130 Value::CreateStringValue("cache 1")); | |
| 131 caches[1].mandatory_policy()->Set(kPolicyProxyMode, | |
| 132 Value::CreateStringValue("cache 1")); | |
| 133 | |
| 134 caches[2].set_initialized(); | |
| 135 caches[2].mandatory_policy()->Set(kPolicyProxyServerMode, | |
| 136 Value::CreateIntegerValue(2)); | |
| 137 caches[2].mandatory_policy()->Set(kPolicyProxyServerMode, | |
| 138 Value::CreateIntegerValue(2)); | |
| 139 | |
| 140 caches[3].set_initialized(); | |
| 141 caches[3].mandatory_policy()->Set(kPolicyProxyServer, | |
| 142 Value::CreateStringValue("cache 3")); | |
| 143 caches[3].mandatory_policy()->Set(kPolicyProxyServer, | |
| 144 Value::CreateStringValue("cache 3")); | |
| 145 | |
| 146 caches[4].set_initialized(); | |
| 147 caches[4].mandatory_policy()->Set(kPolicyProxyPacUrl, | |
| 148 Value::CreateStringValue("cache 4")); | |
| 149 caches[4].mandatory_policy()->Set(kPolicyProxyPacUrl, | |
| 150 Value::CreateStringValue("cache 4")); | |
| 151 | |
| 152 caches[5].set_initialized(); | |
| 153 caches[5].mandatory_policy()->Set(kPolicyProxyMode, | |
| 154 Value::CreateStringValue("cache 5")); | |
| 155 caches[5].mandatory_policy()->Set(kPolicyProxyMode, | |
| 156 Value::CreateStringValue("cache 5")); | |
| 157 | |
| 158 // Make sure that our assumptions about the existing proxy-related policies | |
| 159 // are still correct. | |
| 160 DCHECK( proxy_related_policies == 5 ); | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: extra spaces next to the parenthesis?
sfeuz
2011/06/03 08:30:35
Done.
| |
| 161 | |
| 162 // Connect the caches to the providers as a one-to-one mapping. | |
| 163 for (unsigned int i = 0; i<n ; ++i) { | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: i < n (spaces)
sfeuz
2011/06/03 08:30:35
Done.
| |
| 164 providers[i].reset(new CloudPolicyProvider( | |
| 165 list, | |
| 166 CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY)); | |
| 167 providers[i].get()->set_cache(caches + i); | |
| 168 } | |
| 169 | |
| 170 CreateCombiningCloudPolicyProvider(); | |
| 171 | |
| 172 for (unsigned int i = 0; i < n; ++i) | |
| 173 AddCloudPolicyProvider(providers[i].get()); | |
| 174 | |
| 175 MockConfigurationPolicyStore store; | |
| 176 Provide(&store); | |
| 177 | |
| 178 // The final compilation should have all policies but the proxy-policies set | |
| 179 // to NULL. Of the proxy-related policies only |kPolicyProxyMode| is set. | |
| 180 for (current = list->begin; current != list->end; ++current) { | |
| 181 bool is_proxy_policy = false; | |
| 182 for (unsigned int i = 0;i < proxy_related_policies; ++i) { | |
| 183 if (current->policy_type == proxy_policies[i]) { | |
| 184 is_proxy_policy = true; | |
| 185 break; | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 const Value* value = store.Get(current->policy_type); | |
| 190 if (current->policy_type == kPolicyProxyMode) { | |
| 191 EXPECT_TRUE(value); | |
| 192 std::string string_value; | |
| 193 bool result = value->GetAsString(&string_value); | |
| 194 DCHECK(result); | |
|
Joao da Silva
2011/05/31 14:50:23
Why not EXPECT_TRUE?
sfeuz
2011/06/03 08:30:35
Done. I tried to make a distinction between test-r
| |
| 195 EXPECT_EQ(string_value, "cache 1"); | |
| 196 } else if (is_proxy_policy) { | |
| 197 EXPECT_FALSE(value); | |
| 198 } else if (current->policy_type == kPolicyShowHomeButton || | |
| 199 current->policy_type == kPolicyIncognitoEnabled || | |
| 200 current->policy_type == kPolicyTranslateEnabled) { | |
| 201 EXPECT_TRUE(value); | |
| 202 bool boolean_value = false; | |
| 203 bool result = value->GetAsBoolean(&boolean_value); | |
| 204 DCHECK(result); | |
| 205 EXPECT_TRUE(boolean_value); | |
| 206 } else { | |
| 207 EXPECT_FALSE(value); | |
| 208 } | |
| 209 } | |
| 210 } | |
| 211 | |
| 212 // No caches behind CloudPolicyProviders. | |
| 213 TEST_F(CombiningCloudPolicyProviderTest, NoCaches) { | |
| 214 | |
| 215 // |n| denotes the number of instances of CloudPolicyProvider, which are mixed | |
| 216 // together by one instance of CombiningCloudPolicyProvider. | |
| 217 // None of the CloudPolicyProvider instances will have assigned a cache. | |
| 218 const unsigned int n = 75; | |
| 219 const ConfigurationPolicyProvider::PolicyDefinitionList* list = | |
| 220 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); | |
| 221 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; | |
| 222 | |
| 223 scoped_ptr<CloudPolicyProvider> providers[n]; | |
| 224 | |
| 225 for (unsigned int i = 0; i<n ; ++i) { | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: i < n (spaces)
sfeuz
2011/06/03 08:30:35
Obsolete.
| |
| 226 providers[i].reset(new CloudPolicyProvider( | |
| 227 list, | |
| 228 CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY)); | |
| 229 } | |
| 230 | |
| 231 CreateCombiningCloudPolicyProvider(list); | |
| 232 | |
| 233 MockConfigurationPolicyStore store; | |
| 234 for (unsigned int i = 0; i < n; ++i) { | |
| 235 AddCloudPolicyProvider(providers[i].get()); | |
| 236 Provide(&store); | |
| 237 } | |
| 238 | |
| 239 // The final compilation should have no policies set. | |
| 240 current = list->begin; | |
| 241 for (current = list->begin; current != list->end; ++current) | |
| 242 EXPECT_FALSE(store.Get(current->policy_type)); | |
| 243 } | |
| 244 | |
| 245 // Having many different CloudPolicyProviders adding them incrementally. | |
| 246 TEST_F(CombiningCloudPolicyProviderTest, MultipleProviders) { | |
| 247 | |
| 248 // |n| denotes the number of instances of CloudPolicyProvider, which are mixed | |
| 249 // together by one instance of CombiningCloudPolicyProvider. | |
| 250 // Every other instance is set to be initialized (starting with a | |
| 251 // non-initialized one). | |
| 252 // Each instance of CloudPolicyProvider will have its own cache as a | |
| 253 // backend and the i-th instance will serve i policies and come at position i | |
| 254 // in the list of CombiningCloudPolicyProvider. Thus in the end there should | |
| 255 // be exactly two policies applied per initialized instance. | |
| 256 const unsigned int n = 101; | |
| 257 | |
| 258 const char* key_template = "Policy %03u"; | |
| 259 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; | |
| 260 | |
| 261 // Numbers bigger than 1000 will mess with the key_template. | |
| 262 DCHECK(n - arraysize(proxy_policies) < 1000); | |
|
Joao da Silva
2011/05/31 14:50:23
EXPECT_TRUE?
sfeuz
2011/06/03 08:30:35
It is a DCHECK because this actually checks if som
| |
| 263 | |
| 264 // |simple_list| is a policy list with entries of the form | |
| 265 // {(ConfigurationPolicyType)(7), Value::TYPE_INTEGER, "Policy 007"}. | |
| 266 ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[n]; | |
| 267 | |
| 268 // Note that key_template is exactly one char longer than the resulting keys, | |
| 269 // thus making the arrays correctly sized (including the trailing \0). | |
| 270 const unsigned int key_length = strlen(key_template); | |
| 271 char keys[n][key_length]; | |
| 272 unsigned int counter = 0; | |
| 273 for (unsigned int i = 0; i < n; ++counter) { | |
| 274 bool is_proxy_policy = false; | |
| 275 for (unsigned int j = 0;j < arraysize(proxy_policies); ++j) { | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: space after j = 0;
sfeuz
2011/06/03 08:30:35
Done.
| |
| 276 if ((ConfigurationPolicyType)counter == proxy_policies[j]) { | |
| 277 is_proxy_policy = true; | |
| 278 break; | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 // We do not want to interfere with the proxy related policies since they | |
| 283 // are treated as a special case inside CombiningCloudPolicyProvider. | |
| 284 if (is_proxy_policy) | |
| 285 continue; | |
| 286 | |
| 287 snprintf(keys[i], key_length, key_template, counter); | |
| 288 entries[i].policy_type = (ConfigurationPolicyType)counter; | |
| 289 entries[i].value_type = Value::TYPE_INTEGER; | |
| 290 entries[i].name = (const char*)keys[i]; | |
| 291 ++i; | |
| 292 } | |
| 293 ConfigurationPolicyProvider::PolicyDefinitionList simple_list = | |
| 294 {entries, | |
| 295 entries+n}; | |
| 296 const int max_counter = counter; | |
| 297 | |
| 298 MockCloudPolicyCacheBase caches[n]; | |
| 299 scoped_ptr<CloudPolicyProvider> providers[n]; | |
| 300 | |
| 301 // Prepare |cache[i]| to serve the first i policies form |simple_list|. | |
| 302 for (unsigned int i = 0; i < n; ++i) { | |
| 303 current = simple_list.begin; | |
| 304 for (unsigned int j = 0; j <= i; ++j, ++current) { | |
| 305 // Set a unique value. | |
| 306 caches[i].mandatory_policy()->Set( | |
| 307 current->policy_type, | |
| 308 Value::CreateIntegerValue(i*max_counter + (int)current->policy_type)); | |
| 309 caches[i].recommended_policy()->Set( | |
| 310 current->policy_type, | |
| 311 Value::CreateIntegerValue(i*max_counter + (int)current->policy_type)); | |
| 312 if (i&1) | |
| 313 caches[i].set_initialized(); | |
| 314 else | |
| 315 caches[i].set_uninitialized(); | |
| 316 } | |
| 317 } | |
| 318 | |
| 319 // Connect the caches to the providers as a one-to-one mapping. | |
| 320 for (unsigned int i = 0; i<n ; ++i) { | |
|
Joao da Silva
2011/05/31 14:50:23
Nit: i < n (spaces)
sfeuz
2011/06/03 08:30:35
Obsolete.
| |
| 321 providers[i].reset(new CloudPolicyProvider( | |
| 322 (const ConfigurationPolicyProvider::PolicyDefinitionList*) &simple_list, | |
| 323 CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY)); | |
| 324 providers[i].get()->set_cache(caches + i); | |
| 325 } | |
| 326 | |
| 327 CreateCombiningCloudPolicyProvider(&simple_list); | |
| 328 | |
| 329 // We expect that every new arriving provider only can serve its last two | |
| 330 // policies and only if it is inizialized. | |
| 331 MockConfigurationPolicyStore store; | |
| 332 current = simple_list.begin; | |
| 333 for (unsigned int i = 0; i < n; ++i) { | |
| 334 if (caches[i].initialization_complete()) { | |
| 335 EXPECT_CALL( | |
| 336 store, | |
| 337 Apply(current->policy_type, | |
| 338 IntegerValueMatcher((int)(i*max_counter + | |
| 339 (int)current->policy_type)))) | |
| 340 .Times(n-i); | |
| 341 ++current; | |
| 342 | |
| 343 EXPECT_CALL( | |
| 344 store, | |
| 345 Apply(current->policy_type, | |
| 346 IntegerValueMatcher((int)(i*max_counter + | |
| 347 (int)current->policy_type)))) | |
| 348 .Times(n-i); | |
| 349 ++current; | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 current = simple_list.begin; | |
| 354 for (unsigned int i = 0; i < n; ++i) { | |
| 355 AddCloudPolicyProvider(providers[i].get()); | |
| 356 Provide(&store); | |
| 357 } | |
| 358 | |
| 359 // The final compilation should have exactly two policies per active provider | |
| 360 // set. | |
| 361 current = simple_list.begin; | |
| 362 for (unsigned int i = 0; i < n; ++i, ++current) { | |
| 363 if (caches[i].initialization_complete()) { | |
| 364 EXPECT_THAT( | |
| 365 store.Get(current->policy_type), | |
| 366 IntegerValueMatcher((int)(i*max_counter + | |
| 367 (int)current->policy_type))); | |
| 368 } else { | |
| 369 // For non-initialized providers the corresponding value will be set by | |
| 370 // the next provider, except if it is the last one. | |
| 371 if (i != n-1) { | |
| 372 EXPECT_THAT( | |
| 373 store.Get(current->policy_type), | |
| 374 IntegerValueMatcher((int)((i+1)*max_counter + | |
| 375 (int)current->policy_type))); | |
| 376 } else { | |
| 377 EXPECT_FALSE(store.Get(current->policy_type)); | |
| 378 } | |
| 379 } | |
| 380 } | |
| 381 } | |
| 382 | |
| 383 } // namespace policy | |
| OLD | NEW |