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

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: Merge with pre-render single instance changes. 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
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 skip_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 (!skip_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 set_skip_callback(bool skip) {
83 skip_callback_ = skip; 92 skip_callback_ = skip;
84 } 93 }
85 94
86 private: 95 private:
96 CompletionCallback callback_;
97 SavePageRequest request_;
87 bool skip_callback_; 98 bool skip_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 SkipOfflinerCallback() {
dougarnett 2016/06/23 17:19:17 consider whether changing to stub to not auto call
Pete Williamson 2016/06/23 17:54:54 Changed to EnableOfflinerCallback(bool enable); An
149 offliner_->set_skip_callback(true); 163 offliner_->set_skip_callback(true);
150 } 164 }
151 165
166 Offliner::RequestStatus last_offlining_status() const {
167 return coordinator_->last_offlining_status_;
168 }
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 SkipOfflinerCallback();
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 coordinator()->queue()->GetRequests( 340 coordinator()->queue()->GetRequests(
324 base::Bind(&RequestCoordinatorTest::GetRequestsDone, 341 base::Bind(&RequestCoordinatorTest::GetRequestsDone,
325 base::Unretained(this))); 342 base::Unretained(this)));
326 PumpLoop(); 343 PumpLoop();
327 344
328 // Still one request in the queue. 345 // Still one request in the queue.
329 EXPECT_EQ(1UL, last_requests().size()); 346 EXPECT_EQ(1UL, last_requests().size());
330 // TODO(dougarnett): Verify retry count gets incremented. 347 // TODO(dougarnett): Verify retry count gets incremented.
331 } 348 }
332 349
350 // This tests a StopProcessing call before we have actually started the
351 // prerenderer.
352 TEST_F(RequestCoordinatorTest, StartProcessingThenStopProcessingImmediately) {
353 // Add a request to the queue, wait for callbacks to finish.
354 offline_pages::SavePageRequest request(
355 kRequestId, kUrl, kClientId, base::Time::Now());
356 coordinator()->queue()->AddRequest(
357 request,
358 base::Bind(&RequestCoordinatorTest::AddRequestDone,
359 base::Unretained(this)));
360 PumpLoop();
361
362 DeviceConditions device_conditions(false, 75,
363 net::NetworkChangeNotifier::CONNECTION_3G);
364 base::Callback<void(bool)> callback =
365 base::Bind(
366 &RequestCoordinatorTest::EmptyCallbackFunction,
367 base::Unretained(this));
368 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
369
370 // Now, quick, before it can do much (we haven't called PumpLoop), cancel it.
371 coordinator()->StopProcessing();
372
373 // Let the async callbacks in the request coordinator run.
374 PumpLoop();
375
376 // OfflinerDoneCallback will not end up getting called with status SAVED,
377 // Since we cancelled the event before it called offliner_->LoadAndSave().
378 EXPECT_NE(Offliner::RequestStatus::SAVED, last_offlining_status());
379 }
380
381 // This tests a StopProcessing call after the prerenderer has been started.
382 TEST_F(RequestCoordinatorTest, StartProcessingThenStopProcessingLater) {
383 // Add a request to the queue, wait for callbacks to finish.
384 offline_pages::SavePageRequest request(
385 kRequestId, kUrl, kClientId, base::Time::Now());
386 coordinator()->queue()->AddRequest(
387 request,
388 base::Bind(&RequestCoordinatorTest::AddRequestDone,
389 base::Unretained(this)));
390 PumpLoop();
391
392 // Ensure the start processing request stops before the completion callback.
393 SkipOfflinerCallback();
394
395 DeviceConditions device_conditions(false, 75,
396 net::NetworkChangeNotifier::CONNECTION_3G);
397 base::Callback<void(bool)> callback =
398 base::Bind(
399 &RequestCoordinatorTest::EmptyCallbackFunction,
400 base::Unretained(this));
401 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback));
402
403 // Let all the async parts of the start processing pipeline run to completion.
404 PumpLoop();
405
406 // Now we cancel it while the prerenderer is busy.
407 coordinator()->StopProcessing();
408
409 // Let the async callbacks in the cancel run.
410 PumpLoop();
411
412 // OfflinerDoneCallback will not end up getting called with status SAVED,
413 // Since we cancelled the event before it called offliner_->LoadAndSave().
414 EXPECT_EQ(Offliner::RequestStatus::CANCELED, last_offlining_status());
415 }
416
333 } // namespace offline_pages 417 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698