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 "base/file_util.h" | |
6 #include "base/message_loop.h" | |
7 #include "base/scoped_temp_dir.h" | |
8 #include "chrome/browser/browser_thread.h" | |
9 #include "chrome/browser/net/gaia/token_service.h" | |
10 #include "chrome/browser/policy/cloud_policy_cache.h" | |
11 #include "chrome/browser/policy/configuration_policy_pref_store.h" | |
12 #include "chrome/browser/policy/configuration_policy_provider.h" | |
13 #include "chrome/browser/policy/device_management_policy_provider.h" | |
14 #include "chrome/browser/policy/mock_configuration_policy_store.h" | |
15 #include "chrome/browser/policy/mock_device_management_backend.h" | |
16 #include "chrome/common/net/gaia/gaia_constants.h" | |
17 #include "chrome/common/notification_observer_mock.h" | |
18 #include "chrome/common/notification_service.h" | |
19 #include "chrome/test/testing_device_token_fetcher.h" | |
20 #include "chrome/test/testing_profile.h" | |
21 #include "policy/policy_constants.h" | |
22 #include "testing/gmock/include/gmock/gmock.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 | |
25 const char kTestToken[] = "device_policy_provider_test_auth_token"; | |
26 | |
27 namespace policy { | |
28 | |
29 using ::testing::_; | |
30 using ::testing::AtLeast; | |
31 using ::testing::InSequence; | |
32 using ::testing::Mock; | |
33 | |
34 class MockConfigurationPolicyObserver | |
35 : public ConfigurationPolicyProvider::Observer { | |
36 public: | |
37 MOCK_METHOD0(OnUpdatePolicy, void()); | |
38 void OnProviderGoingAway() {} | |
39 }; | |
40 | |
41 class DeviceManagementPolicyProviderTest : public testing::Test { | |
42 public: | |
43 DeviceManagementPolicyProviderTest() | |
44 : ui_thread_(BrowserThread::UI, &loop_), | |
45 file_thread_(BrowserThread::FILE, &loop_) {} | |
46 | |
47 virtual ~DeviceManagementPolicyProviderTest() {} | |
48 | |
49 virtual void SetUp() { | |
50 profile_.reset(new TestingProfile); | |
51 CreateNewProvider(); | |
52 EXPECT_TRUE(waiting_for_initial_policies()); | |
53 loop_.RunAllPending(); | |
54 } | |
55 | |
56 void CreateNewProvider() { | |
57 backend_ = new MockDeviceManagementBackend; | |
58 provider_.reset(new DeviceManagementPolicyProvider( | |
59 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), | |
60 backend_, | |
61 profile_.get())); | |
62 provider_->SetDeviceTokenFetcher( | |
63 new TestingDeviceTokenFetcher(backend_, | |
64 profile_.get(), | |
65 provider_->GetTokenPath())); | |
66 } | |
67 | |
68 void CreateNewProvider(int64 policy_refresh_rate_ms, | |
69 int policy_refresh_fuzz_factor_percent, | |
70 int64 policy_refresh_fuzz_max, | |
71 int64 policy_refresh_error_delay_ms, | |
72 int64 token_fetch_error_delay_ms, | |
73 int64 unmanaged_device_refresh_rate_ms) { | |
74 backend_ = new MockDeviceManagementBackend; | |
75 provider_.reset(new DeviceManagementPolicyProvider( | |
76 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), | |
77 backend_, | |
78 profile_.get(), | |
79 policy_refresh_rate_ms, | |
80 policy_refresh_fuzz_factor_percent, | |
81 policy_refresh_fuzz_max, | |
82 policy_refresh_error_delay_ms, | |
83 token_fetch_error_delay_ms, | |
84 unmanaged_device_refresh_rate_ms)); | |
85 provider_->SetDeviceTokenFetcher( | |
86 new TestingDeviceTokenFetcher(backend_, | |
87 profile_.get(), | |
88 provider_->GetTokenPath())); | |
89 } | |
90 | |
91 FilePath GetTokenPath() const { | |
92 return provider_->GetTokenPath(); | |
93 } | |
94 | |
95 void SimulateSuccessfulLoginAndRunPending() { | |
96 // Make sure the notification for the initial policy fetch is generated. | |
97 MockConfigurationPolicyObserver observer; | |
98 ConfigurationPolicyObserverRegistrar registrar; | |
99 registrar.Init(provider_.get(), &observer); | |
100 EXPECT_CALL(observer, OnUpdatePolicy()).Times(AtLeast(1)); | |
101 | |
102 loop_.RunAllPending(); | |
103 profile_->GetTokenService()->IssueAuthTokenForTest( | |
104 GaiaConstants::kDeviceManagementService, kTestToken); | |
105 TestingDeviceTokenFetcher* fetcher = | |
106 static_cast<TestingDeviceTokenFetcher*>( | |
107 provider_->token_fetcher_.get()); | |
108 fetcher->SimulateLogin(kTestManagedDomainUsername); | |
109 loop_.RunAllPending(); | |
110 } | |
111 | |
112 void SimulateSuccessfulInitialPolicyFetch() { | |
113 MockConfigurationPolicyStore store; | |
114 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
115 MockDeviceManagementBackendSucceedRegister()); | |
116 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
117 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
118 SimulateSuccessfulLoginAndRunPending(); | |
119 EXPECT_FALSE(waiting_for_initial_policies()); | |
120 EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1); | |
121 provider_->Provide(&store); | |
122 ASSERT_EQ(1U, store.policy_map().size()); | |
123 Mock::VerifyAndClearExpectations(backend_); | |
124 Mock::VerifyAndClearExpectations(&store); | |
125 } | |
126 | |
127 virtual void TearDown() { | |
128 provider_.reset(); | |
129 loop_.RunAllPending(); | |
130 } | |
131 | |
132 bool waiting_for_initial_policies() const { | |
133 return !provider_->IsInitializationComplete(); | |
134 } | |
135 | |
136 MockDeviceManagementBackend* backend_; // weak | |
137 scoped_ptr<DeviceManagementPolicyProvider> provider_; | |
138 | |
139 protected: | |
140 CloudPolicyCache* cache(DeviceManagementPolicyProvider* provider) { | |
141 return provider->cache_.get(); | |
142 } | |
143 | |
144 MessageLoop loop_; | |
145 | |
146 private: | |
147 BrowserThread ui_thread_; | |
148 BrowserThread file_thread_; | |
149 scoped_ptr<Profile> profile_; | |
150 | |
151 DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyProviderTest); | |
152 }; | |
153 | |
154 // If there's no login and no previously-fetched policy, the provider should | |
155 // provide an empty policy. | |
156 TEST_F(DeviceManagementPolicyProviderTest, InitialProvideNoLogin) { | |
157 MockConfigurationPolicyStore store; | |
158 EXPECT_CALL(store, Apply(_, _)).Times(0); | |
159 provider_->Provide(&store); | |
160 EXPECT_TRUE(store.policy_map().empty()); | |
161 EXPECT_TRUE(waiting_for_initial_policies()); | |
162 } | |
163 | |
164 // If the login is successful and there's no previously-fetched policy, the | |
165 // policy should be fetched from the server and should be available the first | |
166 // time the Provide method is called. | |
167 TEST_F(DeviceManagementPolicyProviderTest, InitialProvideWithLogin) { | |
168 EXPECT_TRUE(waiting_for_initial_policies()); | |
169 SimulateSuccessfulInitialPolicyFetch(); | |
170 } | |
171 | |
172 // If the login succeed but the device management backend is unreachable, | |
173 // there should be no policy provided if there's no previously-fetched policy, | |
174 TEST_F(DeviceManagementPolicyProviderTest, EmptyProvideWithFailedBackend) { | |
175 MockConfigurationPolicyStore store; | |
176 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
177 MockDeviceManagementBackendFailRegister( | |
178 DeviceManagementBackend::kErrorRequestFailed)); | |
179 EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).Times(0); | |
180 SimulateSuccessfulLoginAndRunPending(); | |
181 EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(0); | |
182 provider_->Provide(&store); | |
183 EXPECT_TRUE(store.policy_map().empty()); | |
184 } | |
185 | |
186 // If a policy has been fetched previously, if should be available even before | |
187 // the login succeeds or the device management backend is available. | |
188 TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) { | |
189 // Pre-fetch and persist a policy | |
190 SimulateSuccessfulInitialPolicyFetch(); | |
191 | |
192 // Simulate a app relaunch by constructing a new provider. Policy should be | |
193 // refreshed (since that might be the purpose of the app relaunch). | |
194 CreateNewProvider(); | |
195 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
196 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
197 loop_.RunAllPending(); | |
198 Mock::VerifyAndClearExpectations(backend_); | |
199 | |
200 // Simulate another app relaunch, this time against a failing backend. | |
201 // Cached policy should still be available. | |
202 MockConfigurationPolicyStore store; | |
203 CreateNewProvider(); | |
204 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
205 MockDeviceManagementBackendFailPolicy( | |
206 DeviceManagementBackend::kErrorRequestFailed)); | |
207 SimulateSuccessfulLoginAndRunPending(); | |
208 EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1); | |
209 provider_->Provide(&store); | |
210 ASSERT_EQ(1U, store.policy_map().size()); | |
211 } | |
212 | |
213 // When policy is successfully fetched from the device management server, it | |
214 // should force a policy refresh. | |
215 TEST_F(DeviceManagementPolicyProviderTest, FetchTriggersRefresh) { | |
216 MockConfigurationPolicyObserver observer; | |
217 ConfigurationPolicyObserverRegistrar registrar; | |
218 registrar.Init(provider_.get(), &observer); | |
219 EXPECT_CALL(observer, OnUpdatePolicy()).Times(1); | |
220 SimulateSuccessfulInitialPolicyFetch(); | |
221 } | |
222 | |
223 TEST_F(DeviceManagementPolicyProviderTest, ErrorCausesNewRequest) { | |
224 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
225 InSequence s; | |
226 CreateNewProvider(1000 * 1000, 0, 0, 0, 0, 0); | |
227 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
228 MockDeviceManagementBackendFailRegister( | |
229 DeviceManagementBackend::kErrorRequestFailed)); | |
230 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
231 MockDeviceManagementBackendSucceedRegister()); | |
232 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
233 MockDeviceManagementBackendFailPolicy( | |
234 DeviceManagementBackend::kErrorRequestFailed)); | |
235 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
236 MockDeviceManagementBackendFailPolicy( | |
237 DeviceManagementBackend::kErrorRequestFailed)); | |
238 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
239 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
240 } | |
241 SimulateSuccessfulLoginAndRunPending(); | |
242 } | |
243 | |
244 TEST_F(DeviceManagementPolicyProviderTest, RefreshPolicies) { | |
245 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
246 InSequence s; | |
247 CreateNewProvider(0, 0, 0, 1000 * 1000, 1000, 0); | |
248 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
249 MockDeviceManagementBackendSucceedRegister()); | |
250 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
251 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
252 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
253 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
254 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
255 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
256 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
257 MockDeviceManagementBackendFailPolicy( | |
258 DeviceManagementBackend::kErrorRequestFailed)); | |
259 } | |
260 SimulateSuccessfulLoginAndRunPending(); | |
261 } | |
262 | |
263 // The client should try to re-register the device if the device server reports | |
264 // back that it doesn't recognize the device token on a policy request. | |
265 TEST_F(DeviceManagementPolicyProviderTest, DeviceNotFound) { | |
266 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
267 InSequence s; | |
268 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
269 MockDeviceManagementBackendSucceedRegister()); | |
270 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
271 MockDeviceManagementBackendFailPolicy( | |
272 DeviceManagementBackend::kErrorServiceDeviceNotFound)); | |
273 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
274 MockDeviceManagementBackendSucceedRegister()); | |
275 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
276 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
277 } | |
278 SimulateSuccessfulLoginAndRunPending(); | |
279 } | |
280 | |
281 // The client should try to re-register the device if the device server reports | |
282 // back that the device token is invalid on a policy request. | |
283 TEST_F(DeviceManagementPolicyProviderTest, InvalidTokenOnPolicyRequest) { | |
284 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
285 InSequence s; | |
286 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
287 MockDeviceManagementBackendSucceedRegister()); | |
288 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
289 MockDeviceManagementBackendFailPolicy( | |
290 DeviceManagementBackend::kErrorServiceManagementTokenInvalid)); | |
291 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
292 MockDeviceManagementBackendSucceedRegister()); | |
293 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
294 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
295 } | |
296 SimulateSuccessfulLoginAndRunPending(); | |
297 } | |
298 | |
299 // If the client is successfully managed, but the admin stops managing the | |
300 // device, the client should notice and throw away the device token and id. | |
301 TEST_F(DeviceManagementPolicyProviderTest, DeviceNoLongerManaged) { | |
302 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
303 InSequence s; | |
304 CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000); | |
305 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
306 MockDeviceManagementBackendSucceedRegister()); | |
307 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
308 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
309 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
310 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
311 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
312 MockDeviceManagementBackendFailPolicy( | |
313 DeviceManagementBackend::kErrorServiceManagementNotSupported)); | |
314 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
315 MockDeviceManagementBackendFailRegister( | |
316 DeviceManagementBackend::kErrorServiceManagementNotSupported)); | |
317 } | |
318 SimulateSuccessfulLoginAndRunPending(); | |
319 FilePath token_path(GetTokenPath()); | |
320 EXPECT_FALSE(file_util::PathExists(token_path)); | |
321 } | |
322 | |
323 // This test tests three things (see numbered comments below): | |
324 TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) { | |
325 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
326 InSequence s; | |
327 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
328 MockDeviceManagementBackendFailRegister( | |
329 DeviceManagementBackend::kErrorServiceManagementNotSupported)); | |
330 } | |
331 SimulateSuccessfulLoginAndRunPending(); | |
332 // (1) The provider's DMPolicyCache should know that the device is not | |
333 // managed. | |
334 EXPECT_TRUE(cache(provider_.get())->is_unmanaged()); | |
335 // (2) On restart, the provider should detect that this is not the first | |
336 // login. | |
337 CreateNewProvider(1000 * 1000, 0, 0, 0, 0, 0); | |
338 EXPECT_FALSE(waiting_for_initial_policies()); | |
339 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
340 InSequence s; | |
341 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
342 MockDeviceManagementBackendSucceedRegister()); | |
343 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
344 MockDeviceManagementBackendSucceedSpdyCloudPolicy()); | |
345 } | |
346 SimulateSuccessfulLoginAndRunPending(); | |
347 // (3) Since the backend call this time returned a device id, the "unmanaged" | |
348 // marker should have been deleted. | |
349 EXPECT_FALSE(cache(provider_.get())->is_unmanaged()); | |
350 } | |
351 | |
352 TEST_F(DeviceManagementPolicyProviderTest, FallbackToOldProtocol) { | |
353 { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence. | |
354 InSequence s; | |
355 CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000); | |
356 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
357 MockDeviceManagementBackendSucceedRegister()); | |
358 // If the CloudPolicyRequest fails with kErrorRequestInvalid... | |
359 EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce( | |
360 MockDeviceManagementBackendFailPolicy( | |
361 DeviceManagementBackend::kErrorRequestInvalid)); | |
362 // ...the client should fall back to a classic PolicyRequest... | |
363 EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( | |
364 MockDeviceManagementBackendSucceedBooleanPolicy( | |
365 key::kDisableSpdy, true)); | |
366 // ...and remember this fallback for any future request, ... | |
367 EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( | |
368 MockDeviceManagementBackendFailPolicy( | |
369 DeviceManagementBackend::kErrorHttpStatus)); | |
370 // ...both after successful fetches and after errors. | |
371 EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce( | |
372 MockDeviceManagementBackendFailPolicy( | |
373 DeviceManagementBackend::kErrorServiceManagementNotSupported)); | |
374 // Finally, we set the client to 'unmanaged' to stop its request stream. | |
375 EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce( | |
376 MockDeviceManagementBackendFailRegister( | |
377 DeviceManagementBackend::kErrorServiceManagementNotSupported)); | |
378 } | |
379 SimulateSuccessfulLoginAndRunPending(); | |
380 } | |
381 | |
382 } // namespace policy | |
OLD | NEW |