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

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

Issue 2091473004: Add the ability to cancel prerender reqeusts and tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment changes per DougArnett Created 4 years, 6 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
« no previous file with comments | « components/offline_pages/background/request_coordinator.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/offline_pages/background/request_coordinator.h" 5 #include "components/offline_pages/background/request_coordinator.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 TriggerConditions const* conditions() const { return &conditions_; } 56 TriggerConditions const* conditions() const { return &conditions_; }
57 57
58 private: 58 private:
59 bool schedule_called_; 59 bool schedule_called_;
60 bool unschedule_called_; 60 bool unschedule_called_;
61 TriggerConditions conditions_; 61 TriggerConditions conditions_;
62 }; 62 };
63 63
64 class OfflinerStub : public Offliner { 64 class OfflinerStub : public Offliner {
65 public: 65 public:
66 OfflinerStub() : skip_callback_(false) {} 66 OfflinerStub() : request_(kRequestId, kUrl, kClientId, base::Time::Now()),
67 enable_callback_(false) {}
67 68
68 bool LoadAndSave(const SavePageRequest& request, 69 bool LoadAndSave(const SavePageRequest& request,
69 const CompletionCallback& callback) override { 70 const CompletionCallback& callback) override {
71 callback_ = callback;
72 request_ = request;
70 // Post the callback on the run loop. 73 // Post the callback on the run loop.
71 if (!skip_callback_) { 74 if (enable_callback_) {
72 base::ThreadTaskRunnerHandle::Get()->PostTask( 75 base::ThreadTaskRunnerHandle::Get()->PostTask(
73 FROM_HERE, 76 FROM_HERE,
74 base::Bind(callback, request, Offliner::RequestStatus::SAVED)); 77 base::Bind(callback, request, Offliner::RequestStatus::SAVED));
75 } 78 }
76 return true; 79 return true;
77 } 80 }
78 81
82 // Clears the currently processing request, if any. Must have called
83 // LoadAndSave first to set the callback and request.
79 // Clears the currently processing request, if any. 84 // Clears the currently processing request, if any.
80 void Cancel() override {} 85 void Cancel() override {
86 base::ThreadTaskRunnerHandle::Get()->PostTask(
87 FROM_HERE,
88 base::Bind(callback_, request_, Offliner::RequestStatus::CANCELED));
89 }
81 90
82 void set_skip_callback(bool skip) { 91 void enable_callback(bool enable) {
83 skip_callback_ = skip; 92 enable_callback_ = enable;
84 } 93 }
85 94
86 private: 95 private:
87 bool skip_callback_; 96 CompletionCallback callback_;
97 SavePageRequest request_;
98 bool enable_callback_;
88 }; 99 };
89 100
90 class OfflinerFactoryStub : public OfflinerFactory { 101 class OfflinerFactoryStub : public OfflinerFactory {
91 public: 102 public:
103
104 OfflinerFactoryStub() : offliner_(nullptr) {}
105
92 Offliner* GetOffliner(const OfflinerPolicy* policy) override { 106 Offliner* GetOffliner(const OfflinerPolicy* policy) override {
93 if (offliner_.get() == nullptr) { 107 if (offliner_.get() == nullptr) {
94 offliner_.reset(new OfflinerStub()); 108 offliner_.reset(new OfflinerStub());
95 } 109 }
96 return offliner_.get(); 110 return offliner_.get();
97 } 111 }
98 112
99 private: 113 private:
100 std::unique_ptr<Offliner> offliner_; 114 std::unique_ptr<OfflinerStub> offliner_;
101 }; 115 };
102 116
103 class RequestCoordinatorTest 117 class RequestCoordinatorTest
104 : public testing::Test { 118 : public testing::Test {
105 public: 119 public:
106 RequestCoordinatorTest(); 120 RequestCoordinatorTest();
107 ~RequestCoordinatorTest() override; 121 ~RequestCoordinatorTest() override;
108 122
109 void SetUp() override; 123 void SetUp() override;
110 124
(...skipping 27 matching lines...) Expand all
138 Offliner::RequestStatus status); 152 Offliner::RequestStatus status);
139 153
140 RequestQueue::GetRequestsResult last_get_requests_result() const { 154 RequestQueue::GetRequestsResult last_get_requests_result() const {
141 return last_get_requests_result_; 155 return last_get_requests_result_;
142 } 156 }
143 157
144 const std::vector<SavePageRequest>& last_requests() const { 158 const std::vector<SavePageRequest>& last_requests() const {
145 return last_requests_; 159 return last_requests_;
146 } 160 }
147 161
148 void skip_offliner_callback() { 162 void EnableOfflinerCallback(bool enable) {
149 offliner_->set_skip_callback(true); 163 offliner_->enable_callback(enable);
164 }
165
166 Offliner::RequestStatus last_offlining_status() const {
167 return coordinator_->last_offlining_status_;
150 } 168 }
151 169
152 private: 170 private:
153 RequestQueue::GetRequestsResult last_get_requests_result_; 171 RequestQueue::GetRequestsResult last_get_requests_result_;
154 std::vector<SavePageRequest> last_requests_; 172 std::vector<SavePageRequest> last_requests_;
155 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 173 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
156 base::ThreadTaskRunnerHandle task_runner_handle_; 174 base::ThreadTaskRunnerHandle task_runner_handle_;
157 std::unique_ptr<RequestCoordinator> coordinator_; 175 std::unique_ptr<RequestCoordinator> coordinator_;
158 OfflinerStub* offliner_; 176 OfflinerStub* offliner_;
159 }; 177 };
160 178
161 RequestCoordinatorTest::RequestCoordinatorTest() 179 RequestCoordinatorTest::RequestCoordinatorTest()
162 : last_get_requests_result_(RequestQueue::GetRequestsResult::STORE_FAILURE), 180 : last_get_requests_result_(RequestQueue::GetRequestsResult::STORE_FAILURE),
163 task_runner_(new base::TestSimpleTaskRunner), 181 task_runner_(new base::TestSimpleTaskRunner),
164 task_runner_handle_(task_runner_), 182 task_runner_handle_(task_runner_),
165 offliner_(nullptr) {} 183 offliner_(nullptr) {}
166 184
167 RequestCoordinatorTest::~RequestCoordinatorTest() {} 185 RequestCoordinatorTest::~RequestCoordinatorTest() {}
168 186
169 void RequestCoordinatorTest::SetUp() { 187 void RequestCoordinatorTest::SetUp() {
170 std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); 188 std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy());
171 std::unique_ptr<OfflinerFactory> factory(new OfflinerFactoryStub()); 189 std::unique_ptr<OfflinerFactory> factory(new OfflinerFactoryStub());
190 // Save the offliner for use by the tests.
172 offliner_ = 191 offliner_ =
173 reinterpret_cast<OfflinerStub*>(factory->GetOffliner(policy.get())); 192 reinterpret_cast<OfflinerStub*>(factory->GetOffliner(policy.get()));
174 std::unique_ptr<RequestQueueInMemoryStore> 193 std::unique_ptr<RequestQueueInMemoryStore>
175 store(new RequestQueueInMemoryStore()); 194 store(new RequestQueueInMemoryStore());
176 std::unique_ptr<RequestQueue> queue(new RequestQueue(std::move(store))); 195 std::unique_ptr<RequestQueue> queue(new RequestQueue(std::move(store)));
177 std::unique_ptr<Scheduler> scheduler_stub(new SchedulerStub()); 196 std::unique_ptr<Scheduler> scheduler_stub(new SchedulerStub());
178 coordinator_.reset(new RequestCoordinator( 197 coordinator_.reset(new RequestCoordinator(
179 std::move(policy), std::move(factory), std::move(queue), 198 std::move(policy), std::move(factory), std::move(queue),
180 std::move(scheduler_stub))); 199 std::move(scheduler_stub)));
181 } 200 }
182 201
183 void RequestCoordinatorTest::PumpLoop() { 202 void RequestCoordinatorTest::PumpLoop() {
184 task_runner_->RunUntilIdle(); 203 task_runner_->RunUntilIdle();
185 } 204 }
186 205
187 void RequestCoordinatorTest::GetRequestsDone( 206 void RequestCoordinatorTest::GetRequestsDone(
188 RequestQueue::GetRequestsResult result, 207 RequestQueue::GetRequestsResult result,
189 const std::vector<SavePageRequest>& requests) { 208 const std::vector<SavePageRequest>& requests) {
190 last_get_requests_result_ = result; 209 last_get_requests_result_ = result;
191 last_requests_ = requests; 210 last_requests_ = requests;
192 } 211 }
193 212
194
195 void RequestCoordinatorTest::AddRequestDone( 213 void RequestCoordinatorTest::AddRequestDone(
196 RequestQueue::AddRequestResult result, 214 RequestQueue::AddRequestResult result,
197 const SavePageRequest& request) {} 215 const SavePageRequest& request) {}
198 216
199 void RequestCoordinatorTest::SendOfflinerDoneCallback( 217 void RequestCoordinatorTest::SendOfflinerDoneCallback(
200 const SavePageRequest& request, Offliner::RequestStatus status) { 218 const SavePageRequest& request, Offliner::RequestStatus status) {
201 // Using the fact that the test class is a friend, call to the callback 219 // Using the fact that the test class is a friend, call to the callback
202 coordinator_->OfflinerDoneCallback(request, status); 220 coordinator_->OfflinerDoneCallback(request, status);
203 } 221 }
204 222
205
206 TEST_F(RequestCoordinatorTest, StartProcessingWithNoRequests) { 223 TEST_F(RequestCoordinatorTest, StartProcessingWithNoRequests) {
207 DeviceConditions device_conditions(false, 75, 224 DeviceConditions device_conditions(false, 75,
208 net::NetworkChangeNotifier::CONNECTION_3G); 225 net::NetworkChangeNotifier::CONNECTION_3G);
209 base::Callback<void(bool)> callback = 226 base::Callback<void(bool)> callback =
210 base::Bind( 227 base::Bind(
211 &RequestCoordinatorTest::EmptyCallbackFunction, 228 &RequestCoordinatorTest::EmptyCallbackFunction,
212 base::Unretained(this)); 229 base::Unretained(this));
213 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); 230 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
214 } 231 }
215 232
216 TEST_F(RequestCoordinatorTest, StartProcessingWithRequestInProgress) { 233 TEST_F(RequestCoordinatorTest, StartProcessingWithRequestInProgress) {
217 // Put the request on the queue. 234 // Put the request on the queue.
218 EXPECT_TRUE(coordinator()->SavePageLater(kUrl, kClientId)); 235 EXPECT_TRUE(coordinator()->SavePageLater(kUrl, kClientId));
219 236
220 // Set up for the call to StartProcessing by building arguments. 237 // Set up for the call to StartProcessing by building arguments.
221 DeviceConditions device_conditions(false, 75, 238 DeviceConditions device_conditions(false, 75,
222 net::NetworkChangeNotifier::CONNECTION_3G); 239 net::NetworkChangeNotifier::CONNECTION_3G);
223 base::Callback<void(bool)> callback = 240 base::Callback<void(bool)> callback =
224 base::Bind(&RequestCoordinatorTest::EmptyCallbackFunction, 241 base::Bind(&RequestCoordinatorTest::EmptyCallbackFunction,
225 base::Unretained(this)); 242 base::Unretained(this));
226 243
227 // Ensure that the forthcoming request does not finish - we simulate it being 244 // Ensure that the forthcoming request does not finish - we simulate it being
228 // in progress by asking it to skip making the completion callback. 245 // in progress by asking it to skip making the completion callback.
229 skip_offliner_callback(); 246 EnableOfflinerCallback(false);
230 247
231 // Sending the request to the offliner should make it busy. 248 // Sending the request to the offliner should make it busy.
232 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); 249 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
233 PumpLoop(); 250 PumpLoop();
234 EXPECT_TRUE(is_busy()); 251 EXPECT_TRUE(is_busy());
235 252
236 // Now trying to start processing on another request should return false. 253 // Now trying to start processing on another request should return false.
237 EXPECT_FALSE(coordinator()->StartProcessing(device_conditions, callback)); 254 EXPECT_FALSE(coordinator()->StartProcessing(device_conditions, callback));
238 } 255 }
239 256
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 292
276 // We need to give a callback to the request. 293 // We need to give a callback to the request.
277 base::Callback<void(bool)> callback = 294 base::Callback<void(bool)> callback =
278 base::Bind( 295 base::Bind(
279 &RequestCoordinatorTest::EmptyCallbackFunction, 296 &RequestCoordinatorTest::EmptyCallbackFunction,
280 base::Unretained(this)); 297 base::Unretained(this));
281 coordinator()->SetProcessingCallbackForTest(callback); 298 coordinator()->SetProcessingCallbackForTest(callback);
282 299
283 // Call the OfflinerDoneCallback to simulate the page being completed, wait 300 // Call the OfflinerDoneCallback to simulate the page being completed, wait
284 // for callbacks. 301 // for callbacks.
302 EnableOfflinerCallback(true);
285 SendOfflinerDoneCallback(request, Offliner::RequestStatus::SAVED); 303 SendOfflinerDoneCallback(request, Offliner::RequestStatus::SAVED);
286 PumpLoop(); 304 PumpLoop();
287 305
288 // Verify the request gets removed from the queue, and wait for callbacks. 306 // Verify the request gets removed from the queue, and wait for callbacks.
289 coordinator()->queue()->GetRequests( 307 coordinator()->queue()->GetRequests(
290 base::Bind(&RequestCoordinatorTest::GetRequestsDone, 308 base::Bind(&RequestCoordinatorTest::GetRequestsDone,
291 base::Unretained(this))); 309 base::Unretained(this)));
292 PumpLoop(); 310 PumpLoop();
293 311
294 // We should not find any requests in the queue anymore. 312 // We should not find any requests in the queue anymore.
(...skipping 14 matching lines...) Expand all
309 327
310 // We need to give a callback to the request. 328 // We need to give a callback to the request.
311 base::Callback<void(bool)> callback = 329 base::Callback<void(bool)> callback =
312 base::Bind( 330 base::Bind(
313 &RequestCoordinatorTest::EmptyCallbackFunction, 331 &RequestCoordinatorTest::EmptyCallbackFunction,
314 base::Unretained(this)); 332 base::Unretained(this));
315 coordinator()->SetProcessingCallbackForTest(callback); 333 coordinator()->SetProcessingCallbackForTest(callback);
316 334
317 // Call the OfflinerDoneCallback to simulate the request failed, wait 335 // Call the OfflinerDoneCallback to simulate the request failed, wait
318 // for callbacks. 336 // for callbacks.
337 EnableOfflinerCallback(true);
319 SendOfflinerDoneCallback(request, Offliner::RequestStatus::FAILED); 338 SendOfflinerDoneCallback(request, Offliner::RequestStatus::FAILED);
320 PumpLoop(); 339 PumpLoop();
321 340
322 // Verify the request is not removed from the queue, and wait for callbacks. 341 // Verify the request is not removed from the queue, and wait for callbacks.
323 coordinator()->queue()->GetRequests( 342 coordinator()->queue()->GetRequests(
324 base::Bind(&RequestCoordinatorTest::GetRequestsDone, 343 base::Bind(&RequestCoordinatorTest::GetRequestsDone,
325 base::Unretained(this))); 344 base::Unretained(this)));
326 PumpLoop(); 345 PumpLoop();
327 346
328 // Still one request in the queue. 347 // Still one request in the queue.
329 EXPECT_EQ(1UL, last_requests().size()); 348 EXPECT_EQ(1UL, last_requests().size());
330 // TODO(dougarnett): Verify retry count gets incremented. 349 // TODO(dougarnett): Verify retry count gets incremented.
331 } 350 }
332 351
352 // This tests a StopProcessing call before we have actually started the
353 // prerenderer.
354 TEST_F(RequestCoordinatorTest, StartProcessingThenStopProcessingImmediately) {
355 // Add a request to the queue, wait for callbacks to finish.
356 offline_pages::SavePageRequest request(
357 kRequestId, kUrl, kClientId, base::Time::Now());
358 coordinator()->queue()->AddRequest(
359 request,
360 base::Bind(&RequestCoordinatorTest::AddRequestDone,
361 base::Unretained(this)));
362 PumpLoop();
363
364 DeviceConditions device_conditions(false, 75,
365 net::NetworkChangeNotifier::CONNECTION_3G);
366 base::Callback<void(bool)> callback =
367 base::Bind(
368 &RequestCoordinatorTest::EmptyCallbackFunction,
369 base::Unretained(this));
370 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
371
372 // Now, quick, before it can do much (we haven't called PumpLoop), cancel it.
373 coordinator()->StopProcessing();
374
375 // Let the async callbacks in the request coordinator run.
376 PumpLoop();
377
378 // OfflinerDoneCallback will not end up getting called with status SAVED,
379 // Since we cancelled the event before it called offliner_->LoadAndSave().
380 EXPECT_NE(Offliner::RequestStatus::SAVED, last_offlining_status());
381 }
382
383 // This tests a StopProcessing call after the prerenderer has been started.
384 TEST_F(RequestCoordinatorTest, StartProcessingThenStopProcessingLater) {
385 // Add a request to the queue, wait for callbacks to finish.
386 offline_pages::SavePageRequest request(
387 kRequestId, kUrl, kClientId, base::Time::Now());
388 coordinator()->queue()->AddRequest(
389 request,
390 base::Bind(&RequestCoordinatorTest::AddRequestDone,
391 base::Unretained(this)));
392 PumpLoop();
393
394 // Ensure the start processing request stops before the completion callback.
395 EnableOfflinerCallback(false);
396
397 DeviceConditions device_conditions(false, 75,
398 net::NetworkChangeNotifier::CONNECTION_3G);
399 base::Callback<void(bool)> callback =
400 base::Bind(
401 &RequestCoordinatorTest::EmptyCallbackFunction,
402 base::Unretained(this));
403 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
404
405 // Let all the async parts of the start processing pipeline run to completion.
406 PumpLoop();
407
408 // Now we cancel it while the prerenderer is busy.
409 coordinator()->StopProcessing();
410
411 // Let the async callbacks in the cancel run.
412 PumpLoop();
413
414 // OfflinerDoneCallback will not end up getting called with status SAVED,
415 // Since we cancelled the event before it called offliner_->LoadAndSave().
416 EXPECT_EQ(Offliner::RequestStatus::CANCELED, last_offlining_status());
417 }
418
333 } // namespace offline_pages 419 } // namespace offline_pages
OLDNEW
« no previous file with comments | « components/offline_pages/background/request_coordinator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698