| 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 |