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 |