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 "base/values.h" | |
8 #include "base/string_util.h" | |
9 #include "chrome/browser/policy/cloud_policy_cache_base.h" | |
10 #include "chrome/browser/policy/cloud_policy_provider.h" | |
11 #include "chrome/browser/policy/configuration_policy_pref_store.h" | |
12 #include "chrome/browser/policy/mock_configuration_policy_store.h" | |
13 #include "testing/gmock/include/gmock/gmock.h" | |
14 | |
15 namespace policy { | |
16 | |
17 namespace { | |
18 | |
19 ConfigurationPolicyType proxy_policies[]= { kPolicyProxyMode, | |
20 kPolicyProxyServerMode, | |
21 kPolicyProxyServer, | |
22 kPolicyProxyPacUrl, | |
23 kPolicyProxyBypassList }; | |
24 | |
25 bool is_proxy_policy(ConfigurationPolicyType policy) { | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
This is duplicated code. Can we somehow share?
sfeuz
2011/06/13 06:53:53
Made it private static of CloudPolicyProvider.
wdy
| |
26 const unsigned int n = arraysize(proxy_policies); | |
27 for (unsigned int i = 0; i < n; ++i) | |
28 if (proxy_policies[i] == policy) | |
29 return true; | |
30 return false; | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 class MockCloudPolicyCacheBase : public CloudPolicyCacheBase { | |
36 public: | |
37 MockCloudPolicyCacheBase() {} | |
38 virtual ~MockCloudPolicyCacheBase() {} | |
39 | |
40 // CloudPolicyCacheBase Implementation. | |
41 void Load(){} | |
42 void SetPolicy(const em::PolicyFetchResponse& policy) {} | |
43 bool DecodePolicyData(const em::PolicyData& policy_data, | |
44 PolicyMap* mandatory, | |
45 PolicyMap* recommended) { | |
46 return true; | |
47 } | |
48 | |
49 // Non-const accessors for underlying PolicyMaps. | |
50 PolicyMap* raw_mandatory_policy() { | |
51 return &mandatory_policy_; | |
52 } | |
53 | |
54 PolicyMap* raw_recommended_policy() { | |
55 return &recommended_policy_; | |
56 } | |
57 | |
58 void SetUnmanaged() { | |
59 is_unmanaged_ = true; | |
60 } | |
61 | |
62 void set_initialized() { | |
63 initialization_complete_ = true; | |
64 } | |
65 | |
66 void set_uninitialized() { | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
why not merge these two into set_initialized(bool)
sfeuz
2011/06/13 06:53:53
Done.
| |
67 initialization_complete_ = false; | |
68 } | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
DISALLOW_COPY_AND_ASSIGN
sfeuz
2011/06/13 06:53:53
Done.
| |
69 }; | |
70 | |
71 class CloudPolicyProviderTest : public testing::Test { | |
72 public: | |
73 void CreateCloudPolicyProvider( | |
74 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, | |
75 CloudPolicyCacheBase::PolicyLevel level) { | |
76 cloud_policy_provider_.reset(new CloudPolicyProvider(policy_list, level)); | |
77 } | |
78 | |
79 void CreateCloudPolicyProvider( | |
80 CloudPolicyCacheBase::PolicyLevel level) { | |
81 CreateCloudPolicyProvider( | |
82 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), | |
83 level); | |
84 } | |
85 | |
86 void Provide(ConfigurationPolicyStoreInterface* store) { | |
87 DCHECK(cloud_policy_provider_.get()); | |
88 cloud_policy_provider_->Provide(store); | |
89 } | |
90 | |
91 void AppendCache(CloudPolicyCacheBase* cache) { | |
92 DCHECK(cloud_policy_provider_.get()); | |
93 cloud_policy_provider_->AppendCache(cache); | |
94 } | |
95 | |
96 void PrependCache(CloudPolicyCacheBase* cache) { | |
97 DCHECK(cloud_policy_provider_.get()); | |
98 cloud_policy_provider_->PrependCache(cache); | |
99 } | |
100 | |
101 void CombineTwoPolicyMaps(const PolicyMap& base, | |
102 const PolicyMap& overlay, | |
103 PolicyMap* out_map) { | |
104 DCHECK(cloud_policy_provider_.get()); | |
105 cloud_policy_provider_->CombineTwoPolicyMaps(base, overlay, out_map); | |
106 } | |
107 | |
108 private: | |
109 scoped_ptr<CloudPolicyProvider> cloud_policy_provider_; | |
110 }; | |
111 | |
112 // Proxy setting distributed over multiple caches. | |
113 TEST_F(CloudPolicyProviderTest, | |
114 ProxySettingDistributedOverMultipleCaches) { | |
115 const unsigned int proxy_related_policies = arraysize(proxy_policies); | |
116 | |
117 // There are |proxy_related_policies|+1 caches and they are mixed together by | |
118 // one instance of CloudPolicyProvider. The first cache has some policies but | |
119 // no proxy-related ones. The following caches have each one proxy-policy set. | |
120 const unsigned int n = proxy_related_policies + 1; | |
121 | |
122 // Make sure that our assumptions about the existing proxy-related policies | |
123 // are still correct. | |
124 DCHECK(proxy_related_policies == 5); | |
125 | |
126 MockCloudPolicyCacheBase caches[n]; | |
127 | |
128 const ConfigurationPolicyProvider::PolicyDefinitionList* list = | |
129 policy::ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(); | |
130 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; | |
131 | |
132 // Prepare |cache[0]| to serve some non-proxy policies. | |
133 caches[0].set_initialized(); | |
134 caches[0].raw_mandatory_policy()->Set(kPolicyShowHomeButton, | |
135 Value::CreateBooleanValue(true)); | |
136 caches[0].raw_mandatory_policy()->Set(kPolicyIncognitoEnabled, | |
137 Value::CreateBooleanValue(true)); | |
138 caches[0].raw_mandatory_policy()->Set(kPolicyTranslateEnabled, | |
139 Value::CreateBooleanValue(true)); | |
140 | |
141 // Prepare the other caches to serve one proxy-policy each. | |
142 caches[1].set_initialized(); | |
143 caches[1].raw_mandatory_policy()->Set(kPolicyProxyMode, | |
144 Value::CreateStringValue("cache 1")); | |
145 caches[2].set_initialized(); | |
146 caches[2].raw_mandatory_policy()->Set(kPolicyProxyServerMode, | |
147 Value::CreateIntegerValue(2)); | |
148 caches[3].set_initialized(); | |
149 caches[3].raw_mandatory_policy()->Set(kPolicyProxyServer, | |
150 Value::CreateStringValue("cache 3")); | |
151 caches[4].set_initialized(); | |
152 caches[4].raw_mandatory_policy()->Set(kPolicyProxyPacUrl, | |
153 Value::CreateStringValue("cache 4")); | |
154 caches[5].set_initialized(); | |
155 caches[5].raw_mandatory_policy()->Set(kPolicyProxyMode, | |
156 Value::CreateStringValue("cache 5")); | |
157 | |
158 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY); | |
159 | |
160 // Prepend from the end. | |
161 for (unsigned int i = 0; i < n; ++i) | |
162 PrependCache(&caches[n-i-1]); | |
163 | |
164 MockConfigurationPolicyStore store; | |
165 EXPECT_CALL(store, Apply(testing::_,testing::_)).Times(testing::AnyNumber()); | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace after comma
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
It is common practice to import the symbols in tes
sfeuz
2011/06/13 06:53:53
Done.
sfeuz
2011/06/13 06:53:53
Done.
| |
166 Provide(&store); | |
167 | |
168 // The final compilation should have some policies set to true. From the proxy | |
169 // related policies only |kPolicyProxyMode| should be set. | |
170 for (current = list->begin; current != list->end; ++current) { | |
171 const Value* value = store.Get(current->policy_type); | |
172 if (current->policy_type == kPolicyProxyMode) { | |
173 EXPECT_TRUE(value); | |
174 std::string string_value; | |
175 bool result = value->GetAsString(&string_value); | |
176 EXPECT_TRUE(result); | |
177 EXPECT_EQ(string_value, "cache 1"); | |
178 } else if (is_proxy_policy(current->policy_type)) { | |
179 EXPECT_FALSE(value); | |
180 } else if (current->policy_type == kPolicyShowHomeButton || | |
181 current->policy_type == kPolicyIncognitoEnabled || | |
182 current->policy_type == kPolicyTranslateEnabled) { | |
183 EXPECT_TRUE(value); | |
184 bool boolean_value = false; | |
185 bool result = value->GetAsBoolean(&boolean_value); | |
186 DCHECK(result); | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
Why DCHECK instead of EXPECT_TRUE()?
sfeuz
2011/06/13 06:53:53
Done.
| |
187 EXPECT_TRUE(boolean_value); | |
188 } else { | |
189 EXPECT_FALSE(value); | |
190 } | |
191 } | |
192 } | |
193 | |
194 // Having many different caches adding them to the end incrementally. | |
195 TEST_F(CloudPolicyProviderTest, MultipleCaches) { | |
196 // |n| denotes the number of caches, which are mixed together by one | |
197 // instance of CloudPolicyProvider. Every other cache is set to be | |
198 // initialized (starting with a non-initialized one). The i-th cache will | |
199 // serve i policies and be at position i in the list of CloudPolicyProvider. | |
200 // Thus in the end there should be exactly two policies/ applied per | |
201 // initialized cache. | |
202 const unsigned int n = 101; | |
203 const ConfigurationPolicyProvider::PolicyDefinitionList::Entry* current; | |
204 | |
205 // Numbers bigger than 1000 will mess with the key names. | |
206 DCHECK(n - arraysize(proxy_policies) < 1000); | |
207 | |
208 // Prepare the PolicyDefinitionList |simple_list| with entries of the form | |
209 // {(ConfigurationPolicyType)(7), Value::TYPE_INTEGER, "007"}. | |
210 ConfigurationPolicyProvider::PolicyDefinitionList::Entry entries[n]; | |
211 | |
212 // The size of the keys depends on their format. Currently they are of the | |
213 // form "007" needing 4 characters including the terminal \0. | |
214 char keys[n][4]; | |
215 unsigned int counter = 0; | |
216 for (unsigned int i = 0; i < n; ++counter) { | |
217 | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
no newline here.
sfeuz
2011/06/13 06:53:53
Done.
| |
218 // We do not want to interfere with the proxy related policies since they | |
219 // are treated as a special case inside CloudPolicyProvider. | |
220 if (is_proxy_policy((ConfigurationPolicyType)counter)) | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
casting integers to enum members seems like a bad
sfeuz
2011/06/13 06:53:53
Done.
| |
221 continue; | |
222 | |
223 base::snprintf(keys[i], 4, "%03u", counter); | |
224 entries[i].policy_type = (ConfigurationPolicyType)counter; | |
225 entries[i].value_type = Value::TYPE_INTEGER; | |
226 entries[i].name = (const char*)keys[i]; | |
227 ++i; | |
228 } | |
229 const int max_counter = counter; | |
230 ConfigurationPolicyProvider::PolicyDefinitionList simple_list = | |
231 {entries, | |
232 entries+n}; | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace around +, after { and before }
sfeuz
2011/06/13 06:53:53
Done.
| |
233 | |
234 // Prepare |cache[i]| to serve the first i policies form |simple_list|. | |
235 MockCloudPolicyCacheBase caches[n]; | |
236 for (unsigned int i = 0; i < n; ++i) { | |
237 current = simple_list.begin; | |
238 for (unsigned int j = 0; j <= i; ++j, ++current) { | |
239 // Set a unique value. | |
240 caches[i].raw_recommended_policy()->Set( | |
241 current->policy_type, | |
242 Value::CreateIntegerValue(i*max_counter + | |
243 (int)current->policy_type)); | |
244 caches[i].raw_mandatory_policy()->Set( | |
245 current->policy_type, | |
246 Value::CreateIntegerValue(i*max_counter + | |
247 (int)current->policy_type)); | |
248 if (i&1) | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace around &
sfeuz
2011/06/13 06:53:53
Done.
| |
249 caches[i].set_initialized(); | |
250 else | |
251 caches[i].set_uninitialized(); | |
252 } | |
253 } | |
254 | |
255 // Executed twice. Once for recommended and once for mandatory policy level. | |
256 for (int l = 0; l < 2; ++l) { | |
257 CloudPolicyCacheBase::PolicyLevel level = l ? | |
258 CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED: | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespcae before :
sfeuz
2011/06/13 06:53:53
Done.
| |
259 CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY; | |
260 CreateCloudPolicyProvider(&simple_list,level); | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace after comma
sfeuz
2011/06/13 06:53:53
Done.
| |
261 MockConfigurationPolicyStore store; | |
262 current = simple_list.begin; | |
263 for (unsigned int i = 0; i < n; ++i) | |
264 AppendCache(&caches[i]); | |
265 | |
266 EXPECT_CALL(store, Apply(testing::_,testing::_)).Times( | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
see my comment on importing symbols from testing::
sfeuz
2011/06/13 06:53:53
Done.
| |
267 testing::AnyNumber()); | |
268 Provide(&store); | |
269 | |
270 // The final compilation should have exactly two policies per active cache | |
271 // set. | |
272 current = simple_list.begin; | |
273 for (unsigned int i = 0; i < n; ++i, ++current) { | |
274 // Initialized caches will have their corresponding policy set. | |
275 if (caches[i].initialization_complete()) { | |
276 const Value* value = store.Get(current->policy_type); | |
277 EXPECT_TRUE(value); | |
278 int expected = i*max_counter + (int)current->policy_type; | |
279 int integer_value; | |
280 bool result = value->GetAsInteger(&integer_value); | |
281 EXPECT_TRUE(result); | |
282 EXPECT_EQ(integer_value, expected); | |
283 } else { | |
284 | |
285 // For non-initialized providers the corresponding value will be set by | |
286 // the next provider, except if it is the last one. | |
287 if (i == n-1) { | |
288 EXPECT_FALSE(store.Get(current->policy_type)); | |
289 break; | |
290 } | |
291 | |
292 const Value* value = store.Get(current->policy_type); | |
293 EXPECT_TRUE(value); | |
294 int expected = (i+1)*max_counter + (int)current->policy_type; | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace around + and * and after cast
sfeuz
2011/06/13 06:53:53
Done.
| |
295 int integer_value; | |
296 bool result = value->GetAsInteger(&integer_value); | |
297 EXPECT_TRUE(result); | |
298 EXPECT_EQ(integer_value, expected); | |
299 } | |
300 } | |
301 } | |
302 } | |
303 | |
304 // Combining two PolicyMaps. | |
305 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsSame) { | |
306 const int n = 1000; | |
307 PolicyMap A, B, C; | |
308 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED); | |
309 | |
310 for (int i=0; i < n; ++i) | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace around =
sfeuz
2011/06/13 06:53:53
Done.
| |
311 if (!is_proxy_policy((ConfigurationPolicyType)i)) | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace after cast (also below)
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
Again, can we just use a static PolicyDefinitionMa
sfeuz
2011/06/13 06:53:53
Done.
sfeuz
2011/06/13 06:53:53
Done.
| |
312 A.Set((ConfigurationPolicyType)i,Value::CreateIntegerValue(i)); | |
313 | |
314 for (int i=0; i < n; ++i) | |
315 if (!is_proxy_policy((ConfigurationPolicyType)i)) | |
316 B.Set((ConfigurationPolicyType)i,Value::CreateIntegerValue(-1*i)); | |
317 | |
318 CombineTwoPolicyMaps(A,B,&C); | |
Mattias Nissler (ping if slow)
2011/06/09 14:36:26
whitespace after , (I'll stop commenting on missin
sfeuz
2011/06/13 06:53:53
Done.
| |
319 EXPECT_TRUE(A.Equals(C)); | |
320 } | |
321 | |
322 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsEmpty) { | |
323 PolicyMap A, B, C; | |
324 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED); | |
325 CombineTwoPolicyMaps(A,B,&C); | |
326 EXPECT_TRUE(C.empty()); | |
327 } | |
328 | |
329 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsPartial) { | |
330 const int n = 1000; | |
331 PolicyMap A, B, C; | |
332 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED); | |
333 | |
334 for (int i=0; i < n; ++i) { | |
335 if (is_proxy_policy((ConfigurationPolicyType)(2*i)) || | |
336 is_proxy_policy((ConfigurationPolicyType)(2*i+1))) { | |
337 continue; | |
338 } | |
339 A.Set((ConfigurationPolicyType)(2*i),Value::CreateIntegerValue(2*i)); | |
340 B.Set((ConfigurationPolicyType)(2*i),Value::CreateIntegerValue(-2*i)); | |
341 B.Set((ConfigurationPolicyType)(2*i+1),Value::CreateIntegerValue(-2*i-1)); | |
342 } | |
343 | |
344 CombineTwoPolicyMaps(A,B,&C); | |
345 | |
346 for (int i=0; i < 2*n; ++i) { | |
347 if (const Value* value = C.Get((ConfigurationPolicyType)i)) { | |
348 int int_value; | |
349 EXPECT_TRUE(value->GetAsInteger(&int_value)); | |
350 if (i&1) | |
351 EXPECT_EQ(int_value, -1*i); | |
352 else | |
353 EXPECT_EQ(int_value, i); | |
354 } | |
355 } | |
356 } | |
357 | |
358 TEST_F(CloudPolicyProviderTest, CombineTwoPolicyMapsProxies) { | |
359 const int n = arraysize(proxy_policies); | |
360 const int a_value = 1; | |
361 const int b_value = -1; | |
362 PolicyMap A, B, C; | |
363 CreateCloudPolicyProvider(CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED); | |
364 | |
365 A.Set(proxy_policies[0], Value::CreateIntegerValue(a_value)); | |
366 for (int i=1; i < n; ++i) | |
367 B.Set(proxy_policies[i], Value::CreateIntegerValue(b_value)); | |
368 | |
369 CombineTwoPolicyMaps(A,B,&C); | |
370 | |
371 EXPECT_TRUE(A.Equals(C)); | |
372 EXPECT_FALSE(B.Equals(C)); | |
373 } | |
374 | |
375 } // namespace policy | |
OLD | NEW |