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.h" | |
10 #include "base/test/test_simple_task_runner.h" | |
11 #include "chrome/browser/policy/cloud_policy_constants.h" | |
12 #include "chrome/browser/policy/cloud_policy_refresh_scheduler.h" | |
13 #include "chrome/browser/policy/mock_cloud_policy_client.h" | |
14 #include "chrome/browser/policy/mock_cloud_policy_store.h" | |
15 #include "chrome/browser/prefs/browser_prefs.h" | |
16 #include "policy/policy_constants.h" | |
17 #include "testing/gmock/include/gmock/gmock.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 namespace em = enterprise_management; | |
21 | |
22 using testing::DoAll; | |
23 using testing::Return; | |
24 using testing::SaveArg; | |
25 using testing::_; | |
26 | |
27 namespace policy { | |
28 | |
29 namespace { | |
30 const int64 kPolicyRefreshRate = 4 * 60 * 60 * 1000; | |
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 store_.policy_->set_timestamp( | |
47 ((base::Time::NowFromSystemTime() - base::TimeDelta::FromMinutes(1)) - | |
48 base::Time::UnixEpoch()).InMilliseconds()); | |
49 last_refresh_ = | |
50 base::Time::UnixEpoch() + | |
51 base::TimeDelta::FromMilliseconds(store_.policy_->timestamp()); | |
52 } | |
53 | |
54 CloudPolicyRefreshScheduler* CreateRefreshScheduler() { | |
55 CloudPolicyRefreshScheduler* scheduler = | |
56 new CloudPolicyRefreshScheduler(&client_, &store_, task_runner_); | |
57 scheduler->SetRefreshDelay(kPolicyRefreshRate); | |
58 return scheduler; | |
59 } | |
60 | |
61 void NotifyIPAddressChanged() { | |
62 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); | |
63 loop_.RunUntilIdle(); | |
64 } | |
65 | |
66 base::TimeDelta GetLastDelay() const { | |
67 const std::deque<base::TestPendingTask>& pending_tasks = | |
68 task_runner_->GetPendingTasks(); | |
69 return | |
70 pending_tasks.empty() ? base::TimeDelta() : pending_tasks.back().delay; | |
71 } | |
72 | |
73 void CheckTiming(int64 expected_delay_ms) const { | |
74 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
75 base::Time now(base::Time::NowFromSystemTime()); | |
76 base::TimeDelta expected_delay( | |
77 base::TimeDelta::FromMilliseconds(expected_delay_ms)); | |
78 EXPECT_GE(GetLastDelay(), expected_delay - (now - last_refresh_)); | |
79 EXPECT_LE(GetLastDelay(), expected_delay); | |
80 } | |
81 | |
82 MessageLoop loop_; | |
83 MockCloudPolicyClient client_; | |
84 MockCloudPolicyStore store_; | |
85 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | |
86 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; | |
87 | |
88 // Base time for the refresh that the scheduler should be using. | |
89 base::Time last_refresh_; | |
90 }; | |
91 | |
92 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshNoPolicy) { | |
93 store_.policy_.reset(); | |
94 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
95 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
96 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
97 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
98 task_runner_->RunUntilIdle(); | |
99 } | |
100 | |
101 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshUnmanaged) { | |
102 store_.policy_->set_state(em::PolicyData::UNMANAGED); | |
103 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
104 CheckTiming(CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs); | |
105 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
106 task_runner_->RunUntilIdle(); | |
107 } | |
108 | |
109 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedNotYetFetched) { | |
110 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
111 EXPECT_FALSE(task_runner_->GetPendingTasks().empty()); | |
112 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
113 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
114 task_runner_->RunUntilIdle(); | |
115 } | |
116 | |
117 TEST_F(CloudPolicyRefreshSchedulerTest, InitialRefreshManagedAlreadyFetched) { | |
118 last_refresh_ = base::Time::NowFromSystemTime(); | |
119 client_.SetPolicy(PolicyNamespaceKey(dm_protocol::kChromeUserPolicyType, | |
120 std::string()), | |
121 em::PolicyFetchResponse()); | |
122 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
123 CheckTiming(kPolicyRefreshRate); | |
124 EXPECT_CALL(client_, FetchPolicy()).Times(1); | |
125 task_runner_->RunUntilIdle(); | |
126 } | |
127 | |
128 TEST_F(CloudPolicyRefreshSchedulerTest, Unregistered) { | |
129 client_.SetDMToken(""); | |
130 scoped_ptr<CloudPolicyRefreshScheduler> scheduler(CreateRefreshScheduler()); | |
131 client_.NotifyPolicyFetched(); | |
132 client_.NotifyRegistrationStateChanged(); | |
133 client_.NotifyClientError(); | |
134 scheduler->SetRefreshDelay(12 * 60 * 60 * 1000); | |
135 store_.NotifyStoreLoaded(); | |
136 store_.NotifyStoreError(); | |
137 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
138 } | |
139 | |
140 class CloudPolicyRefreshSchedulerSteadyStateTest | |
141 : public CloudPolicyRefreshSchedulerTest { | |
142 protected: | |
143 CloudPolicyRefreshSchedulerSteadyStateTest() | |
144 : refresh_scheduler_(&client_, &store_, task_runner_) {} | |
145 | |
146 virtual void SetUp() OVERRIDE { | |
147 refresh_scheduler_.SetRefreshDelay(kPolicyRefreshRate); | |
148 CloudPolicyRefreshSchedulerTest::SetUp(); | |
149 last_refresh_ = base::Time::NowFromSystemTime(); | |
150 client_.NotifyPolicyFetched(); | |
151 CheckTiming(kPolicyRefreshRate); | |
152 } | |
153 | |
154 CloudPolicyRefreshScheduler refresh_scheduler_; | |
155 }; | |
156 | |
157 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnPolicyFetched) { | |
158 client_.NotifyPolicyFetched(); | |
159 CheckTiming(kPolicyRefreshRate); | |
160 } | |
161 | |
162 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnRegistrationStateChanged) { | |
163 client_.SetDMToken("new_token"); | |
164 client_.NotifyRegistrationStateChanged(); | |
165 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
166 | |
167 task_runner_->ClearPendingTasks(); | |
168 client_.SetDMToken(""); | |
169 client_.NotifyRegistrationStateChanged(); | |
170 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
171 } | |
172 | |
173 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreLoaded) { | |
174 store_.NotifyStoreLoaded(); | |
175 CheckTiming(kPolicyRefreshRate); | |
176 } | |
177 | |
178 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnStoreError) { | |
179 task_runner_->ClearPendingTasks(); | |
180 store_.NotifyStoreError(); | |
181 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
182 } | |
183 | |
184 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, RefreshDelayChange) { | |
185 const int delay_short_ms = 5 * 60 * 1000; | |
186 refresh_scheduler_.SetRefreshDelay(delay_short_ms); | |
187 CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMinMs); | |
188 | |
189 const int delay_ms = 12 * 60 * 60 * 1000; | |
190 refresh_scheduler_.SetRefreshDelay(delay_ms); | |
191 CheckTiming(delay_ms); | |
192 | |
193 const int delay_long_ms = 2 * 24 * 60 * 60 * 1000; | |
194 refresh_scheduler_.SetRefreshDelay(delay_long_ms); | |
195 CheckTiming(CloudPolicyRefreshScheduler::kRefreshDelayMaxMs); | |
196 } | |
197 | |
198 TEST_F(CloudPolicyRefreshSchedulerSteadyStateTest, OnIPAddressChanged) { | |
199 NotifyIPAddressChanged(); | |
200 CheckTiming(kPolicyRefreshRate); | |
201 | |
202 client_.SetStatus(DM_STATUS_REQUEST_FAILED); | |
203 NotifyIPAddressChanged(); | |
204 EXPECT_EQ(GetLastDelay(), base::TimeDelta()); | |
205 } | |
206 | |
207 struct ClientErrorTestParam { | |
208 DeviceManagementStatus client_error; | |
209 int64 expected_delay_ms; | |
210 int backoff_factor; | |
211 }; | |
212 | |
213 static const ClientErrorTestParam kClientErrorTestCases[] = { | |
214 { DM_STATUS_REQUEST_INVALID, | |
215 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
216 { DM_STATUS_REQUEST_FAILED, | |
217 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, | |
218 { DM_STATUS_TEMPORARY_UNAVAILABLE, | |
219 CloudPolicyRefreshScheduler::kInitialErrorRetryDelayMs, 2 }, | |
220 { DM_STATUS_HTTP_STATUS_ERROR, | |
221 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
222 { DM_STATUS_RESPONSE_DECODING_ERROR, | |
223 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
224 { DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED, | |
225 CloudPolicyRefreshScheduler::kUnmanagedRefreshDelayMs, 1 }, | |
226 { DM_STATUS_SERVICE_DEVICE_NOT_FOUND, | |
227 -1, 1 }, | |
228 { DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID, | |
229 -1, 1 }, | |
230 { DM_STATUS_SERVICE_ACTIVATION_PENDING, | |
231 kPolicyRefreshRate, 1 }, | |
232 { DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER, | |
233 -1, 1 }, | |
234 { DM_STATUS_SERVICE_MISSING_LICENSES, | |
235 -1, 1 }, | |
236 { DM_STATUS_SERVICE_DEVICE_ID_CONFLICT, | |
237 -1, 1 }, | |
238 { DM_STATUS_SERVICE_POLICY_NOT_FOUND, | |
239 kPolicyRefreshRate, 1 }, | |
240 }; | |
241 | |
242 class CloudPolicyRefreshSchedulerClientErrorTest | |
243 : public CloudPolicyRefreshSchedulerSteadyStateTest, | |
244 public testing::WithParamInterface<ClientErrorTestParam> { | |
245 }; | |
246 | |
247 TEST_P(CloudPolicyRefreshSchedulerClientErrorTest, OnClientError) { | |
248 client_.SetStatus(GetParam().client_error); | |
249 task_runner_->ClearPendingTasks(); | |
250 | |
251 // See whether the error triggers the right refresh delay. | |
252 int64 expected_delay_ms = GetParam().expected_delay_ms; | |
253 client_.NotifyClientError(); | |
254 if (expected_delay_ms >= 0) { | |
255 CheckTiming(expected_delay_ms); | |
256 | |
257 // Check whether exponential backoff is working as expected and capped at | |
258 // the regular refresh rate (if applicable). | |
259 do { | |
260 expected_delay_ms *= GetParam().backoff_factor; | |
261 last_refresh_ = base::Time::NowFromSystemTime(); | |
262 client_.NotifyClientError(); | |
263 CheckTiming(std::max(std::min(expected_delay_ms, kPolicyRefreshRate), | |
264 GetParam().expected_delay_ms)); | |
265 } while (GetParam().backoff_factor > 1 && | |
266 expected_delay_ms <= kPolicyRefreshRate); | |
267 } else { | |
268 EXPECT_EQ(base::TimeDelta(), GetLastDelay()); | |
269 EXPECT_TRUE(task_runner_->GetPendingTasks().empty()); | |
270 } | |
271 } | |
272 | |
273 INSTANTIATE_TEST_CASE_P(CloudPolicyRefreshSchedulerClientErrorTest, | |
274 CloudPolicyRefreshSchedulerClientErrorTest, | |
275 testing::ValuesIn(kClientErrorTestCases)); | |
276 | |
277 } // namespace policy | |
OLD | NEW |