OLD | NEW |
| (Empty) |
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/policy_service_impl.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/bind_helpers.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/message_loop.h" | |
11 #include "base/values.h" | |
12 #include "chrome/browser/policy/mock_configuration_policy_provider.h" | |
13 #include "content/public/browser/browser_thread.h" | |
14 #include "content/test/test_browser_thread.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using ::testing::AnyNumber; | |
19 using ::testing::Mock; | |
20 using ::testing::Return; | |
21 using ::testing::_; | |
22 | |
23 namespace policy { | |
24 | |
25 namespace { | |
26 | |
27 class MockPolicyServiceObserver : public PolicyService::Observer { | |
28 public: | |
29 virtual ~MockPolicyServiceObserver() {} | |
30 MOCK_METHOD4(OnPolicyUpdated, void(PolicyDomain, | |
31 const std::string&, | |
32 const PolicyMap& previous, | |
33 const PolicyMap& current)); | |
34 }; | |
35 | |
36 // Helper to compare the arguments to an EXPECT_CALL of OnPolicyUpdated() with | |
37 // their expected values. | |
38 MATCHER_P(PolicyEquals, expected, "") { | |
39 return arg.Equals(*expected); | |
40 } | |
41 | |
42 // Helper to compare the arguments to an EXPECT_CALL of OnPolicyValueUpdated() | |
43 // with their expected values. | |
44 MATCHER_P(ValueEquals, expected, "") { | |
45 return base::Value::Equals(arg, expected); | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 class PolicyServiceTest : public testing::Test { | |
51 public: | |
52 PolicyServiceTest() {} | |
53 | |
54 void SetUp() OVERRIDE { | |
55 EXPECT_CALL(provider0_, ProvideInternal(_)) | |
56 .WillRepeatedly(CopyPolicyMap(&policy0_)); | |
57 EXPECT_CALL(provider1_, ProvideInternal(_)) | |
58 .WillRepeatedly(CopyPolicyMap(&policy1_)); | |
59 EXPECT_CALL(provider2_, ProvideInternal(_)) | |
60 .WillRepeatedly(CopyPolicyMap(&policy2_)); | |
61 | |
62 EXPECT_CALL(provider0_, IsInitializationComplete()) | |
63 .WillRepeatedly(Return(true)); | |
64 EXPECT_CALL(provider1_, IsInitializationComplete()) | |
65 .WillRepeatedly(Return(true)); | |
66 EXPECT_CALL(provider2_, IsInitializationComplete()) | |
67 .WillRepeatedly(Return(true)); | |
68 | |
69 policy0_.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
70 base::Value::CreateIntegerValue(13)); | |
71 | |
72 PolicyServiceImpl::Providers providers; | |
73 providers.push_back(&provider0_); | |
74 providers.push_back(&provider1_); | |
75 providers.push_back(&provider2_); | |
76 policy_service_.reset(new PolicyServiceImpl(providers)); | |
77 } | |
78 | |
79 MOCK_METHOD2(OnPolicyValueUpdated, void(const base::Value*, | |
80 const base::Value*)); | |
81 | |
82 MOCK_METHOD0(OnPolicyRefresh, void()); | |
83 | |
84 // Returns true if the policies for |domain|, |component_id| match |expected|. | |
85 bool VerifyPolicies(PolicyDomain domain, | |
86 const std::string& component_id, | |
87 const PolicyMap& expected) { | |
88 const PolicyMap* policies = | |
89 policy_service_->GetPolicies(domain, component_id); | |
90 return policies && policies->Equals(expected); | |
91 } | |
92 | |
93 protected: | |
94 MockConfigurationPolicyProvider provider0_; | |
95 MockConfigurationPolicyProvider provider1_; | |
96 MockConfigurationPolicyProvider provider2_; | |
97 PolicyMap policy0_; | |
98 PolicyMap policy1_; | |
99 PolicyMap policy2_; | |
100 scoped_ptr<PolicyServiceImpl> policy_service_; | |
101 | |
102 private: | |
103 DISALLOW_COPY_AND_ASSIGN(PolicyServiceTest); | |
104 }; | |
105 | |
106 TEST_F(PolicyServiceTest, LoadsPoliciesBeforeProvidersRefresh) { | |
107 PolicyMap expected; | |
108 expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
109 base::Value::CreateIntegerValue(13)); | |
110 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected)); | |
111 } | |
112 | |
113 TEST_F(PolicyServiceTest, NotifyObservers) { | |
114 MockPolicyServiceObserver observer; | |
115 policy_service_->AddObserver(POLICY_DOMAIN_CHROME, "", &observer); | |
116 | |
117 PolicyMap expectedPrevious; | |
118 expectedPrevious.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
119 base::Value::CreateIntegerValue(13)); | |
120 | |
121 PolicyMap expectedCurrent; | |
122 expectedCurrent.CopyFrom(expectedPrevious); | |
123 expectedCurrent.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
124 base::Value::CreateIntegerValue(123)); | |
125 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
126 base::Value::CreateIntegerValue(123)); | |
127 EXPECT_CALL(observer, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "", | |
128 PolicyEquals(&expectedPrevious), | |
129 PolicyEquals(&expectedCurrent))); | |
130 provider0_.NotifyPolicyUpdated(); | |
131 Mock::VerifyAndClearExpectations(&observer); | |
132 | |
133 // No changes. | |
134 EXPECT_CALL(observer, OnPolicyUpdated(_, _, _, _)).Times(0); | |
135 provider0_.NotifyPolicyUpdated(); | |
136 Mock::VerifyAndClearExpectations(&observer); | |
137 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expectedCurrent)); | |
138 | |
139 // New policy. | |
140 expectedPrevious.CopyFrom(expectedCurrent); | |
141 expectedCurrent.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
142 base::Value::CreateIntegerValue(456)); | |
143 policy0_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
144 base::Value::CreateIntegerValue(456)); | |
145 EXPECT_CALL(observer, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "", | |
146 PolicyEquals(&expectedPrevious), | |
147 PolicyEquals(&expectedCurrent))); | |
148 provider0_.NotifyPolicyUpdated(); | |
149 Mock::VerifyAndClearExpectations(&observer); | |
150 | |
151 // Removed policy. | |
152 expectedPrevious.CopyFrom(expectedCurrent); | |
153 expectedCurrent.Erase("bbb"); | |
154 policy0_.Erase("bbb"); | |
155 EXPECT_CALL(observer, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "", | |
156 PolicyEquals(&expectedPrevious), | |
157 PolicyEquals(&expectedCurrent))); | |
158 provider0_.NotifyPolicyUpdated(); | |
159 Mock::VerifyAndClearExpectations(&observer); | |
160 | |
161 // Changed policy. | |
162 expectedPrevious.CopyFrom(expectedCurrent); | |
163 expectedCurrent.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
164 base::Value::CreateIntegerValue(789)); | |
165 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
166 base::Value::CreateIntegerValue(789)); | |
167 | |
168 EXPECT_CALL(observer, OnPolicyUpdated(POLICY_DOMAIN_CHROME, "", | |
169 PolicyEquals(&expectedPrevious), | |
170 PolicyEquals(&expectedCurrent))); | |
171 provider0_.NotifyPolicyUpdated(); | |
172 Mock::VerifyAndClearExpectations(&observer); | |
173 | |
174 // No changes again. | |
175 EXPECT_CALL(observer, OnPolicyUpdated(_, _, _, _)).Times(0); | |
176 provider0_.NotifyPolicyUpdated(); | |
177 Mock::VerifyAndClearExpectations(&observer); | |
178 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expectedCurrent)); | |
179 | |
180 policy_service_->RemoveObserver(POLICY_DOMAIN_CHROME, "", &observer); | |
181 } | |
182 | |
183 TEST_F(PolicyServiceTest, Priorities) { | |
184 PolicyMap expected; | |
185 expected.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
186 base::Value::CreateIntegerValue(13)); | |
187 expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
188 base::Value::CreateIntegerValue(0)); | |
189 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
190 base::Value::CreateIntegerValue(0)); | |
191 policy1_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
192 base::Value::CreateIntegerValue(1)); | |
193 policy2_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
194 base::Value::CreateIntegerValue(2)); | |
195 provider0_.NotifyPolicyUpdated(); | |
196 provider1_.NotifyPolicyUpdated(); | |
197 provider2_.NotifyPolicyUpdated(); | |
198 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected)); | |
199 | |
200 expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
201 base::Value::CreateIntegerValue(1)); | |
202 policy0_.Erase("aaa"); | |
203 provider0_.NotifyPolicyUpdated(); | |
204 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected)); | |
205 | |
206 expected.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
207 base::Value::CreateIntegerValue(2)); | |
208 policy1_.Set("aaa", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, | |
209 base::Value::CreateIntegerValue(1)); | |
210 provider1_.NotifyPolicyUpdated(); | |
211 EXPECT_TRUE(VerifyPolicies(POLICY_DOMAIN_CHROME, "", expected)); | |
212 } | |
213 | |
214 TEST_F(PolicyServiceTest, PolicyChangeRegistrar) { | |
215 scoped_ptr<PolicyChangeRegistrar> registrar( | |
216 new PolicyChangeRegistrar( | |
217 policy_service_.get(), POLICY_DOMAIN_CHROME, "")); | |
218 | |
219 // Starting to observe existing policies doesn't trigger a notification. | |
220 EXPECT_CALL(*this, OnPolicyValueUpdated(_, _)).Times(0); | |
221 registrar->Observe("pre", base::Bind( | |
222 &PolicyServiceTest::OnPolicyValueUpdated, | |
223 base::Unretained(this))); | |
224 registrar->Observe("aaa", base::Bind( | |
225 &PolicyServiceTest::OnPolicyValueUpdated, | |
226 base::Unretained(this))); | |
227 Mock::VerifyAndClearExpectations(this); | |
228 | |
229 // Changing it now triggers a notification. | |
230 base::FundamentalValue kValue0(0); | |
231 EXPECT_CALL(*this, OnPolicyValueUpdated(NULL, ValueEquals(&kValue0))); | |
232 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
233 kValue0.DeepCopy()); | |
234 provider0_.NotifyPolicyUpdated(); | |
235 Mock::VerifyAndClearExpectations(this); | |
236 | |
237 // Changing other values doesn't trigger a notification. | |
238 EXPECT_CALL(*this, OnPolicyValueUpdated(_, _)).Times(0); | |
239 policy0_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
240 kValue0.DeepCopy()); | |
241 provider0_.NotifyPolicyUpdated(); | |
242 Mock::VerifyAndClearExpectations(this); | |
243 | |
244 // Modifying the value triggers a notification. | |
245 base::FundamentalValue kValue1(1); | |
246 EXPECT_CALL(*this, OnPolicyValueUpdated(ValueEquals(&kValue0), | |
247 ValueEquals(&kValue1))); | |
248 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
249 kValue1.DeepCopy()); | |
250 provider0_.NotifyPolicyUpdated(); | |
251 Mock::VerifyAndClearExpectations(this); | |
252 | |
253 // Removing the value triggers a notification. | |
254 EXPECT_CALL(*this, OnPolicyValueUpdated(ValueEquals(&kValue1), NULL)); | |
255 policy0_.Erase("aaa"); | |
256 provider0_.NotifyPolicyUpdated(); | |
257 Mock::VerifyAndClearExpectations(this); | |
258 | |
259 // No more notifications after destroying the registrar. | |
260 EXPECT_CALL(*this, OnPolicyValueUpdated(_, _)).Times(0); | |
261 registrar.reset(); | |
262 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
263 kValue1.DeepCopy()); | |
264 policy0_.Set("pre", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
265 kValue1.DeepCopy()); | |
266 provider0_.NotifyPolicyUpdated(); | |
267 Mock::VerifyAndClearExpectations(this); | |
268 } | |
269 | |
270 TEST_F(PolicyServiceTest, RefreshPolicies) { | |
271 MessageLoop loop; | |
272 content::TestBrowserThread ui_thread(content::BrowserThread::UI, &loop); | |
273 content::TestBrowserThread file_thread(content::BrowserThread::FILE, &loop); | |
274 content::TestBrowserThread io_thread(content::BrowserThread::IO, &loop); | |
275 | |
276 EXPECT_CALL(provider0_, RefreshPolicies()).Times(AnyNumber()); | |
277 EXPECT_CALL(provider1_, RefreshPolicies()).Times(AnyNumber()); | |
278 EXPECT_CALL(provider2_, RefreshPolicies()).Times(AnyNumber()); | |
279 | |
280 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
281 policy_service_->RefreshPolicies(base::Bind( | |
282 &PolicyServiceTest::OnPolicyRefresh, | |
283 base::Unretained(this))); | |
284 loop.RunAllPending(); | |
285 Mock::VerifyAndClearExpectations(this); | |
286 | |
287 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
288 base::FundamentalValue kValue0(0); | |
289 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
290 kValue0.DeepCopy()); | |
291 provider0_.NotifyPolicyUpdated(); | |
292 loop.RunAllPending(); | |
293 Mock::VerifyAndClearExpectations(this); | |
294 | |
295 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
296 base::FundamentalValue kValue1(1); | |
297 policy1_.Set("aaa", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, | |
298 kValue1.DeepCopy()); | |
299 provider1_.NotifyPolicyUpdated(); | |
300 loop.RunAllPending(); | |
301 Mock::VerifyAndClearExpectations(this); | |
302 | |
303 // A provider can refresh more than once after a RefreshPolicies call, but | |
304 // OnPolicyRefresh should be triggered only after all providers are | |
305 // refreshed. | |
306 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
307 policy1_.Set("bbb", POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, | |
308 kValue1.DeepCopy()); | |
309 provider1_.NotifyPolicyUpdated(); | |
310 loop.RunAllPending(); | |
311 Mock::VerifyAndClearExpectations(this); | |
312 | |
313 // If another RefreshPolicies() call happens while waiting for a previous | |
314 // one to complete, then all providers must refresh again. | |
315 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
316 policy_service_->RefreshPolicies(base::Bind( | |
317 &PolicyServiceTest::OnPolicyRefresh, | |
318 base::Unretained(this))); | |
319 loop.RunAllPending(); | |
320 Mock::VerifyAndClearExpectations(this); | |
321 | |
322 EXPECT_CALL(*this, OnPolicyRefresh()).Times(0); | |
323 policy2_.Set("bbb", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
324 kValue0.DeepCopy()); | |
325 provider2_.NotifyPolicyUpdated(); | |
326 loop.RunAllPending(); | |
327 Mock::VerifyAndClearExpectations(this); | |
328 | |
329 // Providers 0 and 1 must reload again. | |
330 EXPECT_CALL(*this, OnPolicyRefresh()).Times(2); | |
331 base::FundamentalValue kValue2(2); | |
332 policy0_.Set("aaa", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, | |
333 kValue2.DeepCopy()); | |
334 provider0_.NotifyPolicyUpdated(); | |
335 provider1_.NotifyPolicyUpdated(); | |
336 loop.RunAllPending(); | |
337 Mock::VerifyAndClearExpectations(this); | |
338 | |
339 const PolicyMap* policies = policy_service_->GetPolicies( | |
340 POLICY_DOMAIN_CHROME, ""); | |
341 ASSERT_TRUE(policies); | |
342 EXPECT_TRUE(base::Value::Equals(&kValue2, policies->GetValue("aaa"))); | |
343 EXPECT_TRUE(base::Value::Equals(&kValue0, policies->GetValue("bbb"))); | |
344 } | |
345 | |
346 } // namespace policy | |
OLD | NEW |