QUIC - cleanup changes to sync chromium tree with internal source.
[chromium-blink-merge.git] / components / domain_reliability / scheduler_unittest.cc
blobb70ccbba5fb28a668386118e3273cfa31c400b4c
1 // Copyright 2014 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.
5 #include "components/domain_reliability/scheduler.h"
7 #include "base/bind.h"
8 #include "base/time/time.h"
9 #include "components/domain_reliability/config.h"
10 #include "components/domain_reliability/test_util.h"
11 #include "components/domain_reliability/uploader.h"
12 #include "components/domain_reliability/util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace domain_reliability {
16 namespace {
18 using base::TimeDelta;
19 using base::TimeTicks;
21 class DomainReliabilitySchedulerTest : public testing::Test {
22 public:
23 DomainReliabilitySchedulerTest()
24 : num_collectors_(0),
25 params_(MakeTestSchedulerParams()),
26 callback_called_(false) {}
28 void CreateScheduler(int num_collectors) {
29 DCHECK_LT(0, num_collectors);
30 DCHECK(!scheduler_);
32 num_collectors_ = num_collectors;
33 scheduler_.reset(new DomainReliabilityScheduler(
34 &time_,
35 num_collectors_,
36 params_,
37 base::Bind(&DomainReliabilitySchedulerTest::ScheduleUploadCallback,
38 base::Unretained(this))));
39 scheduler_->MakeDeterministicForTesting();
42 void NotifySuccessfulUpload() {
43 DomainReliabilityUploader::UploadResult result;
44 result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
45 scheduler_->OnUploadComplete(result);
48 void NotifyFailedUpload() {
49 DomainReliabilityUploader::UploadResult result;
50 result.status = DomainReliabilityUploader::UploadResult::FAILURE;
51 scheduler_->OnUploadComplete(result);
54 void NotifyRetryAfterUpload(base::TimeDelta retry_after) {
55 DomainReliabilityUploader::UploadResult result;
56 result.status = DomainReliabilityUploader::UploadResult::RETRY_AFTER;
57 result.retry_after = retry_after;
58 scheduler_->OnUploadComplete(result);
61 ::testing::AssertionResult CheckNoPendingUpload() {
62 DCHECK(scheduler_);
64 if (!callback_called_)
65 return ::testing::AssertionSuccess();
67 return ::testing::AssertionFailure()
68 << "expected no upload, got upload between "
69 << callback_min_.InSeconds() << " and "
70 << callback_max_.InSeconds() << " seconds from now";
73 ::testing::AssertionResult CheckPendingUpload(TimeDelta expected_min,
74 TimeDelta expected_max) {
75 DCHECK(scheduler_);
76 DCHECK_LE(expected_min.InMicroseconds(), expected_max.InMicroseconds());
78 if (callback_called_ && expected_min == callback_min_
79 && expected_max == callback_max_) {
80 callback_called_ = false;
81 return ::testing::AssertionSuccess();
84 if (callback_called_) {
85 return ::testing::AssertionFailure()
86 << "expected upload between " << expected_min.InSeconds()
87 << " and " << expected_max.InSeconds() << " seconds from now, "
88 << "got upload between " << callback_min_.InSeconds()
89 << " and " << callback_max_.InSeconds() << " seconds from now";
90 } else {
91 return ::testing::AssertionFailure()
92 << "expected upload between " << expected_min.InSeconds()
93 << " and " << expected_max.InSeconds() << " seconds from now, "
94 << "got no upload";
98 ::testing::AssertionResult CheckStartingUpload(size_t expected_collector) {
99 DCHECK(scheduler_);
100 DCHECK_GT(num_collectors_, expected_collector);
102 size_t collector = scheduler_->OnUploadStart();
103 if (collector == expected_collector)
104 return ::testing::AssertionSuccess();
106 return ::testing::AssertionFailure()
107 << "expected upload to collector " << expected_collector
108 << ", got upload to collector " << collector;
111 TimeDelta min_delay() const { return params_.minimum_upload_delay; }
112 TimeDelta max_delay() const { return params_.maximum_upload_delay; }
113 TimeDelta retry_interval() const { return params_.upload_retry_interval; }
114 TimeDelta zero_delta() const { return base::TimeDelta::FromMicroseconds(0); }
116 protected:
117 void ScheduleUploadCallback(TimeDelta min, TimeDelta max) {
118 callback_called_ = true;
119 callback_min_ = min;
120 callback_max_ = max;
123 MockTime time_;
124 size_t num_collectors_;
125 DomainReliabilityScheduler::Params params_;
126 scoped_ptr<DomainReliabilityScheduler> scheduler_;
128 bool callback_called_;
129 TimeDelta callback_min_;
130 TimeDelta callback_max_;
133 TEST_F(DomainReliabilitySchedulerTest, Create) {
134 CreateScheduler(1);
137 TEST_F(DomainReliabilitySchedulerTest, UploadNotPendingWithoutBeacon) {
138 CreateScheduler(1);
140 ASSERT_TRUE(CheckNoPendingUpload());
143 TEST_F(DomainReliabilitySchedulerTest, SuccessfulUploads) {
144 CreateScheduler(1);
146 scheduler_->OnBeaconAdded();
147 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
148 time_.Advance(min_delay());
149 ASSERT_TRUE(CheckStartingUpload(0));
150 NotifySuccessfulUpload();
152 scheduler_->OnBeaconAdded();
153 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
154 time_.Advance(min_delay());
155 ASSERT_TRUE(CheckStartingUpload(0));
156 NotifySuccessfulUpload();
159 TEST_F(DomainReliabilitySchedulerTest, RetryAfter) {
160 CreateScheduler(1);
162 base::TimeDelta retry_after_interval = base::TimeDelta::FromMinutes(30);
164 scheduler_->OnBeaconAdded();
165 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
166 time_.Advance(min_delay());
167 ASSERT_TRUE(CheckStartingUpload(0));
168 NotifyRetryAfterUpload(retry_after_interval);
170 scheduler_->OnBeaconAdded();
171 ASSERT_TRUE(CheckPendingUpload(retry_after_interval, retry_after_interval));
172 time_.Advance(retry_after_interval);
173 ASSERT_TRUE(CheckStartingUpload(0));
174 NotifySuccessfulUpload();
177 TEST_F(DomainReliabilitySchedulerTest, Failover) {
178 CreateScheduler(2);
180 scheduler_->OnBeaconAdded();
181 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
182 time_.Advance(min_delay());
183 ASSERT_TRUE(CheckStartingUpload(0));
184 NotifyFailedUpload();
186 scheduler_->OnBeaconAdded();
187 ASSERT_TRUE(CheckPendingUpload(zero_delta(), max_delay() - min_delay()));
188 // Don't need to advance; should retry immediately.
189 ASSERT_TRUE(CheckStartingUpload(1));
190 NotifySuccessfulUpload();
193 TEST_F(DomainReliabilitySchedulerTest, FailedAllCollectors) {
194 CreateScheduler(2);
196 // T = 0
197 scheduler_->OnBeaconAdded();
198 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
199 time_.Advance(min_delay());
201 // T = min_delay
202 ASSERT_TRUE(CheckStartingUpload(0));
203 NotifyFailedUpload();
205 ASSERT_TRUE(CheckPendingUpload(zero_delta(), max_delay() - min_delay()));
206 // Don't need to advance; should retry immediately.
207 ASSERT_TRUE(CheckStartingUpload(1));
208 NotifyFailedUpload();
210 ASSERT_TRUE(CheckPendingUpload(retry_interval(), max_delay() - min_delay()));
211 time_.Advance(retry_interval());
213 // T = min_delay + retry_interval
214 ASSERT_TRUE(CheckStartingUpload(0));
215 NotifyFailedUpload();
217 ASSERT_TRUE(CheckPendingUpload(
218 zero_delta(),
219 max_delay() - min_delay() - retry_interval()));
220 ASSERT_TRUE(CheckStartingUpload(1));
221 NotifyFailedUpload();
224 // Make sure that the scheduler uses the first available collector at upload
225 // time, even if it wasn't available at scheduling time.
226 TEST_F(DomainReliabilitySchedulerTest, DetermineCollectorAtUpload) {
227 CreateScheduler(2);
229 // T = 0
230 scheduler_->OnBeaconAdded();
231 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
232 time_.Advance(min_delay());
234 // T = min_delay
235 ASSERT_TRUE(CheckStartingUpload(0));
236 NotifyFailedUpload();
238 ASSERT_TRUE(CheckPendingUpload(zero_delta(), max_delay() - min_delay()));
239 time_.Advance(retry_interval());
241 // T = min_delay + retry_interval; collector 0 should be active again.
242 ASSERT_TRUE(CheckStartingUpload(0));
243 NotifySuccessfulUpload();
246 TEST_F(DomainReliabilitySchedulerTest, BeaconWhilePending) {
247 CreateScheduler(1);
249 scheduler_->OnBeaconAdded();
250 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
252 // Second beacon should not call callback again.
253 scheduler_->OnBeaconAdded();
254 ASSERT_TRUE(CheckNoPendingUpload());
255 time_.Advance(min_delay());
257 // No pending upload after beacon.
258 ASSERT_TRUE(CheckStartingUpload(0));
259 NotifySuccessfulUpload();
260 ASSERT_TRUE(CheckNoPendingUpload());
263 TEST_F(DomainReliabilitySchedulerTest, BeaconWhileUploading) {
264 CreateScheduler(1);
266 scheduler_->OnBeaconAdded();
267 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
268 time_.Advance(min_delay());
270 // If a beacon arrives during the upload, a new upload should be pending.
271 ASSERT_TRUE(CheckStartingUpload(0));
272 scheduler_->OnBeaconAdded();
273 NotifySuccessfulUpload();
274 ASSERT_TRUE(CheckPendingUpload(min_delay(), max_delay()));
276 time_.Advance(min_delay());
277 ASSERT_TRUE(CheckStartingUpload(0));
278 NotifySuccessfulUpload();
279 ASSERT_TRUE(CheckNoPendingUpload());
282 } // namespace
283 } // namespace domain_reliability