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 "base/callback.h" | |
6 #include "base/compiler_specific.h" | |
7 #include "base/memory/ref_counted.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/test/test_simple_task_runner.h" | |
11 #include "chrome/browser/policy/cloud/cloud_policy_constants.h" | |
12 #include "chrome/browser/policy/cloud/cloud_policy_refresh_scheduler.h" | |
13 #include "chrome/browser/policy/cloud/mock_cloud_policy_client.h" | |
14 #include "chrome/browser/policy/cloud/mock_cloud_policy_store.h" | |
15 #include "policy/policy_constants.h" | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace em = enterprise_management; | |
20 | |
21 using testing::Mock; | |
22 | |
23 namespace policy { | |
24 | |
25 namespace { | |
26 | |
27 const int64 kPolicyRefreshRate = 4 * 60 * 60 * 1000; | |
28 | |
29 const int64 kInitialCacheAgeMinutes = 1; | |
30 | |
31 } // namespace | |
32 | |
33 class CloudPolicyRefreshSchedulerTest : public testing::Test { | |
34 protected: | |
35 CloudPolicyRefreshSchedulerTest() | |
36 : task_runner_(new base::TestSimpleTaskRunner()), | |
37 network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {} | |
38 | |
39 virtual void SetUp() OVERRIDE { | |
40 client_.SetDMToken("token"); | |
41 | |
42 // Set up the protobuf timestamp to be one minute in the past. Since the | |
43 // protobuf field only has millisecond precision, we convert the actual | |
44 // value back to get a millisecond-clamped time stamp for the checks below. | |
45 store_.policy_.reset(new em::PolicyData()); | |
46 base::Time now = base::Time::NowFromSystemTime(); | |
47 base::TimeDelta initial_age = | |
48 base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes); | |
49 store_.policy_->set_timestamp( | |
50 ((now - initial_age) - base::Time::UnixEpoch()).InMilliseconds()); | |
51 last_update_ = | |
52 base::Time::UnixEpoch() + | |
53 base::TimeDelta::FromMilliseconds(store_.policy_->timestamp()); | |
54 } | |
55 | |
56 CloudPolicyRefreshScheduler* CreateRefreshScheduler() { | |
57 EXPECT_EQ(0u, task_runner_->GetPendingTasks().size()); | |
58 CloudPolicyRefreshScheduler* scheduler = | |
59 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_); | |
60 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
61 // If the store has policy, run the wait-for-invalidations timeout task. | |
62 if (store_.has_policy()) { | |
63 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
64 task_runner_->RunPendingTasks(); | |
65 } | |
66 return scheduler; | |
67 } | |
68 | |
69 void NotifyIPAddressChanged() { | |
70 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
71 loop_.RunUntilIdle(); | |
72 } | |
73 | |
74 base::TimeDelta GetLastDelay() const { | |
75 const std::deque<base::TestPendingTask>& pending_tasks = | |
76 task_runner_->GetPendingTasks(); | |
77 return | |
78 pending_tasks.empty() ? base::TimeDelta() : pending_tasks.back().delay; | |
79 } | |
80 | |
81 void CheckTiming(int64 expected_delay_ms) const { | |
82 CheckTimingWithAge(base::TimeDelta::FromMilliseconds(expected_delay_ms), | |
83 base::TimeDelta()); | |
84 } | |
85 | |
86 // Checks that the latest refresh scheduled used an offset of | |
87 // |offset_from_last_refresh| from the time of the previous refresh. | |
88 // |cache_age| is how old the cache was when the refresh was issued. | |
89 void CheckTimingWithAge(const base::TimeDelta& offset_from_last_refresh, | |
90 const base::TimeDelta& cache_age) const { | |
91 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
92 base::Time now(base::Time::NowFromSystemTime()); | |
93 // |last_update_| was updated and then a refresh was scheduled at time S, | |
94 // so |last_update_| is a bit before that. | |
95 // Now is a bit later, N. | |
96 // GetLastDelay() + S is the time when the refresh will run, T. | |
97 // |cache_age| is the age of the cache at time S. It was thus created at | |
98 // S - cache_age. | |
99 // | |
100 // Schematically: | |
101 // | |
102 // . S . N . . . . . . . T . . . . | |
103 // | | | | |
104 // set "last_refresh_" and then scheduled the next refresh; the cache | |
105 // was "cache_age" old at this point. | |
106 // | | | |
107 // some time elapsed on the test execution since then; | |
108 // this is the current time, "now" | |
109 // | | |
110 // the refresh will execute at this time | |
111 // | |
112 // So the exact delay is T - S - |cache_age|, but we don't have S here. | |
113 // | |
114 // |last_update_| was a bit before S, so if | |
115 // elapsed = now - |last_update_| then the delay is more than | |
116 // |offset_from_last_refresh| - elapsed. | |
117 // | |
118 // The delay is also less than offset_from_last_refresh, because some time | |
119 // already elapsed. Additionally, if the cache was already considered old | |
120 // when the schedule was performed then its age at that time has been | |
121 // discounted from the delay. So the delay is a bit less than | |
122 // |offset_from_last_refresh - cache_age|. | |
123 EXPECT_GE(GetLastDelay(), offset_from_last_refresh - (now - last_update_)); | |
124 EXPECT_LE(GetLastDelay(), offset_from_last_refresh - cache_age); | |
125 } | |
126 | |
127 void CheckInitialRefresh(bool with_invalidations) const { | |
128 #if defined(OS_ANDROID) | |
129 // Android takes the cache age into account for the initial fetch. | |
130 // Usually the cache age is ignored for the initial refresh, but Android | |
131 // uses it to restrain from refreshing on every startup. | |
132 base::TimeDelta rate = base::TimeDelta::FromMilliseconds( | |
133 with_invalidations | |
134 ? CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs | |
135 : kPolicyRefreshRate); | |
136 CheckTimingWithAge(rate, | |
137 base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes)); | |
138 #else | |
139 // Other platforms refresh immediately. | |
140 EXPECT_EQ(base::TimeDelta(), GetLastDelay()); | |
141 #endif | |
142 } | |
143 | |
144 base::MessageLoop loop_; | |
145 MockCloudPolicyClient client_; | |
146 MockCloudPolicyStore store_; | |
147 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | |
148 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; | |
149 | |
150 // Base time for the refresh that the scheduler should be using. | |
151 base::Time last_update_; | |
152 }; | |
153 | |
154 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshNoPolicy) { | |
155 store_.policy_.reset(); | |
156 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
157 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
158 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
159 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
160 task_runner_->RunUntilIdle(); | |
161 } | |
162 | |
163 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshUnmanaged) { | |
164 store_.policy_->set_state(em::PolicyData::UNMANAGED); | |
165 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
166 CheckTiming(CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs); | |
167 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
168 task_runner_->RunUntilIdle(); | |
169 } | |
170 | |
171 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedNotYetFetched) { | |
172 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
173 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
174 CheckInitialRefresh(false); | |
175 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
176 task_runner_->RunUntilIdle(); | |
177 } | |
178 | |
179 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedAlreadyFetched) { | |
180 last_update_ = base::Time::NowFromSystemTime(); | |
181 client_.SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, | |
182 std::string()), | |
183 em::PolicyFetchResponse()); | |
184 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
185 CheckTiming(kPolicyRefreshRate); | |
186 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
187 task_runner_->RunUntilIdle(); | |
188 } | |
189 | |
190 TEST_F(CloudPolicyRefreshSchedulerTest, Unregistered) { | |
191 client_.SetDMToken(std::string()); | |
192 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
193 client_.NotifyPolicyFetched(); | |
194 client_.NotifyRegistrationStateChanged(); | |
195 client_.NotifyClientError(); | |
196 scheduler->SetRefreshDelay(12 * 60 * 60 * 1000); | |
197 store_.NotifyStoreLoaded(); | |
198 store_.NotifyStoreError(); | |
199 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
200 } | |
201 | |
202 TEST_F(CloudPolicyRefreshSchedulerTest, RefreshSoonRateLimit) { | |
203 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
204 // Max out the request rate. | |
205 for (int i = 0; i < 5; ++i) { | |
206 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
207 scheduler->RefreshSoon(); | |
208 task_runner_->RunUntilIdle(); | |
209 Mock::VerifyAndClearExpectations(&client_); | |
210 } | |
211 // The next refresh is throttled. | |
212 EXPECT_CALL(client_, FetchPolicy()).Times(0); | |
213 scheduler->RefreshSoon(); | |
214 task_runner_->RunPendingTasks(); | |
215 Mock::VerifyAndClearExpectations(&client_); | |
216 } | |
217 | |
218 TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsAvailable) { | |
219 scoped_ptr<CloudPolicyRefreshScheduler> scheduler( | |
220 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); | |
221 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
222 | |
223 // The scheduler is currently waiting for the invalidations service to | |
224 // initialize. | |
225 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
226 | |
227 // Signal that invalidations are available. The scheduler is currently | |
228 // waiting for any pending invalidations to be received. | |
229 scheduler->SetInvalidationServiceAvailability(true); | |
230 EXPECT_EQ(2u, task_runner_->GetPendingTasks().size()); | |
231 | |
232 // Run the invalidation service timeout task. | |
233 EXPECT_CALL(client_, FetchPolicy()).Times(0); | |
234 task_runner_->RunPendingTasks(); | |
235 Mock::VerifyAndClearExpectations(&client_); | |
236 | |
237 // The initial refresh is scheduled. | |
238 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
239 CheckInitialRefresh(true); | |
240 | |
241 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
242 task_runner_->RunPendingTasks(); | |
243 Mock::VerifyAndClearExpectations(&client_); | |
244 | |
245 // Complete that fetch. | |
246 last_update_ = base::Time::NowFromSystemTime(); | |
247 client_.NotifyPolicyFetched(); | |
248 | |
249 // The next refresh has been scheduled using a lower refresh rate. | |
250 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
251 CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); | |
252 } | |
253 | |
254 TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsNotAvailable) { | |
255 scoped_ptr<CloudPolicyRefreshScheduler> scheduler( | |
256 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); | |
257 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
258 | |
259 // The scheduler is currently waiting for the invalidations service to | |
260 // initialize. | |
261 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
262 | |
263 // Signal that invalidations are not available. The scheduler will keep | |
264 // waiting for us. | |
265 for (int i = 0; i < 10; ++i) { | |
266 scheduler->SetInvalidationServiceAvailability(false); | |
267 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
268 } | |
269 | |
270 // Run the timeout task. | |
271 EXPECT_CALL(client_, FetchPolicy()).Times(0); | |
272 task_runner_->RunPendingTasks(); | |
273 Mock::VerifyAndClearExpectations(&client_); | |
274 | |
275 // This scheduled the initial refresh. | |
276 CheckInitialRefresh(false); | |
277 | |
278 // Perform that fetch now. | |
279 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
280 task_runner_->RunPendingTasks(); | |
281 Mock::VerifyAndClearExpectations(&client_); | |
282 | |
283 // Complete that fetch. | |
284 last_update_ = base::Time::NowFromSystemTime(); | |
285 client_.NotifyPolicyFetched(); | |
286 | |
287 // The next refresh has been scheduled at the normal rate. | |
288 EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); | |
289 CheckTiming(kPolicyRefreshRate); | |
290 } | |
291 | |
292 TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsOffAndOn) { | |
293 scoped_ptr<CloudPolicyRefreshScheduler> scheduler( | |
294 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); | |
295 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
296 scheduler->SetInvalidationServiceAvailability(true); | |
297 // Initial fetch. | |
298 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
299 task_runner_->RunUntilIdle(); | |
300 Mock::VerifyAndClearExpectations(&client_); | |
301 last_update_ = base::Time::NowFromSystemTime(); | |
302 client_.NotifyPolicyFetched(); | |
303 | |
304 // The next refresh has been scheduled using a lower refresh rate. | |
305 // Flush that task. | |
306 CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); | |
307 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
308 task_runner_->RunPendingTasks(); | |
309 Mock::VerifyAndClearExpectations(&client_); | |
310 | |
311 // If the service goes down and comes back up before the timeout then a | |
312 // refresh is rescheduled at the lower rate again; after executing all | |
313 // pending tasks only 1 fetch is performed. | |
314 EXPECT_CALL(client_, FetchPolicy()).Times(0); | |
315 scheduler->SetInvalidationServiceAvailability(false); | |
316 scheduler->SetInvalidationServiceAvailability(true); | |
317 // Run the invalidation service timeout task. | |
318 task_runner_->RunPendingTasks(); | |
319 Mock::VerifyAndClearExpectations(&client_); | |
320 // The next refresh has been scheduled using a lower refresh rate. | |
321 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
322 CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); | |
323 task_runner_->RunPendingTasks(); | |
324 Mock::VerifyAndClearExpectations(&client_); | |
325 } | |
326 | |
327 TEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsDisconnected) { | |
328 scoped_ptr<CloudPolicyRefreshScheduler> scheduler( | |
329 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); | |
330 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
331 scheduler->SetInvalidationServiceAvailability(true); | |
332 // Initial fetch. | |
333 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
334 task_runner_->RunUntilIdle(); | |
335 Mock::VerifyAndClearExpectations(&client_); | |
336 last_update_ = base::Time::NowFromSystemTime(); | |
337 client_.NotifyPolicyFetched(); | |
338 | |
339 // The next refresh has been scheduled using a lower refresh rate. | |
340 // Flush that task. | |
341 CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); | |
342 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
343 task_runner_->RunPendingTasks(); | |
344 Mock::VerifyAndClearExpectations(&client_); | |
345 | |
346 // If the service goes down then the refresh scheduler falls back on the | |
347 // default polling rate after a timeout. | |
348 EXPECT_CALL(client_, FetchPolicy()).Times(0); | |
349 scheduler->SetInvalidationServiceAvailability(false); | |
350 task_runner_->RunPendingTasks(); | |
351 Mock::VerifyAndClearExpectations(&client_); | |
352 // The next refresh has been scheduled at the normal rate. | |
353 CheckTiming(kPolicyRefreshRate); | |
354 } | |
355 | |
356 class CloudPolicyRefreshSchedulerSteadyStateTest | |
357 : public CloudPolicyRefreshSchedulerTest { | |
358 protected: | |
359 CloudPolicyRefreshSchedulerSteadyStateTest() {} | |
360 | |
361 virtual void SetUp() OVERRIDE { | |
362 refresh_scheduler_.reset(CreateRefreshScheduler()); | |
363 refresh_scheduler_->SetRefreshDelay(kPolicyRefreshRate); | |
364 CloudPolicyRefreshSchedulerTest::SetUp(); | |
365 last_update_ = base::Time::NowFromSystemTime(); | |
366 client_.NotifyPolicyFetched(); | |
367 CheckTiming(kPolicyRefreshRate); | |
368 } | |
369 | |
370 scoped_ptr<CloudPolicyRefreshScheduler> refresh_scheduler_; | |
371 }; | |
372 | |
373 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnPolicyFetched) { | |
374 client_.NotifyPolicyFetched(); | |
375 CheckTiming(kPolicyRefreshRate); | |
376 } | |
377 | |
378 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnRegistrationStateChanged) { | |
379 client_.SetDMToken("new_token"); | |
380 client_.NotifyRegistrationStateChanged(); | |
381 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
382 | |
383 task_runner_->ClearPendingTasks(); | |
384 client_.SetDMToken(std::string()); | |
385 client_.NotifyRegistrationStateChanged(); | |
386 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
387 } | |
388 | |
389 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreLoaded) { | |
390 store_.NotifyStoreLoaded(); | |
391 CheckTiming(kPolicyRefreshRate); | |
392 } | |
393 | |
394 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreError) { | |
395 task_runner_->ClearPendingTasks(); | |
396 store_.NotifyStoreError(); | |
397 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
398 } | |
399 | |
400 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, RefreshDelayChange) { | |
401 const int delay_short_ms = 5 * 60 * 1000; | |
402 refresh_scheduler_->SetRefreshDelay(delay_short_ms); | |
403 CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMinMs); | |
404 | |
405 const int delay_ms = 12 * 60 * 60 * 1000; | |
406 refresh_scheduler_->SetRefreshDelay(delay_ms); | |
407 CheckTiming(delay_ms); | |
408 | |
409 const int delay_long_ms = 20 * 24 * 60 * 60 * 1000; | |
410 refresh_scheduler_->SetRefreshDelay(delay_long_ms); | |
411 CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMaxMs); | |
412 } | |
413 | |
414 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnIPAddressChanged) { | |
415 NotifyIPAddressChanged(); | |
416 CheckTiming(kPolicyRefreshRate); | |
417 | |
418 client_.SetStatus(DM_STATUS_REQUEST_FAILED); | |
419 NotifyIPAddressChanged(); | |
420 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
421 } | |
422 | |
423 struct ClientErrorTestParam { | |
424 DeviceManagementStatus client_error; | |
425 int64 expected_delay_ms; | |
426 int backoff_factor; | |
427 }; | |
428 | |
429 static const ClientErrorTestParam kClientErrorTestCases[] = { | |
430 { DM_STATUS_REQUEST_INVALID, | |
431 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
432 { DM_STATUS_REQUEST_FAILED, | |
433 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, | |
434 { DM_STATUS_TEMPORARY_UNAVAILABLE, | |
435 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, | |
436 { DM_STATUS_HTTP_STATUS_ERROR, | |
437 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
438 { DM_STATUS_RESPONSE_DECODING_ERROR, | |
439 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
440 { DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED, | |
441 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
442 { DM_STATUS_SERVICE_DEVICE_NOT_FOUND, | |
443 -1, 1 }, | |
444 { DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID, | |
445 -1, 1 }, | |
446 { DM_STATUS_SERVICE_ACTIVATION_PENDING, | |
447 kPolicyRefreshRate, 1 }, | |
448 { DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER, | |
449 -1, 1 }, | |
450 { DM_STATUS_SERVICE_MISSING_LICENSES, | |
451 -1, 1 }, | |
452 { DM_STATUS_SERVICE_DEVICE_ID_CONFLICT, | |
453 -1, 1 }, | |
454 { DM_STATUS_SERVICE_POLICY_NOT_FOUND, | |
455 kPolicyRefreshRate, 1 }, | |
456 }; | |
457 | |
458 class CloudPolicyRefreshSchedulerClientErrorTest | |
459 : public CloudPolicyRefreshSchedulerSteadyStateTest, | |
460 public testing::WithParamInterface<ClientErrorTestParam> { | |
461 }; | |
462 | |
463 TEST_P(CloudPolicyRefreshSchedulerClientErrorTest, OnClientError) { | |
464 client_.SetStatus(GetParam().client_error); | |
465 task_runner_->ClearPendingTasks(); | |
466 | |
467 // See whether the error triggers the right refresh delay. | |
468 int64 expected_delay_ms = GetParam().expected_delay_ms; | |
469 client_.NotifyClientError(); | |
470 if (expected_delay_ms >= 0) { | |
471 CheckTiming(expected_delay_ms); | |
472 | |
473 // Check whether exponential backoff is working as expected and capped at | |
474 // the regular refresh rate (if applicable). | |
475 do { | |
476 expected_delay_ms *= GetParam().backoff_factor; | |
477 last_update_ = base::Time::NowFromSystemTime(); | |
478 client_.NotifyClientError(); | |
479 CheckTiming(std::max(std::min(expected_delay_ms, kPolicyRefreshRate), | |
480 GetParam().expected_delay_ms)); | |
481 } while (GetParam().backoff_factor > 1 && | |
482 expected_delay_ms <= kPolicyRefreshRate); | |
483 } else { | |
484 EXPECT_EQ(base::TimeDelta(), GetLastDelay()); | |
485 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
486 } | |
487 } | |
488 | |
489 INSTANTIATE_TEST_CASE_P(CloudPolicyRefreshSchedulerClientErrorTest, | |
490 CloudPolicyRefreshSchedulerClientErrorTest, | |
491 testing::ValuesIn(kClientErrorTestCases)); | |
492 | |
493 } // namespace policy | |
OLD | NEW |