Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: chrome/browser/policy/cloud_policy_provider_unittest.cc

Issue 7147015: Move user cloud policy to BrowserProcess (was 6979011) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cut a circular startup dependency Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "base/values.h"
8 #include "chrome/browser/policy/cloud_policy_cache_base.h"
9 #include "chrome/browser/policy/cloud_policy_provider_impl.h"
10 #include "chrome/browser/policy/configuration_policy_pref_store.h"
11 #include "chrome/browser/policy/mock_configuration_policy_store.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13
14 using testing::AnyNumber;
15 using testing::_;
16
17 namespace policy {
18
19 class MockCloudPolicyCache : public CloudPolicyCacheBase {
20 public:
21 MockCloudPolicyCache() {}
22 virtual ~MockCloudPolicyCache() {}
23
24 // CloudPolicyCacheBase Implementation.
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 lower-case: implementation
gfeher 2011/06/22 19:18:34 Done.
25 void Load() {}
26 void SetPolicy(const em::PolicyFetchResponse& policy) {}
27 bool DecodePolicyData(const em::PolicyData& policy_data,
28 PolicyMap* mandatory,
29 PolicyMap* recommended) {
30 return true;
31 }
32
33 // Non-const accessors for underlying PolicyMaps.
34 PolicyMap* raw_mandatory_policy() {
35 return &mandatory_policy_;
36 }
37
38 PolicyMap* raw_recommended_policy() {
39 return &recommended_policy_;
40 }
41
42 void SetUnmanaged() {
43 is_unmanaged_ = true;
44 }
45
46 void set_initialized(bool initialized) {
47 initialization_complete_ = initialized;
48 }
49
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 private:
gfeher 2011/06/22 19:18:34 Done.
50 DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyCache);
51 };
52
53 class CloudPolicyProviderTest : public testing::Test {
54 protected:
55 void CreateCloudPolicyProvider(
56 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list,
57 CloudPolicyCacheBase::PolicyLevel level) {
58 cloud_policy_provider_.reset(
59 new CloudPolicyProviderImpl(policy_list, level));
60 }
61
62 void CreateCloudPolicyProvider(
63 CloudPolicyCacheBase::PolicyLevel level) {
64 CreateCloudPolicyProvider(
65 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
66 level);
67 }
68
69 void Provide(ConfigurationPolicyStoreInterface* store) {
70 DCHECK(cloud_policy_provider_.get());
71 cloud_policy_provider_->Provide(store);
72 }
73
74 void AppendCache(CloudPolicyCacheBase* cache) {
75 DCHECK(cloud_policy_provider_.get());
76 cloud_policy_provider_->AppendCache(cache);
77 }
78
79 void PrependCache(CloudPolicyCacheBase* cache) {
80 DCHECK(cloud_policy_provider_.get());
81 cloud_policy_provider_->PrependCache(cache);
82 }
83
84 void CombineTwoPolicyMaps(const PolicyMap& base,
85 const PolicyMap& overlay,
86 PolicyMap* out_map) {
87 DCHECK(cloud_policy_provider_.get());
88 cloud_policy_provider_->CombineTwoPolicyMaps(base, overlay, out_map);
89 }
90
91 ConfigurationPolicyProvider::PolicyDefinitionList* simple_list() {
92 return simple_list_.get();
93 }
94
95 ConfigurationPolicyType simple_list_policy_type(int id) {
96 DCHECK(id < simple_list_length_);
97 return simple_list_->begin[id].policy_type;
98 }
99
100 int simple_list_length() {
101 return simple_list_length_;
102 }
103
104 int proxy_policy_count() {
105 return CloudPolicyProviderImpl::proxy_policy_count();
106 }
107
108 bool is_proxy_policy(ConfigurationPolicyType policy) {
109 return CloudPolicyProviderImpl::is_proxy_policy(policy);
110 }
111
112 ConfigurationPolicyType get_proxy_policy(int i) {
113 DCHECK(i < proxy_policy_count());
114 return CloudPolicyProviderImpl::proxy_policies[i];
115 }
116
117 virtual void SetUp() {
118 // Extract all non-proxy policies from the default chrome policy definition
119 // list but set all the types to integer. The names of policies are not
120 // modified, and they are not used later in these tests.
121 const ConfigurationPolicyProvider::PolicyDefinitionList* real_list =
122 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
123 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current;
124
125 // Count the number of non-proxy policies.
126 simple_list_length_ = 0;
127 for (current = real_list->begin; current != real_list->end; ++current) {
128 if (!CloudPolicyProviderImpl::is_proxy_policy(current->policy_type)) {
129 ++simple_list_length_;
130 }
131 }
132
133 int counter = 0;
134 simple_list_.reset(new ConfigurationPolicyProvider::PolicyDefinitionList);
135 entries_.reset(
136 new ConfigurationPolicyProvider::PolicyDefinitionList::Entry[
137 simple_list_length_]);
138 for (current = real_list->begin; current != real_list->end; ++current) {
139 if (CloudPolicyProviderImpl::is_proxy_policy(current->policy_type))
140 continue;
141
142 entries_[counter].policy_type = current->policy_type;
143 entries_[counter].value_type = Value::TYPE_INTEGER;
144 entries_[counter].name = current->name;
145
146 ++counter;
147 }
148
149 simple_list_->begin = entries_.get();
150 simple_list_->end = entries_.get() + simple_list_length_;
151 }
152
153 virtual void TearDown() {
154 simple_list_.reset();
155 entries_.reset();
156 }
157
158 // Verify the test scenario of MultipleCaches
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 period.
gfeher 2011/06/22 19:18:34 Done.
159 void VerifyMultipleCaches(MockCloudPolicyCache caches[],
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 I don't like this verification code. It's hard to
gfeher 2011/06/22 19:18:34 Done.
160 CloudPolicyCacheBase::PolicyLevel level) {
161 CreateCloudPolicyProvider(simple_list(), level);
162 MockConfigurationPolicyStore store;
163 for (int i = 0; i < simple_list_length(); ++i)
164 AppendCache(&caches[i]);
165
166 EXPECT_CALL(store, Apply(_, _)).Times(AnyNumber());
167 Provide(&store);
168
169 const int n = simple_list_length();
170 // The final compilation should have exactly two policies per active cache
171 // set.
172 for (int i = 0; i < n; ++i) {
173 const Value* value = store.Get(simple_list_policy_type(i));
174 if (i == n - 1 && !caches[i].initialization_complete()) {
175 // If the last provider is not initialized, then the last policy
176 // is not provided by anyone.
177 EXPECT_EQ(NULL, value);
178 break;
179 }
180 ASSERT_TRUE(value != NULL);
181 int policy_value;
182 EXPECT_TRUE(value->GetAsInteger(&policy_value));
183 int originating_cache = policy_value / n;
184 int policy_id = policy_value % n;
185 EXPECT_EQ(i, policy_id) << "Policy identifier mismatch";
186 if (caches[i].initialization_complete()) {
187 // Initialized caches will have their corresponding policy set.
188 EXPECT_EQ(i, originating_cache) << "Providing cache mismatch.";
189 } else {
190 // For non-initialized providers the corresponding value will be set by
191 // the next provider. (The last provider is handled elsewhere.)
192 EXPECT_EQ(i + 1, originating_cache) << "Providing cache mismatch.";
193 }
194 }
195 }
196
197 private:
198 scoped_ptr<CloudPolicyProviderImpl> cloud_policy_provider_;
199
200 // A list of policies to be used in tests: it has some simplifications to
201 // make testing more easy: it doesn't have proxy policies and all the
202 // policies have the type of integer.
203 scoped_ptr<ConfigurationPolicyProvider::PolicyDefinitionList> simple_list_;
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 Why is this so complicated? Can't we just declare
gfeher 2011/06/22 19:18:34 We can go even deeper...
204 int simple_list_length_;
205
206 // The following members own the internal parts of simple_list_, therefore
207 // they may only be freed after simple_list_ is freed.
208 scoped_array<ConfigurationPolicyProvider::PolicyDefinitionList::Entry>
209 entries_;
210 };
211
212 // Proxy setting distributed over multiple caches.
213 TEST_F(CloudPolicyProviderTest,
214 ProxySettingDistributedOverMultipleCaches) {
215 const int proxy_related_policies = proxy_policy_count();
216
217 // There are |proxy_related_policies|+1 caches and they are mixed together by
218 // one instance of CloudPolicyProvider. The first cache has some policies but
219 // no proxy-related ones. The following caches have each one proxy-policy set.
220 const int n = proxy_related_policies + 1;
221
222 // Make sure that our assumptions about the existing proxy-related policies
223 // are still correct.
224 DCHECK(proxy_related_policies == 5);
225
226 scoped_array<MockCloudPolicyCache> caches(new MockCloudPolicyCache[n]);
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 Just put 5 instead of n and delete all the cruft a
gfeher 2011/06/22 19:18:34 Done.
227
228 const ConfigurationPolicyProvider::PolicyDefinitionList* list =
229 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList();
230 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current;
231
232 // Prepare |cache[0]| to serve some non-proxy policies.
233 caches[0].set_initialized(true);
234 caches[0].raw_mandatory_policy()->Set(kPolicyShowHomeButton,
235 Value::CreateBooleanValue(true));
236 caches[0].raw_mandatory_policy()->Set(kPolicyIncognitoEnabled,
237 Value::CreateBooleanValue(true));
238 caches[0].raw_mandatory_policy()->Set(kPolicyTranslateEnabled,
239 Value::CreateBooleanValue(true));
240
241 // Prepare the other caches to serve one proxy-policy each.
242 caches[1].set_initialized(true);
243 caches[1].raw_mandatory_policy()->Set(kPolicyProxyMode,
244 Value::CreateStringValue("cache 1"));
245 caches[2].set_initialized(true);
246 caches[2].raw_mandatory_policy()->Set(kPolicyProxyServerMode,
247 Value::CreateIntegerValue(2));
248 caches[3].set_initialized(true);
249 caches[3].raw_mandatory_policy()->Set(kPolicyProxyServer,
250 Value::CreateStringValue("cache 3"));
251 caches[4].set_initialized(true);
252 caches[4].raw_mandatory_policy()->Set(kPolicyProxyPacUrl,
253 Value::CreateStringValue("cache 4"));
254 caches[5].set_initialized(true);
255 caches[5].raw_mandatory_policy()->Set(kPolicyProxyMode,
256 Value::CreateStringValue("cache 5"));
257
258 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY);
259
260 // Prepend from the end.
261 for (int i = 0; i < n; ++i)
262 PrependCache(&caches[n-i-1]);
263
264 MockConfigurationPolicyStore store;
265 EXPECT_CALL(store, Apply(_, _)).Times(AnyNumber());
266 Provide(&store);
267
268 // The final compilation should have some policies set to true. From the proxy
269 // related policies only |kPolicyProxyMode| should be set.
270 for (current = list->begin; current != list->end; ++current) {
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 let's just write down what exact expectation we ha
gfeher 2011/06/22 19:18:34 Done.
271 const Value* value = store.Get(current->policy_type);
272 if (current->policy_type == kPolicyProxyMode) {
273 EXPECT_TRUE(value);
274 std::string string_value;
275 bool result = value->GetAsString(&string_value);
276 EXPECT_TRUE(result);
277 EXPECT_EQ(string_value, "cache 1");
278 } else if (is_proxy_policy(current->policy_type)) {
279 EXPECT_FALSE(value);
280 } else if (current->policy_type == kPolicyShowHomeButton ||
281 current->policy_type == kPolicyIncognitoEnabled ||
282 current->policy_type == kPolicyTranslateEnabled) {
283 EXPECT_TRUE(value);
284 bool boolean_value = false;
285 EXPECT_TRUE(value->GetAsBoolean(&boolean_value));
286 EXPECT_TRUE(boolean_value);
287 } else {
288 EXPECT_FALSE(value);
289 }
290 }
291 }
292
293 // Having many different caches adding them to the end incrementally.
294 TEST_F(CloudPolicyProviderTest, MultipleCaches) {
295 const int n = simple_list_length();
296 // We set up as many caches as non-proxy policies (n). We configure them
297 // according to the following pattern:
298 // The i-th cache will serve i policies and be at position i in the list
299 // of CloudPolicyProvider.
300 // The i-th cache will be set to initialized iff i % 2 == 1
301 // Thus in the end there should be exactly two policies applied per
302 // initialized cache.
303 // The j-th policy of the i-th cache will be set to i * n + j, thus
304 // given a policy value of x, x / n gives us the cache that provided it and
305 // x % n should give its own identifier.
306 // Prepare |cache[i]| to serve the first i policies from |list|.
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 Again, I find this too complicated. Why not just c
gfeher 2011/06/22 19:18:34 Done.
307 scoped_array<MockCloudPolicyCache> caches(new MockCloudPolicyCache[n]);
308 for (int cache_id = 0; cache_id < n; ++cache_id) {
309 for (int policy_id = 0; policy_id <= cache_id; ++policy_id) {
310 // Set a unique value.
311 caches[cache_id].raw_recommended_policy()->Set(
312 simple_list_policy_type(policy_id),
313 Value::CreateIntegerValue(cache_id * n + policy_id));
314 caches[cache_id].raw_mandatory_policy()->Set(
315 simple_list_policy_type(policy_id),
316 Value::CreateIntegerValue(cache_id * n + policy_id));
317
318 // Odd numbered caches are initialized and evens are not.
319 caches[cache_id].set_initialized(cache_id % 2);
320 }
321 }
322
323 // Verify that the provider provides policies according to the expected
324 // pattern.
325 VerifyMultipleCaches(caches.get(),
326 CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED);
327 VerifyMultipleCaches(caches.get(),
328 CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY);
329 }
330
331 // Combining two PolicyMaps.
332 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsSame) {
333 PolicyMap A, B, C;
334 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED);
335 for (int i = 0; i < simple_list_length(); ++i) {
336 A.Set(simple_list_policy_type(i), Value::CreateIntegerValue(i));
337 B.Set(simple_list_policy_type(i), Value::CreateIntegerValue(-1 * i));
338 }
339 CombineTwoPolicyMaps(A, B, &C);
340 EXPECT_TRUE(A.Equals(C));
341 }
342
343 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsEmpty) {
344 PolicyMap A, B, C;
345 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED);
346 CombineTwoPolicyMaps(A, B, &C);
347 EXPECT_TRUE(C.empty());
348 }
349
350 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsPartial) {
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 What additional coverage does this test give over
gfeher 2011/06/22 19:18:34 If this doesn't fail but MultipleCaches does, then
351 PolicyMap A, B, C;
352 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED);
353
354 for (int i = 0; i < simple_list_length(); ++i) {
355 B.Set(simple_list_policy_type(i), Value::CreateIntegerValue(-i));
356 if (i % 2 == 0)
357 A.Set(simple_list_policy_type(i), Value::CreateIntegerValue(i));
358 }
359
360 CombineTwoPolicyMaps(A, B, &C);
361
362 for (int i = 0; i < simple_list_length(); ++i) {
363 if (const Value* value = C.Get(simple_list_policy_type(i))) {
364 int int_value;
365 EXPECT_TRUE(value->GetAsInteger(&int_value));
366 if (i % 2 == 1) {
367 EXPECT_EQ(int_value, -1 * i);
368 } else {
369 EXPECT_EQ(int_value, i);
370 }
371 }
372 }
373 }
374
375 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsProxies) {
376 const int n = proxy_policy_count();
377 const int a_value = 1;
378 const int b_value = -1;
379 PolicyMap A, B, C;
380 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED);
381
382 A.Set(get_proxy_policy(0), Value::CreateIntegerValue(a_value));
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 Why not just use a static constant here?
gfeher 2011/06/22 19:18:34 Done.
383 for (int i = 1; i < n; ++i)
384 B.Set(get_proxy_policy(i), Value::CreateIntegerValue(b_value));
Mattias Nissler (ping if slow) 2011/06/21 20:09:56 and here, and unroll the loop?
gfeher 2011/06/22 19:18:34 Done.
385
386 CombineTwoPolicyMaps(A, B, &C);
387
388 EXPECT_TRUE(A.Equals(C));
389 EXPECT_FALSE(B.Equals(C));
390 }
391
392 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698