Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: components/proximity_auth/cryptauth/sync_scheduler_impl_unittest.cc

Issue 1147563002: Add SyncScheduler for scheduling CryptAuth enrollments and syncing devices. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactor out Strategy enum Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "components/proximity_auth/cryptauth/sync_scheduler_impl.h"
6
7 #include "base/timer/mock_timer.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9
10 namespace proximity_auth {
11
12 namespace {
13
14 // Constants configuring the the scheduler.
15 const int kElapsedTimeDays = 40;
16 const int kRefreshPeriodDays = 30;
17 const int kRecoveryPeriodSeconds = 10;
18 const double kMaxJitterPercentage = 0.1;
19 const char kTestSchedulerName[] = "TestSyncSchedulerImpl";
20
21 // Returns true if |jittered_time_delta| is within the range of a jittered
22 // |base_time_delta| with a maximum of |max_jitter_ratio|.
23 bool IsTimeDeltaWithinJitter(const base::TimeDelta& base_time_delta,
24 const base::TimeDelta& jittered_time_delta,
25 double max_jitter_ratio) {
26 if (base_time_delta.is_zero())
27 return jittered_time_delta.is_zero();
28
29 base::TimeDelta difference =
30 (jittered_time_delta - base_time_delta).magnitude();
31 double percentage_of_base =
32 difference.InMillisecondsF() / base_time_delta.InMillisecondsF();
33 return percentage_of_base < max_jitter_ratio;
34 }
35
36 // Test harness for the SyncSchedulerImpl to create MockTimers.
37 class TestSyncSchedulerImpl : public SyncSchedulerImpl {
38 public:
39 TestSyncSchedulerImpl(Delegate* delegate,
40 base::TimeDelta refresh_period,
41 base::TimeDelta recovery_period,
42 double max_jitter_ratio)
43 : SyncSchedulerImpl(delegate,
44 refresh_period,
45 recovery_period,
46 max_jitter_ratio,
47 kTestSchedulerName) {}
48
49 ~TestSyncSchedulerImpl() override {}
50
51 base::MockTimer* timer() { return mock_timer_; }
52
53 private:
54 scoped_ptr<base::Timer> CreateTimer() override {
55 bool retain_user_task = false;
56 bool is_repeating = false;
57 mock_timer_ = new base::MockTimer(retain_user_task, is_repeating);
58 return make_scoped_ptr(mock_timer_);
59 }
60
61 // A timer instance for testing. Owned by the parent scheduler.
62 base::MockTimer* mock_timer_;
63
64 DISALLOW_COPY_AND_ASSIGN(TestSyncSchedulerImpl);
65 };
66
67 } // namespace
68
69 class ProximityAuthSyncSchedulerImplTest : public testing::Test,
70 public SyncSchedulerImpl::Delegate {
71 protected:
72 ProximityAuthSyncSchedulerImplTest()
73 : refresh_period_(base::TimeDelta::FromDays(kRefreshPeriodDays)),
74 base_recovery_period_(
75 base::TimeDelta::FromSeconds(kRecoveryPeriodSeconds)),
76 zero_elapsed_time_(base::TimeDelta::FromSeconds(0)),
77 scheduler_(new TestSyncSchedulerImpl(this,
78 refresh_period_,
79 base_recovery_period_,
80 0)) {}
81
82 ~ProximityAuthSyncSchedulerImplTest() override {}
83
84 void OnSyncRequested(
85 scoped_ptr<SyncScheduler::SyncRequest> sync_request) override {
86 sync_request_ = sync_request.Pass();
87 }
88
89 base::MockTimer* timer() { return scheduler_->timer(); }
90
91 // The time deltas used to configure |scheduler_|.
92 base::TimeDelta refresh_period_;
93 base::TimeDelta base_recovery_period_;
94 base::TimeDelta zero_elapsed_time_;
95
96 // The scheduler instance under test.
97 scoped_ptr<TestSyncSchedulerImpl> scheduler_;
98
99 scoped_ptr<SyncScheduler::SyncRequest> sync_request_;
100
101 DISALLOW_COPY_AND_ASSIGN(ProximityAuthSyncSchedulerImplTest);
102 };
103
104 TEST_F(ProximityAuthSyncSchedulerImplTest, ForceSyncSuccess) {
105 scheduler_->Start(zero_elapsed_time_,
106 SyncScheduler::Strategy::PERIODIC_REFRESH);
Ilya Sherman 2015/05/19 22:46:55 Optional nit: I'd add using stmts for SyncSchedule
Tim Song 2015/05/20 00:13:22 Done.
107 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
108 scheduler_->GetStrategy());
109 EXPECT_EQ(SyncScheduler::SyncState::WAITING_FOR_REFRESH,
110 scheduler_->GetSyncState());
111
112 scheduler_->ForceSync();
113 EXPECT_EQ(SyncScheduler::SyncState::SYNC_IN_PROGRESS,
114 scheduler_->GetSyncState());
115 EXPECT_TRUE(sync_request_);
116 sync_request_->OnDidComplete(true);
117 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
118 scheduler_->GetStrategy());
119 EXPECT_EQ(SyncScheduler::SyncState::WAITING_FOR_REFRESH,
120 scheduler_->GetSyncState());
121 }
122
123 TEST_F(ProximityAuthSyncSchedulerImplTest, ForceSyncFailure) {
124 scheduler_->Start(zero_elapsed_time_,
125 SyncScheduler::Strategy::PERIODIC_REFRESH);
126 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
127 scheduler_->GetStrategy());
128
129 scheduler_->ForceSync();
130 EXPECT_TRUE(sync_request_);
131 sync_request_->OnDidComplete(false);
132 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
133 scheduler_->GetStrategy());
134 }
135
136 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshSuccess) {
137 EXPECT_EQ(SyncScheduler::SyncState::NOT_STARTED, scheduler_->GetSyncState());
138 scheduler_->Start(zero_elapsed_time_,
139 SyncScheduler::Strategy::PERIODIC_REFRESH);
140 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
141 scheduler_->GetStrategy());
142
143 EXPECT_EQ(refresh_period_, timer()->GetCurrentDelay());
144 timer()->Fire();
145 EXPECT_EQ(SyncScheduler::SyncState::SYNC_IN_PROGRESS,
146 scheduler_->GetSyncState());
147 ASSERT_TRUE(sync_request_.get());
148
149 sync_request_->OnDidComplete(true);
150 EXPECT_EQ(SyncScheduler::SyncState::WAITING_FOR_REFRESH,
151 scheduler_->GetSyncState());
152 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
153 scheduler_->GetStrategy());
154 }
155
156 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshFailure) {
157 scheduler_->Start(zero_elapsed_time_,
158 SyncScheduler::Strategy::PERIODIC_REFRESH);
159 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
160 scheduler_->GetStrategy());
161 timer()->Fire();
162 sync_request_->OnDidComplete(false);
163 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
164 scheduler_->GetStrategy());
165 }
166
167 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoverySuccess) {
168 scheduler_->Start(zero_elapsed_time_,
169 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY);
170 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
171 scheduler_->GetStrategy());
172
173 EXPECT_EQ(base_recovery_period_, timer()->GetCurrentDelay());
174 timer()->Fire();
175 EXPECT_EQ(SyncScheduler::SyncState::SYNC_IN_PROGRESS,
176 scheduler_->GetSyncState());
177 ASSERT_TRUE(sync_request_.get());
178
179 sync_request_->OnDidComplete(true);
180 EXPECT_EQ(SyncScheduler::SyncState::WAITING_FOR_REFRESH,
181 scheduler_->GetSyncState());
182 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
183 scheduler_->GetStrategy());
184 }
185
186 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoveryFailure) {
187 scheduler_->Start(zero_elapsed_time_,
188 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY);
189
190 timer()->Fire();
191 sync_request_->OnDidComplete(false);
192 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
193 scheduler_->GetStrategy());
194 }
195
196 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoveryBackOff) {
197 scheduler_->Start(zero_elapsed_time_,
198 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY);
199 base::TimeDelta last_recovery_period = base::TimeDelta::FromSeconds(0);
200
201 for (int i = 0; i < 20; ++i) {
202 timer()->Fire();
203 EXPECT_EQ(SyncScheduler::SyncState::SYNC_IN_PROGRESS,
204 scheduler_->GetSyncState());
205 sync_request_->OnDidComplete(false);
206 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
207 scheduler_->GetStrategy());
208 EXPECT_EQ(SyncScheduler::SyncState::WAITING_FOR_REFRESH,
209 scheduler_->GetSyncState());
210
211 base::TimeDelta recovery_period = scheduler_->GetTimeToNextSync();
212 EXPECT_LE(last_recovery_period, recovery_period);
213 last_recovery_period = recovery_period;
214 }
215
216 // Backoffs should rapidly converge to the normal refresh period.
217 EXPECT_EQ(refresh_period_, last_recovery_period);
218 }
219
220 TEST_F(ProximityAuthSyncSchedulerImplTest, RefreshFailureRecoverySuccess) {
221 scheduler_->Start(zero_elapsed_time_,
222 SyncScheduler::Strategy::PERIODIC_REFRESH);
223 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
224 scheduler_->GetStrategy());
225
226 timer()->Fire();
227 sync_request_->OnDidComplete(false);
228 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
229 scheduler_->GetStrategy());
230
231 timer()->Fire();
232 sync_request_->OnDidComplete(true);
233 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
234 scheduler_->GetStrategy());
235 }
236
237 TEST_F(ProximityAuthSyncSchedulerImplTest, SyncImmediatelyForPeriodicRefresh) {
238 scheduler_->Start(base::TimeDelta::FromDays(kElapsedTimeDays),
239 SyncScheduler::Strategy::PERIODIC_REFRESH);
240 EXPECT_TRUE(scheduler_->GetTimeToNextSync().is_zero());
241 EXPECT_TRUE(timer()->GetCurrentDelay().is_zero());
242 timer()->Fire();
243 EXPECT_TRUE(sync_request_);
244
245 EXPECT_EQ(SyncScheduler::Strategy::PERIODIC_REFRESH,
246 scheduler_->GetStrategy());
247 }
248
249 TEST_F(ProximityAuthSyncSchedulerImplTest,
250 SyncImmediatelyForAggressiveRecovery) {
251 scheduler_->Start(base::TimeDelta::FromDays(kElapsedTimeDays),
252 SyncScheduler::Strategy::AGGRESSIVE_RECOVERY);
253 EXPECT_TRUE(scheduler_->GetTimeToNextSync().is_zero());
254 EXPECT_TRUE(timer()->GetCurrentDelay().is_zero());
255 timer()->Fire();
256 EXPECT_TRUE(sync_request_);
257
258 EXPECT_EQ(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY,
259 scheduler_->GetStrategy());
260 }
261
262 TEST_F(ProximityAuthSyncSchedulerImplTest, InitialSyncShorterByElapsedTime) {
263 base::TimeDelta elapsed_time = base::TimeDelta::FromDays(2);
264 scheduler_->Start(elapsed_time, SyncScheduler::Strategy::PERIODIC_REFRESH);
265 EXPECT_EQ(refresh_period_ - elapsed_time, scheduler_->GetTimeToNextSync());
266 timer()->Fire();
267 EXPECT_TRUE(sync_request_);
268 }
269
270 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshJitter) {
271 scheduler_.reset(new TestSyncSchedulerImpl(
272 this, refresh_period_, base_recovery_period_, kMaxJitterPercentage));
273
274 scheduler_->Start(zero_elapsed_time_,
275 SyncScheduler::Strategy::PERIODIC_REFRESH);
276
277 base::TimeDelta cumulative_jitter = base::TimeDelta::FromSeconds(0);
278 for (int i = 0; i < 10; ++i) {
279 base::TimeDelta next_sync_delta = scheduler_->GetTimeToNextSync();
280 cumulative_jitter += (next_sync_delta - refresh_period_).magnitude();
281 EXPECT_TRUE(IsTimeDeltaWithinJitter(refresh_period_, next_sync_delta,
282 kMaxJitterPercentage));
283 timer()->Fire();
284 sync_request_->OnDidComplete(true);
285 }
286
287 // The probablility that all periods are randomly equal to |refresh_period_|
288 // is so low that we would expect the heat death of the universe before this
289 // test flakes.
290 EXPECT_FALSE(cumulative_jitter.is_zero());
291 }
292
293 TEST_F(ProximityAuthSyncSchedulerImplTest, JitteredTimeDeltaIsNonNegative) {
294 base::TimeDelta zero_delta = base::TimeDelta::FromSeconds(0);
295 double max_jitter_ratio = 1;
296 scheduler_.reset(new TestSyncSchedulerImpl(this, zero_delta, zero_delta,
297 max_jitter_ratio));
298 scheduler_->Start(zero_elapsed_time_,
299 SyncScheduler::Strategy::PERIODIC_REFRESH);
300
301 for (int i = 0; i < 10; ++i) {
302 base::TimeDelta next_sync_delta = scheduler_->GetTimeToNextSync();
303 EXPECT_GE(zero_delta, next_sync_delta);
304 EXPECT_TRUE(
305 IsTimeDeltaWithinJitter(zero_delta, next_sync_delta, max_jitter_ratio));
306 timer()->Fire();
307 sync_request_->OnDidComplete(true);
308 }
309 }
310
311 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698