| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "content/browser/background_fetch/background_fetch_job_controller.h" | 5 #include "content/browser/background_fetch/background_fetch_job_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <unordered_map> | 9 #include <unordered_map> |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "net/url_request/url_request_context_getter.h" | 23 #include "net/url_request/url_request_context_getter.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
| 25 | 25 |
| 26 using testing::_; | 26 using testing::_; |
| 27 | 27 |
| 28 namespace content { | 28 namespace content { |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 const char kExampleTag[] = "my-example-tag"; | 31 const char kExampleTag[] = "my-example-tag"; |
| 32 | 32 |
| 33 // Use the basic MockDownloadManager, but override it so that it implements the | |
| 34 // functionality that the JobController requires. | |
| 35 class MockDownloadManagerWithCallback : public MockDownloadManager { | |
| 36 public: | |
| 37 MockDownloadManagerWithCallback() = default; | |
| 38 ~MockDownloadManagerWithCallback() override = default; | |
| 39 | |
| 40 void DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override { | |
| 41 DownloadUrlMock(params.get()); | |
| 42 | |
| 43 auto download_item = base::MakeUnique<FakeDownloadItem>(); | |
| 44 download_item->SetState(DownloadItem::DownloadState::IN_PROGRESS); | |
| 45 download_item->SetGuid(base::GenerateGUID()); | |
| 46 | |
| 47 // Post a task to invoke the callback included with the |params|. This is | |
| 48 // done asynchronously to match the semantics of the download manager. | |
| 49 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 50 base::Bind(params->callback(), download_item.get(), | |
| 51 DOWNLOAD_INTERRUPT_REASON_NONE)); | |
| 52 | |
| 53 // Post a task for automatically completing the download item if requested. | |
| 54 if (post_completion_task_enabled_) { | |
| 55 BrowserThread::PostTask( | |
| 56 BrowserThread::IO, FROM_HERE, | |
| 57 base::Bind(&MockDownloadManagerWithCallback::MarkAsCompleted, | |
| 58 base::Unretained(this), download_item.get())); | |
| 59 } | |
| 60 | |
| 61 download_items_.insert( | |
| 62 std::make_pair(download_item->GetGuid(), std::move(download_item))); | |
| 63 } | |
| 64 | |
| 65 DownloadItem* GetDownloadByGuid(const std::string& guid) override { | |
| 66 auto iter = download_items_.find(guid); | |
| 67 if (iter != download_items_.end()) | |
| 68 return iter->second.get(); | |
| 69 | |
| 70 return nullptr; | |
| 71 } | |
| 72 | |
| 73 // Returns a vector with pointers to all downloaded items. The lifetime of the | |
| 74 // returned pointers is scoped to the lifetime of this instance, which will be | |
| 75 // kept alive for the lifetime of the tests. | |
| 76 std::vector<FakeDownloadItem*> GetDownloadItems() { | |
| 77 std::vector<FakeDownloadItem*> download_items; | |
| 78 for (const auto& pair : download_items_) | |
| 79 download_items.push_back(pair.second.get()); | |
| 80 | |
| 81 return download_items; | |
| 82 } | |
| 83 | |
| 84 // Will automatically mark downloads as completing shortly after they start. | |
| 85 void set_post_completion_task_enabled(bool enabled) { | |
| 86 post_completion_task_enabled_ = enabled; | |
| 87 } | |
| 88 | |
| 89 private: | |
| 90 // Marks the |download_item| as having completed. | |
| 91 void MarkAsCompleted(FakeDownloadItem* download_item) { | |
| 92 download_item->SetState(DownloadItem::DownloadState::COMPLETE); | |
| 93 download_item->NotifyDownloadUpdated(); | |
| 94 } | |
| 95 | |
| 96 // All ever-created download items for this manager. Owned by this instance. | |
| 97 std::unordered_map<std::string, std::unique_ptr<FakeDownloadItem>> | |
| 98 download_items_; | |
| 99 | |
| 100 // Whether a task should be posted for automatically marking the download as | |
| 101 // having completed, avoiding complicated spinning for tests that don't care. | |
| 102 bool post_completion_task_enabled_ = false; | |
| 103 | |
| 104 DISALLOW_COPY_AND_ASSIGN(MockDownloadManagerWithCallback); | |
| 105 }; | |
| 106 | |
| 107 class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase { | 33 class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase { |
| 108 public: | 34 public: |
| 109 BackgroundFetchJobControllerTest() | 35 BackgroundFetchJobControllerTest() : data_manager_(browser_context()) {} |
| 110 : data_manager_(browser_context()), download_manager_(nullptr) {} | |
| 111 ~BackgroundFetchJobControllerTest() override = default; | 36 ~BackgroundFetchJobControllerTest() override = default; |
| 112 | 37 |
| 113 void SetUp() override { | |
| 114 BackgroundFetchTestBase::SetUp(); | |
| 115 | |
| 116 download_manager_ = new MockDownloadManagerWithCallback(); | |
| 117 | |
| 118 // The download_manager_ ownership is given to the BrowserContext, and the | |
| 119 // BrowserContext will take care of deallocating it. | |
| 120 BrowserContext::SetDownloadManagerForTesting(browser_context(), | |
| 121 download_manager_); | |
| 122 } | |
| 123 | |
| 124 // Creates a new Background Fetch registration, whose id will be stored in | 38 // Creates a new Background Fetch registration, whose id will be stored in |
| 125 // the |*registration_id|, and registers it with the DataManager for the | 39 // the |*registration_id|, and registers it with the DataManager for the |
| 126 // included |request_data|. Should be wrapped in ASSERT_NO_FATAL_FAILURE(). | 40 // included |request_data|. Should be wrapped in ASSERT_NO_FATAL_FAILURE(). |
| 127 void CreateRegistrationForRequests( | 41 void CreateRegistrationForRequests( |
| 128 BackgroundFetchRegistrationId* registration_id, | 42 BackgroundFetchRegistrationId* registration_id, |
| 129 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>* | 43 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>* |
| 130 out_initial_requests, | 44 out_initial_requests, |
| 131 std::map<std::string /* url */, std::string /* method */> request_data) { | 45 std::map<std::string /* url */, std::string /* method */> request_data) { |
| 132 DCHECK(registration_id); | 46 DCHECK(registration_id); |
| 133 DCHECK(out_initial_requests); | 47 DCHECK(out_initial_requests); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 150 *registration_id, requests, BackgroundFetchOptions(), | 64 *registration_id, requests, BackgroundFetchOptions(), |
| 151 base::BindOnce(&BackgroundFetchJobControllerTest::DidCreateRegistration, | 65 base::BindOnce(&BackgroundFetchJobControllerTest::DidCreateRegistration, |
| 152 base::Unretained(this), &error, out_initial_requests, | 66 base::Unretained(this), &error, out_initial_requests, |
| 153 run_loop.QuitClosure())); | 67 run_loop.QuitClosure())); |
| 154 run_loop.Run(); | 68 run_loop.Run(); |
| 155 | 69 |
| 156 ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); | 70 ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
| 157 ASSERT_GE(out_initial_requests->size(), 1u); | 71 ASSERT_GE(out_initial_requests->size(), 1u); |
| 158 ASSERT_LE(out_initial_requests->size(), | 72 ASSERT_LE(out_initial_requests->size(), |
| 159 kMaximumBackgroundFetchParallelRequests); | 73 kMaximumBackgroundFetchParallelRequests); |
| 74 |
| 75 // Provide fake responses for the given |request_data| pairs. |
| 76 for (const auto& pair : request_data) { |
| 77 CreateRequestWithProvidedResponse(pair.second, pair.first, |
| 78 200 /* status_code */, |
| 79 "" /* response_text */); |
| 80 } |
| 160 } | 81 } |
| 161 | 82 |
| 162 // Creates a new BackgroundFetchJobController instance. | 83 // Creates a new BackgroundFetchJobController instance. |
| 163 std::unique_ptr<BackgroundFetchJobController> CreateJobController( | 84 std::unique_ptr<BackgroundFetchJobController> CreateJobController( |
| 164 const BackgroundFetchRegistrationId& registration_id) { | 85 const BackgroundFetchRegistrationId& registration_id) { |
| 165 StoragePartition* storage_partition = | 86 StoragePartition* storage_partition = |
| 166 BrowserContext::GetDefaultStoragePartition(browser_context()); | 87 BrowserContext::GetDefaultStoragePartition(browser_context()); |
| 167 | 88 |
| 168 return base::MakeUnique<BackgroundFetchJobController>( | 89 return base::MakeUnique<BackgroundFetchJobController>( |
| 169 registration_id, BackgroundFetchOptions(), &data_manager_, | 90 registration_id, BackgroundFetchOptions(), &data_manager_, |
| 170 browser_context(), | 91 browser_context(), |
| 171 make_scoped_refptr(storage_partition->GetURLRequestContext()), | 92 make_scoped_refptr(storage_partition->GetURLRequestContext()), |
| 172 base::BindOnce(&BackgroundFetchJobControllerTest::DidCompleteJob, | 93 base::BindOnce(&BackgroundFetchJobControllerTest::DidCompleteJob, |
| 173 base::Unretained(this))); | 94 base::Unretained(this))); |
| 174 } | 95 } |
| 175 | 96 |
| 176 protected: | 97 protected: |
| 177 BackgroundFetchDataManager data_manager_; | 98 BackgroundFetchDataManager data_manager_; |
| 178 MockDownloadManagerWithCallback* download_manager_; // BrowserContext owned | |
| 179 bool did_complete_job_ = false; | 99 bool did_complete_job_ = false; |
| 180 | 100 |
| 181 // Closure that will be invoked when the JobController has completed all | 101 // Closure that will be invoked when the JobController has completed all |
| 182 // available jobs. Enables use of a run loop for deterministic waits. | 102 // available jobs. Enables use of a run loop for deterministic waits. |
| 183 base::OnceClosure job_completed_closure_; | 103 base::OnceClosure job_completed_closure_; |
| 184 | 104 |
| 185 private: | 105 private: |
| 186 void DidCreateRegistration( | 106 void DidCreateRegistration( |
| 187 blink::mojom::BackgroundFetchError* out_error, | 107 blink::mojom::BackgroundFetchError* out_error, |
| 188 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>* | 108 std::vector<scoped_refptr<BackgroundFetchRequestInfo>>* |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 | 140 |
| 221 ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests( | 141 ASSERT_NO_FATAL_FAILURE(CreateRegistrationForRequests( |
| 222 ®istration_id, &initial_requests, | 142 ®istration_id, &initial_requests, |
| 223 {{"https://example.com/funny_cat.png", "GET"}})); | 143 {{"https://example.com/funny_cat.png", "GET"}})); |
| 224 | 144 |
| 225 std::unique_ptr<BackgroundFetchJobController> controller = | 145 std::unique_ptr<BackgroundFetchJobController> controller = |
| 226 CreateJobController(registration_id); | 146 CreateJobController(registration_id); |
| 227 | 147 |
| 228 EXPECT_EQ(controller->state(), | 148 EXPECT_EQ(controller->state(), |
| 229 BackgroundFetchJobController::State::INITIALIZED); | 149 BackgroundFetchJobController::State::INITIALIZED); |
| 230 EXPECT_CALL(*download_manager_, DownloadUrlMock(_)).Times(1); | |
| 231 | 150 |
| 232 controller->Start(initial_requests /* deliberate copy */); | 151 controller->Start(initial_requests /* deliberate copy */); |
| 233 EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::FETCHING); | 152 EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::FETCHING); |
| 234 | 153 |
| 235 // Allows for proper initialization of the FakeDownloadItems. | |
| 236 base::RunLoop().RunUntilIdle(); | |
| 237 | |
| 238 std::vector<FakeDownloadItem*> download_items = | |
| 239 download_manager_->GetDownloadItems(); | |
| 240 ASSERT_EQ(download_items.size(), 1u); | |
| 241 | |
| 242 // Mark the single download item as finished, completing the job. | 154 // Mark the single download item as finished, completing the job. |
| 243 { | 155 { |
| 244 base::RunLoop run_loop; | 156 base::RunLoop run_loop; |
| 245 job_completed_closure_ = run_loop.QuitClosure(); | 157 job_completed_closure_ = run_loop.QuitClosure(); |
| 246 | 158 |
| 247 FakeDownloadItem* item = download_items[0]; | |
| 248 | |
| 249 EXPECT_EQ(DownloadItem::DownloadState::IN_PROGRESS, item->GetState()); | |
| 250 | |
| 251 item->SetState(DownloadItem::DownloadState::COMPLETE); | |
| 252 item->NotifyDownloadUpdated(); | |
| 253 | |
| 254 run_loop.Run(); | 159 run_loop.Run(); |
| 255 } | 160 } |
| 256 | 161 |
| 257 EXPECT_EQ(controller->state(), | 162 EXPECT_EQ(controller->state(), |
| 258 BackgroundFetchJobController::State::COMPLETED); | 163 BackgroundFetchJobController::State::COMPLETED); |
| 259 EXPECT_TRUE(did_complete_job_); | 164 EXPECT_TRUE(did_complete_job_); |
| 260 } | 165 } |
| 261 | 166 |
| 262 TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) { | 167 TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) { |
| 263 BackgroundFetchRegistrationId registration_id; | 168 BackgroundFetchRegistrationId registration_id; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 274 {"https://example.com/crazy_cat.png", "GET"}, | 179 {"https://example.com/crazy_cat.png", "GET"}, |
| 275 {"https://example.com/silly_cat.png", "GET"}, | 180 {"https://example.com/silly_cat.png", "GET"}, |
| 276 {"https://example.com/happy_cat.png", "GET"}})); | 181 {"https://example.com/happy_cat.png", "GET"}})); |
| 277 | 182 |
| 278 std::unique_ptr<BackgroundFetchJobController> controller = | 183 std::unique_ptr<BackgroundFetchJobController> controller = |
| 279 CreateJobController(registration_id); | 184 CreateJobController(registration_id); |
| 280 | 185 |
| 281 EXPECT_EQ(controller->state(), | 186 EXPECT_EQ(controller->state(), |
| 282 BackgroundFetchJobController::State::INITIALIZED); | 187 BackgroundFetchJobController::State::INITIALIZED); |
| 283 | 188 |
| 284 // Enable automatically marking downloads as finished. | |
| 285 download_manager_->set_post_completion_task_enabled(true); | |
| 286 | |
| 287 // Continue spinning until the Job Controller has completed all the requests. | 189 // Continue spinning until the Job Controller has completed all the requests. |
| 288 // The Download Manager has been told to automatically mark them as finished. | 190 // The Download Manager has been told to automatically mark them as finished. |
| 289 { | 191 { |
| 290 base::RunLoop run_loop; | 192 base::RunLoop run_loop; |
| 291 job_completed_closure_ = run_loop.QuitClosure(); | 193 job_completed_closure_ = run_loop.QuitClosure(); |
| 292 | 194 |
| 293 EXPECT_CALL(*download_manager_, DownloadUrlMock(_)).Times(5); | |
| 294 | |
| 295 controller->Start(initial_requests /* deliberate copy */); | 195 controller->Start(initial_requests /* deliberate copy */); |
| 296 EXPECT_EQ(controller->state(), | 196 EXPECT_EQ(controller->state(), |
| 297 BackgroundFetchJobController::State::FETCHING); | 197 BackgroundFetchJobController::State::FETCHING); |
| 298 | 198 |
| 299 run_loop.Run(); | 199 run_loop.Run(); |
| 300 } | 200 } |
| 301 | 201 |
| 302 EXPECT_EQ(controller->state(), | 202 EXPECT_EQ(controller->state(), |
| 303 BackgroundFetchJobController::State::COMPLETED); | 203 BackgroundFetchJobController::State::COMPLETED); |
| 304 EXPECT_TRUE(did_complete_job_); | 204 EXPECT_TRUE(did_complete_job_); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 334 | 234 |
| 335 // TODO(peter): Verify that the issued download items have had their state | 235 // TODO(peter): Verify that the issued download items have had their state |
| 336 // updated to be cancelled as well. | 236 // updated to be cancelled as well. |
| 337 | 237 |
| 338 EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::ABORTED); | 238 EXPECT_EQ(controller->state(), BackgroundFetchJobController::State::ABORTED); |
| 339 EXPECT_TRUE(did_complete_job_); | 239 EXPECT_TRUE(did_complete_job_); |
| 340 } | 240 } |
| 341 | 241 |
| 342 } // namespace | 242 } // namespace |
| 343 } // namespace content | 243 } // namespace content |
| OLD | NEW |