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

Side by Side Diff: components/offline_pages/background/request_picker_unittest.cc

Issue 2473553004: Request Picker task (Closed)
Patch Set: merge with latest Created 4 years, 1 month 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 2016 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/offline_pages/background/request_picker.h"
6
7 #include "base/bind.h"
8 #include "base/test/test_simple_task_runner.h"
9 #include "base/threading/thread_task_runner_handle.h"
10 #include "base/time/time.h"
11 #include "components/offline_pages/background/device_conditions.h"
12 #include "components/offline_pages/background/offliner_factory.h"
13 #include "components/offline_pages/background/offliner_policy.h"
14 #include "components/offline_pages/background/request_notifier.h"
15 #include "components/offline_pages/background/request_queue.h"
16 #include "components/offline_pages/background/request_queue_in_memory_store.h"
17 #include "components/offline_pages/background/save_page_request.h"
18 #include "components/offline_pages/offline_page_item.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace offline_pages {
22
23 namespace {
24 // Data for request 1.
25 const int64_t kRequestId1 = 17;
26 const GURL kUrl1("https://google.com");
27 const ClientId kClientId1("bookmark", "1234");
28 // Data for request 2.
29 const int64_t kRequestId2 = 42;
30 const GURL kUrl2("http://nytimes.com");
31 const ClientId kClientId2("bookmark", "5678");
32 const bool kUserRequested = true;
33 const int kAttemptCount = 1;
34 const int kMaxStartedTries = 5;
35 const int kMaxCompletedTries = 1;
36
37 // Constants for policy values - These settings represent the default values.
38 const bool kPreferUntried = false;
39 const bool kPreferEarlier = true;
40 const bool kPreferRetryCount = true;
41 const int kBackgroundProcessingTimeBudgetSeconds = 170;
42
43 // Default request
44 const SavePageRequest kEmptyRequest(0UL,
45 GURL(""),
46 ClientId("", ""),
47 base::Time(),
48 true);
49 } // namespace
50
51 class RequestNotifierStub : public RequestNotifier {
52 public:
53 RequestNotifierStub()
54 : last_expired_request_(kEmptyRequest), total_expired_requests_(0) {}
55
56 void NotifyAdded(const SavePageRequest& request) override {}
57 void NotifyChanged(const SavePageRequest& request) override {}
58
59 void NotifyCompleted(const SavePageRequest& request,
60 BackgroundSavePageResult status) override {
61 last_expired_request_ = request;
62 last_request_expiration_status_ = status;
63 total_expired_requests_++;
64 }
65
66 const SavePageRequest& last_expired_request() {
67 return last_expired_request_;
68 }
69
70 RequestCoordinator::BackgroundSavePageResult
71 last_request_expiration_status() {
72 return last_request_expiration_status_;
73 }
74
75 int32_t total_expired_requests() { return total_expired_requests_; }
76
77 private:
78 BackgroundSavePageResult last_request_expiration_status_;
79 SavePageRequest last_expired_request_;
80 int32_t total_expired_requests_;
81 };
82
83 class RequestPickerTest : public testing::Test {
84 public:
85 RequestPickerTest();
86
87 ~RequestPickerTest() override;
88
89 void SetUp() override;
90
91 void PumpLoop();
92
93 void AddRequestDone(RequestQueue::AddRequestResult result,
94 const SavePageRequest& request);
95
96 void RequestPicked(const SavePageRequest& request);
97
98 void RequestNotPicked(const bool non_user_requested_tasks_remaining);
99
100 void QueueRequestsAndChooseOne(const SavePageRequest& request1,
101 const SavePageRequest& request2);
102
103 RequestNotifierStub* GetNotifier() { return notifier_.get(); }
104
105 protected:
106 // The request queue is simple enough we will use a real queue with a memory
107 // store instead of a stub.
108 std::unique_ptr<RequestQueue> queue_;
109 std::unique_ptr<RequestPicker> picker_;
110 std::unique_ptr<RequestNotifierStub> notifier_;
111 std::unique_ptr<SavePageRequest> last_picked_;
112 std::unique_ptr<OfflinerPolicy> policy_;
113 RequestCoordinatorEventLogger event_logger_;
114 bool request_queue_not_picked_called_;
115
116 private:
117 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
118 base::ThreadTaskRunnerHandle task_runner_handle_;
119 };
120
121 RequestPickerTest::RequestPickerTest()
122 : task_runner_(new base::TestSimpleTaskRunner),
123 task_runner_handle_(task_runner_) {}
124
125 RequestPickerTest::~RequestPickerTest() {}
126
127 void RequestPickerTest::SetUp() {
128 std::unique_ptr<RequestQueueInMemoryStore> store(
129 new RequestQueueInMemoryStore());
130 queue_.reset(new RequestQueue(std::move(store)));
131 policy_.reset(new OfflinerPolicy());
132 notifier_.reset(new RequestNotifierStub());
133 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
134 &event_logger_));
135 request_queue_not_picked_called_ = false;
136 }
137
138 void RequestPickerTest::PumpLoop() {
139 task_runner_->RunUntilIdle();
140 }
141
142 void RequestPickerTest::AddRequestDone(RequestQueue::AddRequestResult result,
143 const SavePageRequest& request) {}
144
145 void RequestPickerTest::RequestPicked(const SavePageRequest& request) {
146 last_picked_.reset(new SavePageRequest(request));
147 }
148
149 void RequestPickerTest::RequestNotPicked(
150 const bool non_user_requested_tasks_remaining) {
151 request_queue_not_picked_called_ = true;
152 }
153
154 // Test helper to queue the two given requests and then pick one of them per
155 // configured policy.
156 void RequestPickerTest::QueueRequestsAndChooseOne(
157 const SavePageRequest& request1, const SavePageRequest& request2) {
158 DeviceConditions conditions;
159 std::set<int64_t> disabled_requests;
160 // Add test requests on the Queue.
161 queue_->AddRequest(request1, base::Bind(&RequestPickerTest::AddRequestDone,
162 base::Unretained(this)));
163 queue_->AddRequest(request2, base::Bind(&RequestPickerTest::AddRequestDone,
164 base::Unretained(this)));
165
166 // Pump the loop to give the async queue the opportunity to do the adds.
167 PumpLoop();
168
169 // Call the method under test.
170 picker_->ChooseNextRequest(
171 base::Bind(&RequestPickerTest::RequestPicked, base::Unretained(this)),
172 base::Bind(&RequestPickerTest::RequestNotPicked, base::Unretained(this)),
173 &conditions, disabled_requests);
174
175 // Pump the loop again to give the async queue the opportunity to return
176 // results from the Get operation, and for the picker to call the "picked"
177 // callback.
178 PumpLoop();
179 }
180
181 TEST_F(RequestPickerTest, PickFromEmptyQueue) {
182 DeviceConditions conditions;
183 std::set<int64_t> disabled_requests;
184 picker_->ChooseNextRequest(
185 base::Bind(&RequestPickerTest::RequestPicked, base::Unretained(this)),
186 base::Bind(&RequestPickerTest::RequestNotPicked, base::Unretained(this)),
187 &conditions, disabled_requests);
188
189 // Pump the loop again to give the async queue the opportunity to return
190 // results from the Get operation, and for the picker to call the "QueueEmpty"
191 // callback.
192 PumpLoop();
193
194 EXPECT_TRUE(request_queue_not_picked_called_);
195 }
196
197 TEST_F(RequestPickerTest, ChooseRequestWithHigherRetryCount) {
198 policy_.reset(new OfflinerPolicy(
199 kPreferUntried, kPreferEarlier, kPreferRetryCount, kMaxStartedTries,
200 kMaxCompletedTries + 1, kBackgroundProcessingTimeBudgetSeconds));
201 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
202 &event_logger_));
203
204 base::Time creation_time = base::Time::Now();
205 SavePageRequest request1(
206 kRequestId1, kUrl1, kClientId1, creation_time, kUserRequested);
207 SavePageRequest request2(
208 kRequestId2, kUrl2, kClientId2, creation_time, kUserRequested);
209 request2.set_completed_attempt_count(kAttemptCount);
210
211 QueueRequestsAndChooseOne(request1, request2);
212
213 EXPECT_EQ(kRequestId2, last_picked_->request_id());
214 EXPECT_FALSE(request_queue_not_picked_called_);
215 }
216
217 TEST_F(RequestPickerTest, ChooseRequestWithSameRetryCountButEarlier) {
218 base::Time creation_time1 =
219 base::Time::Now() - base::TimeDelta::FromSeconds(10);
220 base::Time creation_time2 = base::Time::Now();
221 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time1,
222 kUserRequested);
223 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time2,
224 kUserRequested);
225
226 QueueRequestsAndChooseOne(request1, request2);
227
228 EXPECT_EQ(kRequestId1, last_picked_->request_id());
229 EXPECT_FALSE(request_queue_not_picked_called_);
230 }
231
232 TEST_F(RequestPickerTest, ChooseEarlierRequest) {
233 // We need a custom policy object prefering recency to retry count.
234 policy_.reset(new OfflinerPolicy(
235 kPreferUntried, kPreferEarlier, !kPreferRetryCount, kMaxStartedTries,
236 kMaxCompletedTries, kBackgroundProcessingTimeBudgetSeconds));
237 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
238 &event_logger_));
239
240 base::Time creation_time1 =
241 base::Time::Now() - base::TimeDelta::FromSeconds(10);
242 base::Time creation_time2 = base::Time::Now();
243 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time1,
244 kUserRequested);
245 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time2,
246 kUserRequested);
247 request2.set_completed_attempt_count(kAttemptCount);
248
249 QueueRequestsAndChooseOne(request1, request2);
250
251 EXPECT_EQ(kRequestId1, last_picked_->request_id());
252 EXPECT_FALSE(request_queue_not_picked_called_);
253 }
254
255 TEST_F(RequestPickerTest, ChooseSameTimeRequestWithHigherRetryCount) {
256 // We need a custom policy object preferring recency to retry count.
257 policy_.reset(new OfflinerPolicy(
258 kPreferUntried, kPreferEarlier, !kPreferRetryCount, kMaxStartedTries,
259 kMaxCompletedTries + 1, kBackgroundProcessingTimeBudgetSeconds));
260 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
261 &event_logger_));
262
263 base::Time creation_time = base::Time::Now();
264 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time,
265 kUserRequested);
266 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
267 kUserRequested);
268 request2.set_completed_attempt_count(kAttemptCount);
269
270 QueueRequestsAndChooseOne(request1, request2);
271
272 EXPECT_EQ(kRequestId2, last_picked_->request_id());
273 EXPECT_FALSE(request_queue_not_picked_called_);
274 }
275
276 TEST_F(RequestPickerTest, ChooseRequestWithLowerRetryCount) {
277 // We need a custom policy object preferring lower retry count.
278 policy_.reset(new OfflinerPolicy(
279 !kPreferUntried, kPreferEarlier, kPreferRetryCount, kMaxStartedTries,
280 kMaxCompletedTries + 1, kBackgroundProcessingTimeBudgetSeconds));
281 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
282 &event_logger_));
283
284 base::Time creation_time = base::Time::Now();
285 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time,
286 kUserRequested);
287 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time,
288 kUserRequested);
289 request2.set_completed_attempt_count(kAttemptCount);
290
291 QueueRequestsAndChooseOne(request1, request2);
292
293 EXPECT_EQ(kRequestId1, last_picked_->request_id());
294 EXPECT_FALSE(request_queue_not_picked_called_);
295 }
296
297 TEST_F(RequestPickerTest, ChooseLaterRequest) {
298 // We need a custom policy preferring recency over retry, and later requests.
299 policy_.reset(new OfflinerPolicy(
300 kPreferUntried, !kPreferEarlier, !kPreferRetryCount, kMaxStartedTries,
301 kMaxCompletedTries, kBackgroundProcessingTimeBudgetSeconds));
302 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
303 &event_logger_));
304
305 base::Time creation_time1 =
306 base::Time::Now() - base::TimeDelta::FromSeconds(10);
307 base::Time creation_time2 = base::Time::Now();
308 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time1,
309 kUserRequested);
310 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time2,
311 kUserRequested);
312
313 QueueRequestsAndChooseOne(request1, request2);
314
315 EXPECT_EQ(kRequestId2, last_picked_->request_id());
316 EXPECT_FALSE(request_queue_not_picked_called_);
317 }
318
319 TEST_F(RequestPickerTest, ChooseNonExpiredRequest) {
320 base::Time creation_time = base::Time::Now();
321 base::Time expired_time =
322 creation_time - base::TimeDelta::FromSeconds(
323 policy_->GetRequestExpirationTimeInSeconds() + 60);
324 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time,
325 kUserRequested);
326 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, expired_time,
327 kUserRequested);
328
329 QueueRequestsAndChooseOne(request1, request2);
330
331 PumpLoop();
332
333 EXPECT_EQ(kRequestId1, last_picked_->request_id());
334 EXPECT_FALSE(request_queue_not_picked_called_);
335 EXPECT_EQ(kRequestId2, GetNotifier()->last_expired_request().request_id());
336 EXPECT_EQ(RequestNotifier::BackgroundSavePageResult::EXPIRED,
337 GetNotifier()->last_request_expiration_status());
338 EXPECT_EQ(1, GetNotifier()->total_expired_requests());
339 }
340
341 TEST_F(RequestPickerTest, ChooseRequestThatHasNotExceededStartLimit) {
342 base::Time creation_time1 =
343 base::Time::Now() - base::TimeDelta::FromSeconds(1);
344 base::Time creation_time2 = base::Time::Now();
345 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time1,
346 kUserRequested);
347 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time2,
348 kUserRequested);
349
350 // With default policy settings, we should choose the earlier request.
351 // However, we will make the earlier reqeust exceed the limit.
352 request1.set_started_attempt_count(policy_->GetMaxStartedTries());
353
354 QueueRequestsAndChooseOne(request1, request2);
355
356 EXPECT_EQ(kRequestId2, last_picked_->request_id());
357 EXPECT_FALSE(request_queue_not_picked_called_);
358 }
359
360 TEST_F(RequestPickerTest, ChooseRequestThatHasNotExceededCompletionLimit) {
361 base::Time creation_time1 =
362 base::Time::Now() - base::TimeDelta::FromSeconds(1);
363 base::Time creation_time2 = base::Time::Now();
364 SavePageRequest request1(kRequestId1, kUrl1, kClientId1, creation_time1,
365 kUserRequested);
366 SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time2,
367 kUserRequested);
368
369 // With default policy settings, we should choose the earlier request.
370 // However, we will make the earlier reqeust exceed the limit.
371 request1.set_completed_attempt_count(policy_->GetMaxCompletedTries());
372
373 QueueRequestsAndChooseOne(request1, request2);
374
375 EXPECT_EQ(kRequestId2, last_picked_->request_id());
376 EXPECT_FALSE(request_queue_not_picked_called_);
377 }
378
379
380 TEST_F(RequestPickerTest, ChooseRequestThatIsNotDisabled) {
381 policy_.reset(new OfflinerPolicy(
382 kPreferUntried, kPreferEarlier, kPreferRetryCount, kMaxStartedTries,
383 kMaxCompletedTries + 1, kBackgroundProcessingTimeBudgetSeconds));
384 picker_.reset(new RequestPicker(queue_.get(), policy_.get(), notifier_.get(),
385 &event_logger_));
386
387 base::Time creation_time = base::Time::Now();
388 SavePageRequest request1(
389 kRequestId1, kUrl1, kClientId1, creation_time, kUserRequested);
390 SavePageRequest request2(
391 kRequestId2, kUrl2, kClientId2, creation_time, kUserRequested);
392 request2.set_completed_attempt_count(kAttemptCount);
393
394 // put request 2 on disabled list, ensure request1 picked instead,
395 // even though policy would prefer 2.
396 std::set<int64_t> disabled_requests {kRequestId2};
397 DeviceConditions conditions;
398
399 // Add test requests on the Queue.
400 queue_->AddRequest(request1, base::Bind(&RequestPickerTest::AddRequestDone,
401 base::Unretained(this)));
402 queue_->AddRequest(request2, base::Bind(&RequestPickerTest::AddRequestDone,
403 base::Unretained(this)));
404
405 // Pump the loop to give the async queue the opportunity to do the adds.
406 PumpLoop();
407
408 // Call the method under test.
409 picker_->ChooseNextRequest(
410 base::Bind(&RequestPickerTest::RequestPicked, base::Unretained(this)),
411 base::Bind(&RequestPickerTest::RequestNotPicked, base::Unretained(this)),
412 &conditions, disabled_requests);
413
414 // Pump the loop again to give the async queue the opportunity to return
415 // results from the Get operation, and for the picker to call the "picked"
416 // callback.
417 PumpLoop();
418
419 EXPECT_EQ(kRequestId1, last_picked_->request_id());
420 EXPECT_FALSE(request_queue_not_picked_called_);
421 }
422 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/background/request_picker.cc ('k') | components/offline_pages/background/request_queue.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698