15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/test/test_simple_task_runner.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kPolicyRefreshRate = 4 * 60 * 60 * 1000; 27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst int64 kInitialCacheAgeMinutes = 1; 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPolicyRefreshSchedulerTest : public testing::Test { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshSchedulerTest() 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : task_runner_(new base::TestSimpleTaskRunner()), 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetDMToken("token"); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the protobuf timestamp to be one minute in the past. Since the 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // protobuf field only has millisecond precision, we convert the actual 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value back to get a millisecond-clamped time stamp for the checks below. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.policy_.reset(new em::PolicyData()); 45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Time now = base::Time::NowFromSystemTime(); 46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::TimeDelta initial_age = 47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.policy_->set_timestamp( 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ((now - initial_age) - base::Time::UnixEpoch()).InMilliseconds()); 50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::UnixEpoch() + 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(store_.policy_->timestamp()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler* CreateRefreshScheduler() { 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(0u, task_runner_->GetPendingTasks().size()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyRefreshScheduler* scheduler = 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler->SetRefreshDelay(kPolicyRefreshRate); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scheduler; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyIPAddressChanged() { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loop_.RunUntilIdle(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta GetLastDelay() const { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::deque<base::TestPendingTask>& pending_tasks = 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->GetPendingTasks(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_tasks.empty() ? base::TimeDelta() : pending_tasks.back().delay; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CheckTiming(int64 expected_delay_ms) const { 76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTimingWithAge(base::TimeDelta::FromMilliseconds(expected_delay_ms), 77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::TimeDelta()); 78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Checks that the latest refresh scheduled used an offset of 81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |offset_from_last_refresh| from the time of the previous refresh. 82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |cache_age| is how old the cache was when the refresh was issued. 83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch void CheckTimingWithAge(const base::TimeDelta& offset_from_last_refresh, 84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const base::TimeDelta& cache_age) const { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time now(base::Time::NowFromSystemTime()); 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |last_update_| was updated and then a refresh was scheduled at time S, 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // so |last_update_| is a bit before that. 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Now is a bit later, N. 90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // GetLastDelay() + S is the time when the refresh will run, T. 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |cache_age| is the age of the cache at time S. It was thus created at 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // S - cache_age. 93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Schematically: 95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // . S . N . . . . . . . T . . . . 97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // | | | 98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // set "last_refresh_" and then scheduled the next refresh; the cache 99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // was "cache_age" old at this point. 100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // | | 101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // some time elapsed on the test execution since then; 102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // this is the current time, "now" 103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // | 104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // the refresh will execute at this time 105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // So the exact delay is T - S - |cache_age|, but we don't have S here. 107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |last_update_| was a bit before S, so if 109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // elapsed = now - |last_update_| then the delay is more than 110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |offset_from_last_refresh| - elapsed. 111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // 112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The delay is also less than offset_from_last_refresh, because some time 113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // already elapsed. Additionally, if the cache was already considered old 114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // when the schedule was performed then its age at that time has been 115558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // discounted from the delay. So the delay is a bit less than 116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // |offset_from_last_refresh - cache_age|. 117558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_GE(GetLastDelay(), offset_from_last_refresh - (now - last_update_)); 118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_LE(GetLastDelay(), offset_from_last_refresh - cache_age); 119558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 121558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch void CheckInitialRefresh(bool with_invalidations) const { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_IOS) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The mobile platforms take the cache age into account for the initial 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fetch. Usually the cache age is ignored for the initial refresh, but on 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // mobile it's used to restrain from refreshing on every startup. 126558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::TimeDelta rate = base::TimeDelta::FromMilliseconds( 127558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch with_invalidations 128558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ? CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs 129558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch : kPolicyRefreshRate); 130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTimingWithAge(rate, 131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::TimeDelta::FromMinutes(kInitialCacheAgeMinutes)); 132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#else 133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Other platforms refresh immediately. 134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(base::TimeDelta(), GetLastDelay()); 135558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop loop_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockCloudPolicyClient client_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockCloudPolicyStore store_; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Base time for the refresh that the scheduler should be using. 145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Time last_update_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshNoPolicy) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.policy_.reset(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(GetLastDelay(), base::TimeDelta()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(client_, FetchPolicy()).Times(1); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->RunUntilIdle(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshUnmanaged) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.policy_->set_state(em::PolicyData::UNMANAGED); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(client_, FetchPolicy()).Times(1); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->RunUntilIdle(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedNotYetFetched) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); 168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckInitialRefresh(false); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(client_, FetchPolicy()).Times(1); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->RunUntilIdle(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedAlreadyFetched) { 174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_.SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string()), 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) em::PolicyFetchResponse()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(kPolicyRefreshRate); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(client_, FetchPolicy()).Times(1); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->RunUntilIdle(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerTest, Unregistered) { 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.SetDMToken(std::string()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyPolicyFetched(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyRegistrationStateChanged(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyClientError(); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler->SetRefreshDelay(12 * 60 * 60 * 1000); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.NotifyStoreLoaded(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.NotifyStoreError(); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 196116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(CloudPolicyRefreshSchedulerTest, RefreshSoon) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler->RefreshSoon(); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_runner_->RunUntilIdle(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Mock::VerifyAndClearExpectations(&client_); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 204558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsAvailable) { 205558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<CloudPolicyRefreshScheduler> scheduler( 206558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); 207558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetRefreshDelay(kPolicyRefreshRate); 208558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 209e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // The scheduler has scheduled refreshes at the initial refresh rate. 210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(2u, task_runner_->GetPendingTasks().size()); 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 212e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Signal that invalidations are available. 213e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scheduler->SetInvalidationServiceAvailability(true); 214e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_EQ(3u, task_runner_->GetPendingTasks().size()); 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckInitialRefresh(true); 217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 218558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch task_runner_->RunPendingTasks(); 220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Complete that fetch. 223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch client_.NotifyPolicyFetched(); 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The next refresh has been scheduled using a lower refresh rate. 227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); 228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); 229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 231558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsNotAvailable) { 232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<CloudPolicyRefreshScheduler> scheduler( 233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); 234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetRefreshDelay(kPolicyRefreshRate); 235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 236e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Signal that invalidations are not available. The scheduler will not 237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // schedule refreshes since the available state is not changed. 238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (int i = 0; i < 10; ++i) { 239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(false); 240e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_EQ(2u, task_runner_->GetPendingTasks().size()); 241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // This scheduled the initial refresh. 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckInitialRefresh(false); 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Perform that fetch now. 247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch task_runner_->RunPendingTasks(); 249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Complete that fetch. 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch client_.NotifyPolicyFetched(); 254558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The next refresh has been scheduled at the normal rate. 256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(1u, task_runner_->GetPendingTasks().size()); 257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(kPolicyRefreshRate); 258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 260558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsOffAndOn) { 261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<CloudPolicyRefreshScheduler> scheduler( 262558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); 263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetRefreshDelay(kPolicyRefreshRate); 264558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(true); 265558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Initial fetch. 266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) task_runner_->RunUntilIdle(); 268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 270558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch client_.NotifyPolicyFetched(); 271558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 272558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The next refresh has been scheduled using a lower refresh rate. 273558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); 274558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // If the service goes down and comes back up before the timeout then a 276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // refresh is rescheduled at the lower rate again; after executing all 277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // pending tasks only 1 fetch is performed. 278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(false); 279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(true); 280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The next refresh has been scheduled using a lower refresh rate. 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_CALL(client_, FetchPolicy()).Times(1); 282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); 283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch task_runner_->RunPendingTasks(); 284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 287558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(CloudPolicyRefreshSchedulerTest, InvalidationsDisconnected) { 288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<CloudPolicyRefreshScheduler> scheduler( 289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_)); 290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetRefreshDelay(kPolicyRefreshRate); 291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(true); 292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Initial fetch. 293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) task_runner_->RunUntilIdle(); 295558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 296558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 297558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch client_.NotifyPolicyFetched(); 298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The next refresh has been scheduled using a lower refresh rate. 300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Flush that task. 301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(CloudPolicyRefreshScheduler::kWithInvalidationsRefreshDelayMs); 302558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_CALL(client_, FetchPolicy()).Times(1); 303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch task_runner_->RunPendingTasks(); 304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Mock::VerifyAndClearExpectations(&client_); 305558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // If the service goes down then the refresh scheduler falls back on the 307e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // default polling rate. 308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scheduler->SetInvalidationServiceAvailability(false); 309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CheckTiming(kPolicyRefreshRate); 310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPolicyRefreshSchedulerSteadyStateTest 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public CloudPolicyRefreshSchedulerTest { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CloudPolicyRefreshSchedulerSteadyStateTest() {} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch refresh_scheduler_.reset(CreateRefreshScheduler()); 319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch refresh_scheduler_->SetRefreshDelay(kPolicyRefreshRate); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshSchedulerTest::SetUp(); 321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyPolicyFetched(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(kPolicyRefreshRate); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<CloudPolicyRefreshScheduler> refresh_scheduler_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnPolicyFetched) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyPolicyFetched(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(kPolicyRefreshRate); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnRegistrationStateChanged) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetDMToken("new_token"); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyRegistrationStateChanged(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(GetLastDelay(), base::TimeDelta()); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->ClearPendingTasks(); 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_.SetDMToken(std::string()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyRegistrationStateChanged(); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreLoaded) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.NotifyStoreLoaded(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(kPolicyRefreshRate); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreError) { 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->ClearPendingTasks(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_.NotifyStoreError(); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, RefreshDelayChange) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int delay_short_ms = 5 * 60 * 1000; 358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch refresh_scheduler_->SetRefreshDelay(delay_short_ms); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMinMs); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int delay_ms = 12 * 60 * 60 * 1000; 362558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch refresh_scheduler_->SetRefreshDelay(delay_ms); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(delay_ms); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const int delay_long_ms = 20 * 24 * 60 * 60 * 1000; 366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch refresh_scheduler_->SetRefreshDelay(delay_long_ms); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMaxMs); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnIPAddressChanged) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyIPAddressChanged(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(kPolicyRefreshRate); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetStatus(DM_STATUS_REQUEST_FAILED); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyIPAddressChanged(); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(GetLastDelay(), base::TimeDelta()); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ClientErrorTestParam { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceManagementStatus client_error; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 expected_delay_ms; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int backoff_factor; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ClientErrorTestParam kClientErrorTestCases[] = { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_REQUEST_INVALID, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_REQUEST_FAILED, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_TEMPORARY_UNAVAILABLE, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_HTTP_STATUS_ERROR, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_RESPONSE_DECODING_ERROR, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_DEVICE_NOT_FOUND, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1 }, 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1 }, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_ACTIVATION_PENDING, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolicyRefreshRate, 1 }, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1 }, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_MISSING_LICENSES, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1 }, 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_DEVICE_ID_CONFLICT, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 1 }, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { DM_STATUS_SERVICE_POLICY_NOT_FOUND, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolicyRefreshRate, 1 }, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPolicyRefreshSchedulerClientErrorTest 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public CloudPolicyRefreshSchedulerSteadyStateTest, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public testing::WithParamInterface<ClientErrorTestParam> { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(CloudPolicyRefreshSchedulerClientErrorTest, OnClientError) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.SetStatus(GetParam().client_error); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner_->ClearPendingTasks(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See whether the error triggers the right refresh delay. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 expected_delay_ms = GetParam().expected_delay_ms; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyClientError(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (expected_delay_ms >= 0) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(expected_delay_ms); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check whether exponential backoff is working as expected and capped at 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the regular refresh rate (if applicable). 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_delay_ms *= GetParam().backoff_factor; 433558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch last_update_ = base::Time::NowFromSystemTime(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_.NotifyClientError(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckTiming(std::max(std::min(expected_delay_ms, kPolicyRefreshRate), 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetParam().expected_delay_ms)); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (GetParam().backoff_factor > 1 && 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_delay_ms <= kPolicyRefreshRate); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(base::TimeDelta(), GetLastDelay()); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(CloudPolicyRefreshSchedulerClientErrorTest, 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyRefreshSchedulerClientErrorTest, 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::ValuesIn(kClientErrorTestCases)); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 450