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

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: 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_percentage|.
23 bool IsTimeDeltaWithinJitter(const base::TimeDelta& base_time_delta,
24 const base::TimeDelta& jittered_time_delta,
25 double max_jitter_percentage) {
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_percentage;
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_percentage)
43 : SyncSchedulerImpl(delegate,
44 refresh_period,
45 recovery_period,
46 max_jitter_percentage,
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_, false);
106 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
107
108 scheduler_->ForceSync();
109 EXPECT_TRUE(sync_request_);
110 sync_request_->Complete(true);
111 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
112 }
113
114 TEST_F(ProximityAuthSyncSchedulerImplTest, ForceSyncFailure) {
115 scheduler_->Start(zero_elapsed_time_, false);
116 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
117
118 scheduler_->ForceSync();
119 EXPECT_TRUE(sync_request_);
120 sync_request_->Complete(false);
121 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
122 }
123
124 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshSuccess) {
125 EXPECT_EQ(SyncScheduler::State::NOT_STARTED, scheduler_->GetState());
126 scheduler_->Start(zero_elapsed_time_, false);
127 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
128
129 EXPECT_EQ(refresh_period_, timer()->GetCurrentDelay());
130 timer()->Fire();
131 EXPECT_EQ(SyncScheduler::State::SYNCING_FOR_PERIODIC_REFRESH,
132 scheduler_->GetState());
133 ASSERT_TRUE(sync_request_.get());
134 EXPECT_FALSE(sync_request_->is_aggressive_recovery());
135
136 sync_request_->Complete(true);
137 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
138 }
139
140 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshFailure) {
141 scheduler_->Start(zero_elapsed_time_, false);
142 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
143 timer()->Fire();
144 sync_request_->Complete(false);
145 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
146 }
147
148 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoverySuccess) {
149 scheduler_->Start(zero_elapsed_time_, true);
150 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
151
152 EXPECT_EQ(base_recovery_period_, timer()->GetCurrentDelay());
153 timer()->Fire();
154 EXPECT_EQ(SyncScheduler::State::SYNCING_FOR_AGGRESSIVE_RECOVERY,
155 scheduler_->GetState());
156 ASSERT_TRUE(sync_request_.get());
157 EXPECT_TRUE(sync_request_->is_aggressive_recovery());
158
159 sync_request_->Complete(true);
160 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
161 }
162
163 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoveryFailure) {
164 scheduler_->Start(zero_elapsed_time_, true);
165
166 timer()->Fire();
167 EXPECT_EQ(SyncScheduler::State::SYNCING_FOR_AGGRESSIVE_RECOVERY,
168 scheduler_->GetState());
169 sync_request_->Complete(false);
170 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
171 }
172
173 TEST_F(ProximityAuthSyncSchedulerImplTest, AggressiveRecoveryBackOff) {
174 scheduler_->Start(zero_elapsed_time_, true);
175 base::TimeDelta last_recovery_period = base::TimeDelta::FromSeconds(0);
176
177 for (int i = 0; i < 20; ++i) {
178 timer()->Fire();
179 EXPECT_EQ(SyncScheduler::State::SYNCING_FOR_AGGRESSIVE_RECOVERY,
180 scheduler_->GetState());
181 sync_request_->Complete(false);
182 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY,
183 scheduler_->GetState());
184
185 base::TimeDelta recovery_period = scheduler_->GetTimeToNextSync();
186 EXPECT_LE(last_recovery_period, recovery_period);
187 last_recovery_period = recovery_period;
188 }
189
190 // Backoffs should rapidly converge to the normal refresh period.
191 EXPECT_EQ(refresh_period_, last_recovery_period);
192 }
193
194 TEST_F(ProximityAuthSyncSchedulerImplTest, RefreshFailureRecoverySuccess) {
195 scheduler_->Start(zero_elapsed_time_, false);
196 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
197
198 timer()->Fire();
199 sync_request_->Complete(false);
200 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
201
202 timer()->Fire();
203 EXPECT_EQ(SyncScheduler::State::SYNCING_FOR_AGGRESSIVE_RECOVERY,
204 scheduler_->GetState());
205 sync_request_->Complete(true);
206 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
207 }
208
209 TEST_F(ProximityAuthSyncSchedulerImplTest, SyncImmediatelyForPeriodicRefresh) {
210 scheduler_->Start(base::TimeDelta::FromDays(kElapsedTimeDays), false);
211 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
212
213 EXPECT_TRUE(scheduler_->GetTimeToNextSync().is_zero());
214 EXPECT_TRUE(timer()->GetCurrentDelay().is_zero());
215 timer()->Fire();
216 EXPECT_TRUE(sync_request_);
217 }
218
219 TEST_F(ProximityAuthSyncSchedulerImplTest,
220 SyncImmediatelyForAggressiveRecovery) {
221 scheduler_->Start(base::TimeDelta::FromDays(kElapsedTimeDays), true);
222 EXPECT_EQ(SyncScheduler::State::AGGRESSIVE_RECOVERY, scheduler_->GetState());
223
224 EXPECT_TRUE(scheduler_->GetTimeToNextSync().is_zero());
225 EXPECT_TRUE(timer()->GetCurrentDelay().is_zero());
226 timer()->Fire();
227 EXPECT_TRUE(sync_request_);
228 }
229
230 TEST_F(ProximityAuthSyncSchedulerImplTest, InitialSyncShorterByElapsedTime) {
231 base::TimeDelta elapsed_time = base::TimeDelta::FromDays(2);
232 scheduler_->Start(elapsed_time, false);
233 EXPECT_EQ(SyncScheduler::State::PERIODIC_REFRESH, scheduler_->GetState());
234
235 EXPECT_EQ(refresh_period_ - elapsed_time, scheduler_->GetTimeToNextSync());
236 timer()->Fire();
237 EXPECT_TRUE(sync_request_);
238 }
239
240 TEST_F(ProximityAuthSyncSchedulerImplTest, PeriodicRefreshJitter) {
241 scheduler_.reset(new TestSyncSchedulerImpl(
242 this, refresh_period_, base_recovery_period_, kMaxJitterPercentage));
243
244 scheduler_->Start(zero_elapsed_time_, false);
245
246 base::TimeDelta cumulative_jitter = base::TimeDelta::FromSeconds(0);
247 for (int i = 0; i < 10; ++i) {
248 base::TimeDelta next_sync_delta = scheduler_->GetTimeToNextSync();
249 cumulative_jitter += (next_sync_delta - refresh_period_).magnitude();
250 EXPECT_TRUE(IsTimeDeltaWithinJitter(refresh_period_, next_sync_delta,
251 kMaxJitterPercentage));
252 timer()->Fire();
253 sync_request_->Complete(true);
254 }
255
256 // The probablility that all periods are randomly equal to |refresh_period_|
257 // is so low that we would expect the heat death of the universe before this
258 // test flakes.
259 EXPECT_FALSE(cumulative_jitter.is_zero());
260 }
261
262 TEST_F(ProximityAuthSyncSchedulerImplTest, JitteredTimeDeltaIsNonNegative) {
263 base::TimeDelta zero_delta = base::TimeDelta::FromSeconds(0);
264 double max_jitter_percentage = 1;
265 scheduler_.reset(new TestSyncSchedulerImpl(this, zero_delta, zero_delta,
266 max_jitter_percentage));
267 scheduler_->Start(zero_elapsed_time_, false);
268
269 for (int i = 0; i < 10; ++i) {
270 base::TimeDelta next_sync_delta = scheduler_->GetTimeToNextSync();
271 EXPECT_GE(zero_delta, next_sync_delta);
272 EXPECT_TRUE(IsTimeDeltaWithinJitter(zero_delta, next_sync_delta,
273 max_jitter_percentage));
274 timer()->Fire();
275 sync_request_->Complete(true);
276 }
277 }
278
279 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698