| OLD | NEW |
| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" |
| 13 #include "base/test/test_simple_task_runner.h" | 14 #include "base/test/test_simple_task_runner.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "components/offline_pages/background/device_conditions.h" | 16 #include "components/offline_pages/background/device_conditions.h" |
| 16 #include "components/offline_pages/background/offliner.h" | 17 #include "components/offline_pages/background/offliner.h" |
| 17 #include "components/offline_pages/background/offliner_factory.h" | 18 #include "components/offline_pages/background/offliner_factory.h" |
| 18 #include "components/offline_pages/background/offliner_policy.h" | 19 #include "components/offline_pages/background/offliner_policy.h" |
| 19 #include "components/offline_pages/background/request_queue.h" | 20 #include "components/offline_pages/background/request_queue.h" |
| 20 #include "components/offline_pages/background/request_queue_in_memory_store.h" | 21 #include "components/offline_pages/background/request_queue_in_memory_store.h" |
| 21 #include "components/offline_pages/background/save_page_request.h" | 22 #include "components/offline_pages/background/save_page_request.h" |
| 22 #include "components/offline_pages/background/scheduler.h" | 23 #include "components/offline_pages/background/scheduler.h" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 47 bool schedule_called() const { return schedule_called_; } | 48 bool schedule_called() const { return schedule_called_; } |
| 48 | 49 |
| 49 bool unschedule_called() const { return unschedule_called_; } | 50 bool unschedule_called() const { return unschedule_called_; } |
| 50 | 51 |
| 51 private: | 52 private: |
| 52 bool schedule_called_; | 53 bool schedule_called_; |
| 53 bool unschedule_called_; | 54 bool unschedule_called_; |
| 54 }; | 55 }; |
| 55 | 56 |
| 56 class OfflinerStub : public Offliner { | 57 class OfflinerStub : public Offliner { |
| 58 public: |
| 59 OfflinerStub() : skip_callback_(false) {} |
| 60 |
| 57 bool LoadAndSave(const SavePageRequest& request, | 61 bool LoadAndSave(const SavePageRequest& request, |
| 58 const CompletionCallback& callback) override { | 62 const CompletionCallback& callback) override { |
| 59 // Post the callback on the run loop. | 63 // Post the callback on the run loop. |
| 60 base::ThreadTaskRunnerHandle::Get()->PostTask( | 64 if (!skip_callback_) { |
| 61 FROM_HERE, | 65 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 62 base::Bind(callback, request, Offliner::RequestStatus::SAVED)); | 66 FROM_HERE, |
| 67 base::Bind(callback, request, Offliner::RequestStatus::SAVED)); |
| 68 } |
| 63 return true; | 69 return true; |
| 64 } | 70 } |
| 65 | 71 |
| 66 // Clears the currently processing request, if any. | 72 // Clears the currently processing request, if any. |
| 67 void Cancel() override {} | 73 void Cancel() override {} |
| 74 |
| 75 void set_skip_callback(bool skip) { |
| 76 skip_callback_ = skip; |
| 77 } |
| 78 |
| 79 private: |
| 80 bool skip_callback_; |
| 68 }; | 81 }; |
| 69 | 82 |
| 70 class OfflinerFactoryStub : public OfflinerFactory { | 83 class OfflinerFactoryStub : public OfflinerFactory { |
| 71 public: | 84 public: |
| 72 Offliner* GetOffliner(const OfflinerPolicy* policy) override { | 85 Offliner* GetOffliner(const OfflinerPolicy* policy) override { |
| 73 offliner_.reset(new OfflinerStub()); | 86 if (offliner_.get() == nullptr) { |
| 87 offliner_.reset(new OfflinerStub()); |
| 88 } |
| 74 return offliner_.get(); | 89 return offliner_.get(); |
| 75 } | 90 } |
| 76 | 91 |
| 77 private: | 92 private: |
| 78 std::unique_ptr<Offliner> offliner_; | 93 std::unique_ptr<Offliner> offliner_; |
| 79 }; | 94 }; |
| 80 | 95 |
| 81 class RequestCoordinatorTest | 96 class RequestCoordinatorTest |
| 82 : public testing::Test { | 97 : public testing::Test { |
| 83 public: | 98 public: |
| 84 RequestCoordinatorTest(); | 99 RequestCoordinatorTest(); |
| 85 ~RequestCoordinatorTest() override; | 100 ~RequestCoordinatorTest() override; |
| 86 | 101 |
| 87 void SetUp() override; | 102 void SetUp() override; |
| 88 | 103 |
| 89 void PumpLoop(); | 104 void PumpLoop(); |
| 90 | 105 |
| 91 RequestCoordinator* coordinator() { | 106 RequestCoordinator* coordinator() { |
| 92 return coordinator_.get(); | 107 return coordinator_.get(); |
| 93 } | 108 } |
| 94 | 109 |
| 110 bool is_busy() { |
| 111 return coordinator_->is_busy(); |
| 112 } |
| 113 |
| 114 void SendRequestToOffliner(SavePageRequest& request) { |
| 115 coordinator_->SendRequestToOffliner(request); |
| 116 } |
| 117 |
| 95 // Empty callback function | 118 // Empty callback function |
| 96 void EmptyCallbackFunction(bool result) { | 119 void EmptyCallbackFunction(bool result) { |
| 97 } | 120 } |
| 98 | 121 |
| 99 // Callback for Add requests | 122 // Callback for Add requests |
| 100 void AddRequestDone(RequestQueue::AddRequestResult result, | 123 void AddRequestDone(RequestQueue::AddRequestResult result, |
| 101 const SavePageRequest& request); | 124 const SavePageRequest& request); |
| 102 | 125 |
| 103 // Callback for getting requests. | 126 // Callback for getting requests. |
| 104 void GetRequestsDone(RequestQueue::GetRequestsResult result, | 127 void GetRequestsDone(RequestQueue::GetRequestsResult result, |
| 105 const std::vector<SavePageRequest>& requests); | 128 const std::vector<SavePageRequest>& requests); |
| 106 | 129 |
| 107 void SendOfflinerDoneCallback(const SavePageRequest& request, | 130 void SendOfflinerDoneCallback(const SavePageRequest& request, |
| 108 Offliner::RequestStatus status); | 131 Offliner::RequestStatus status); |
| 109 | 132 |
| 110 RequestQueue::GetRequestsResult last_get_requests_result() const { | 133 RequestQueue::GetRequestsResult last_get_requests_result() const { |
| 111 return last_get_requests_result_; | 134 return last_get_requests_result_; |
| 112 } | 135 } |
| 113 | 136 |
| 114 const std::vector<SavePageRequest>& last_requests() const { | 137 const std::vector<SavePageRequest>& last_requests() const { |
| 115 return last_requests_; | 138 return last_requests_; |
| 116 } | 139 } |
| 117 | 140 |
| 141 void skip_offliner_callback() { |
| 142 offliner_->set_skip_callback(true); |
| 143 } |
| 144 |
| 118 private: | 145 private: |
| 119 RequestQueue::GetRequestsResult last_get_requests_result_; | 146 RequestQueue::GetRequestsResult last_get_requests_result_; |
| 120 std::vector<SavePageRequest> last_requests_; | 147 std::vector<SavePageRequest> last_requests_; |
| 121 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 148 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 122 base::ThreadTaskRunnerHandle task_runner_handle_; | 149 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 123 std::unique_ptr<RequestCoordinator> coordinator_; | 150 std::unique_ptr<RequestCoordinator> coordinator_; |
| 151 OfflinerStub* offliner_; |
| 124 }; | 152 }; |
| 125 | 153 |
| 126 RequestCoordinatorTest::RequestCoordinatorTest() | 154 RequestCoordinatorTest::RequestCoordinatorTest() |
| 127 : last_get_requests_result_(RequestQueue::GetRequestsResult::STORE_FAILURE), | 155 : last_get_requests_result_(RequestQueue::GetRequestsResult::STORE_FAILURE), |
| 128 task_runner_(new base::TestSimpleTaskRunner), | 156 task_runner_(new base::TestSimpleTaskRunner), |
| 129 task_runner_handle_(task_runner_) {} | 157 task_runner_handle_(task_runner_), |
| 158 offliner_(nullptr) {} |
| 130 | 159 |
| 131 RequestCoordinatorTest::~RequestCoordinatorTest() {} | 160 RequestCoordinatorTest::~RequestCoordinatorTest() {} |
| 132 | 161 |
| 133 void RequestCoordinatorTest::SetUp() { | 162 void RequestCoordinatorTest::SetUp() { |
| 134 std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); | 163 std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); |
| 135 std::unique_ptr<OfflinerFactory> factory(new OfflinerFactoryStub()); | 164 std::unique_ptr<OfflinerFactory> factory(new OfflinerFactoryStub()); |
| 165 offliner_ = |
| 166 reinterpret_cast<OfflinerStub*>(factory->GetOffliner(policy.get())); |
| 136 std::unique_ptr<RequestQueueInMemoryStore> | 167 std::unique_ptr<RequestQueueInMemoryStore> |
| 137 store(new RequestQueueInMemoryStore()); | 168 store(new RequestQueueInMemoryStore()); |
| 138 std::unique_ptr<RequestQueue> queue(new RequestQueue(std::move(store))); | 169 std::unique_ptr<RequestQueue> queue(new RequestQueue(std::move(store))); |
| 139 std::unique_ptr<Scheduler> scheduler_stub(new SchedulerStub()); | 170 std::unique_ptr<Scheduler> scheduler_stub(new SchedulerStub()); |
| 140 coordinator_.reset(new RequestCoordinator( | 171 coordinator_.reset(new RequestCoordinator( |
| 141 std::move(policy), std::move(factory), std::move(queue), | 172 std::move(policy), std::move(factory), std::move(queue), |
| 142 std::move(scheduler_stub))); | 173 std::move(scheduler_stub))); |
| 143 } | 174 } |
| 144 | 175 |
| 145 void RequestCoordinatorTest::PumpLoop() { | 176 void RequestCoordinatorTest::PumpLoop() { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 168 TEST_F(RequestCoordinatorTest, StartProcessingWithNoRequests) { | 199 TEST_F(RequestCoordinatorTest, StartProcessingWithNoRequests) { |
| 169 DeviceConditions device_conditions(false, 75, | 200 DeviceConditions device_conditions(false, 75, |
| 170 net::NetworkChangeNotifier::CONNECTION_3G); | 201 net::NetworkChangeNotifier::CONNECTION_3G); |
| 171 base::Callback<void(bool)> callback = | 202 base::Callback<void(bool)> callback = |
| 172 base::Bind( | 203 base::Bind( |
| 173 &RequestCoordinatorTest::EmptyCallbackFunction, | 204 &RequestCoordinatorTest::EmptyCallbackFunction, |
| 174 base::Unretained(this)); | 205 base::Unretained(this)); |
| 175 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); | 206 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); |
| 176 } | 207 } |
| 177 | 208 |
| 209 TEST_F(RequestCoordinatorTest, StartProcessingWithRequestInProgress) { |
| 210 // Put the request on the queue. |
| 211 EXPECT_TRUE(coordinator()->SavePageLater(kUrl, kClientId)); |
| 212 |
| 213 // Set up for the call to StartProcessing by building arguments. |
| 214 DeviceConditions device_conditions(false, 75, |
| 215 net::NetworkChangeNotifier::CONNECTION_3G); |
| 216 base::Callback<void(bool)> callback = |
| 217 base::Bind(&RequestCoordinatorTest::EmptyCallbackFunction, |
| 218 base::Unretained(this)); |
| 219 |
| 220 // Ensure that the forthcoming request does not finish - we simulate it being |
| 221 // in progress by asking it to skip making the completion callback. |
| 222 skip_offliner_callback(); |
| 223 |
| 224 // Sending the request to the offliner should make it busy. |
| 225 EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); |
| 226 PumpLoop(); |
| 227 EXPECT_TRUE(is_busy()); |
| 228 |
| 229 // Now trying to start processing on another request should return false. |
| 230 EXPECT_FALSE(coordinator()->StartProcessing(device_conditions, callback)); |
| 231 } |
| 232 |
| 178 TEST_F(RequestCoordinatorTest, SavePageLater) { | 233 TEST_F(RequestCoordinatorTest, SavePageLater) { |
| 179 EXPECT_TRUE(coordinator()->SavePageLater(kUrl, kClientId)); | 234 EXPECT_TRUE(coordinator()->SavePageLater(kUrl, kClientId)); |
| 180 | 235 |
| 181 // Expect that a request got placed on the queue. | 236 // Expect that a request got placed on the queue. |
| 182 coordinator()->queue()->GetRequests( | 237 coordinator()->queue()->GetRequests( |
| 183 base::Bind(&RequestCoordinatorTest::GetRequestsDone, | 238 base::Bind(&RequestCoordinatorTest::GetRequestsDone, |
| 184 base::Unretained(this))); | 239 base::Unretained(this))); |
| 185 | 240 |
| 186 // Wait for callbacks to finish, both request queue and offliner. | 241 // Wait for callbacks to finish, both request queue and offliner. |
| 187 PumpLoop(); | 242 PumpLoop(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 base::Bind(&RequestCoordinatorTest::GetRequestsDone, | 313 base::Bind(&RequestCoordinatorTest::GetRequestsDone, |
| 259 base::Unretained(this))); | 314 base::Unretained(this))); |
| 260 PumpLoop(); | 315 PumpLoop(); |
| 261 | 316 |
| 262 // Still one request in the queue. | 317 // Still one request in the queue. |
| 263 EXPECT_EQ(1UL, last_requests().size()); | 318 EXPECT_EQ(1UL, last_requests().size()); |
| 264 // TODO(dougarnett): Verify retry count gets incremented. | 319 // TODO(dougarnett): Verify retry count gets incremented. |
| 265 } | 320 } |
| 266 | 321 |
| 267 } // namespace offline_pages | 322 } // namespace offline_pages |
| OLD | NEW |