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_data_manager.h" | 5 #include "content/browser/background_fetch/background_fetch_data_manager.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | |
10 | 9 |
11 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
12 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
13 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
14 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
15 #include "content/browser/background_fetch/background_fetch_job_info.h" | |
16 #include "content/browser/background_fetch/background_fetch_job_response_data.h" | |
17 #include "content/browser/background_fetch/background_fetch_request_info.h" | 14 #include "content/browser/background_fetch/background_fetch_request_info.h" |
18 #include "content/browser/background_fetch/background_fetch_test_base.h" | 15 #include "content/browser/background_fetch/background_fetch_test_base.h" |
19 #include "content/common/service_worker/service_worker_types.h" | |
20 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
21 #include "content/public/browser/download_interrupt_reasons.h" | |
22 #include "content/public/browser/download_item.h" | |
23 | 17 |
24 namespace content { | 18 namespace content { |
25 namespace { | 19 namespace { |
26 | 20 |
27 const char kResource[] = "https://example.com/resource.html"; | 21 const char kExampleTag[] = "my-example-tag"; |
28 const char kTag[] = "TestRequestTag"; | |
29 const char kJobOrigin[] = "https://example.com"; | |
30 const int64_t kServiceWorkerRegistrationId = 9001; | |
31 | 22 |
32 } // namespace | 23 } // namespace |
33 | 24 |
34 class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase { | 25 class BackgroundFetchDataManagerTest : public BackgroundFetchTestBase { |
35 public: | 26 public: |
36 BackgroundFetchDataManagerTest() | 27 BackgroundFetchDataManagerTest() |
37 : background_fetch_data_manager_( | 28 : background_fetch_data_manager_( |
38 base::MakeUnique<BackgroundFetchDataManager>(browser_context())) {} | 29 base::MakeUnique<BackgroundFetchDataManager>(browser_context())) {} |
39 ~BackgroundFetchDataManagerTest() override = default; | 30 ~BackgroundFetchDataManagerTest() override = default; |
40 | 31 |
(...skipping 23 matching lines...) Expand all Loading... |
64 | 55 |
65 base::RunLoop run_loop; | 56 base::RunLoop run_loop; |
66 background_fetch_data_manager_->DeleteRegistration( | 57 background_fetch_data_manager_->DeleteRegistration( |
67 registration_id, | 58 registration_id, |
68 base::BindOnce(&BackgroundFetchDataManagerTest::DidDeleteRegistration, | 59 base::BindOnce(&BackgroundFetchDataManagerTest::DidDeleteRegistration, |
69 base::Unretained(this), run_loop.QuitClosure(), | 60 base::Unretained(this), run_loop.QuitClosure(), |
70 out_error)); | 61 out_error)); |
71 run_loop.Run(); | 62 run_loop.Run(); |
72 } | 63 } |
73 | 64 |
74 void CreateRequests(int num_requests) { | |
75 DCHECK_GT(num_requests, 0); | |
76 // Create |num_requests| BackgroundFetchRequestInfo's. | |
77 std::vector<std::unique_ptr<BackgroundFetchRequestInfo>> request_infos; | |
78 for (int i = 0; i < num_requests; i++) { | |
79 ServiceWorkerHeaderMap headers; | |
80 ServiceWorkerFetchRequest request(GURL(kResource), "GET", headers, | |
81 Referrer(), false /* is_reload */); | |
82 request_infos.push_back( | |
83 base::MakeUnique<BackgroundFetchRequestInfo>(i, request)); | |
84 } | |
85 std::unique_ptr<BackgroundFetchJobInfo> job_info = | |
86 base::MakeUnique<BackgroundFetchJobInfo>( | |
87 kTag, url::Origin(GURL(kJobOrigin)), kServiceWorkerRegistrationId); | |
88 job_info->set_num_requests(num_requests); | |
89 | |
90 job_guid_ = job_info->guid(); | |
91 | |
92 background_fetch_data_manager_->WriteJobToStorage(std::move(job_info), | |
93 std::move(request_infos)); | |
94 } | |
95 | |
96 void GetResponse() { | |
97 base::RunLoop run_loop; | |
98 BackgroundFetchResponseCompleteCallback callback = | |
99 base::Bind(&BackgroundFetchDataManagerTest::DidGetResponse, | |
100 base::Unretained(this), run_loop.QuitClosure()); | |
101 BrowserThread::PostTask( | |
102 BrowserThread::IO, FROM_HERE, | |
103 base::Bind(&BackgroundFetchDataManager::GetJobResponse, | |
104 base::Unretained(background_fetch_data_manager()), job_guid_, | |
105 base::Bind(&BackgroundFetchDataManagerTest::DidGetResponse, | |
106 base::Unretained(this), run_loop.QuitClosure()))); | |
107 run_loop.Run(); | |
108 } | |
109 | |
110 void DidGetResponse(base::Closure closure, | |
111 std::vector<ServiceWorkerResponse> responses, | |
112 std::vector<std::unique_ptr<BlobHandle>> blobs) { | |
113 responses_ = std::move(responses); | |
114 blobs_ = std::move(blobs); | |
115 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure); | |
116 } | |
117 | |
118 const std::string& job_guid() const { return job_guid_; } | |
119 BackgroundFetchDataManager* background_fetch_data_manager() { | |
120 return background_fetch_data_manager_.get(); | |
121 } | |
122 | |
123 const std::vector<ServiceWorkerResponse>& responses() const { | |
124 return responses_; | |
125 } | |
126 const std::vector<std::unique_ptr<BlobHandle>>& blobs() const { | |
127 return blobs_; | |
128 } | |
129 | |
130 private: | 65 private: |
131 void DidCreateRegistration( | 66 void DidCreateRegistration( |
132 base::Closure quit_closure, | 67 base::Closure quit_closure, |
133 blink::mojom::BackgroundFetchError* out_error, | 68 blink::mojom::BackgroundFetchError* out_error, |
134 std::vector<BackgroundFetchRequestInfo>* out_initial_requests, | 69 std::vector<BackgroundFetchRequestInfo>* out_initial_requests, |
135 blink::mojom::BackgroundFetchError error, | 70 blink::mojom::BackgroundFetchError error, |
136 std::vector<BackgroundFetchRequestInfo> initial_requests) { | 71 std::vector<BackgroundFetchRequestInfo> initial_requests) { |
137 *out_error = error; | 72 *out_error = error; |
138 *out_initial_requests = std::move(initial_requests); | 73 *out_initial_requests = std::move(initial_requests); |
139 | 74 |
140 quit_closure.Run(); | 75 quit_closure.Run(); |
141 } | 76 } |
142 | 77 |
143 void DidDeleteRegistration(base::Closure quit_closure, | 78 void DidDeleteRegistration(base::Closure quit_closure, |
144 blink::mojom::BackgroundFetchError* out_error, | 79 blink::mojom::BackgroundFetchError* out_error, |
145 blink::mojom::BackgroundFetchError error) { | 80 blink::mojom::BackgroundFetchError error) { |
146 *out_error = error; | 81 *out_error = error; |
147 | 82 |
148 quit_closure.Run(); | 83 quit_closure.Run(); |
149 } | 84 } |
150 | 85 |
151 std::string job_guid_; | 86 std::string job_guid_; |
152 std::unique_ptr<BackgroundFetchDataManager> background_fetch_data_manager_; | 87 std::unique_ptr<BackgroundFetchDataManager> background_fetch_data_manager_; |
153 std::vector<ServiceWorkerResponse> responses_; | |
154 std::vector<std::unique_ptr<BlobHandle>> blobs_; | |
155 }; | 88 }; |
156 | 89 |
157 TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) { | 90 TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) { |
158 // Tests that the BackgroundFetchDataManager correctly rejects creating a | 91 // Tests that the BackgroundFetchDataManager correctly rejects creating a |
159 // registration that's already known to the system. | 92 // registration that's already known to the system. |
160 | 93 |
161 BackgroundFetchRegistrationId registration_id; | 94 BackgroundFetchRegistrationId registration_id; |
162 ASSERT_TRUE(CreateRegistrationId(kTag, ®istration_id)); | 95 ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
163 | 96 |
164 std::vector<ServiceWorkerFetchRequest> requests; | 97 std::vector<ServiceWorkerFetchRequest> requests; |
165 BackgroundFetchOptions options; | 98 BackgroundFetchOptions options; |
166 | 99 |
167 blink::mojom::BackgroundFetchError error; | 100 blink::mojom::BackgroundFetchError error; |
168 std::vector<BackgroundFetchRequestInfo> initial_requests; | 101 std::vector<BackgroundFetchRequestInfo> initial_requests; |
169 | 102 |
170 // Deleting the not-yet-created registration should fail. | 103 // Deleting the not-yet-created registration should fail. |
171 ASSERT_NO_FATAL_FAILURE(DeleteRegistration(registration_id, &error)); | 104 ASSERT_NO_FATAL_FAILURE(DeleteRegistration(registration_id, &error)); |
172 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_TAG); | 105 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_TAG); |
(...skipping 11 matching lines...) Expand all Loading... |
184 // Deleting the registration should succeed. | 117 // Deleting the registration should succeed. |
185 ASSERT_NO_FATAL_FAILURE(DeleteRegistration(registration_id, &error)); | 118 ASSERT_NO_FATAL_FAILURE(DeleteRegistration(registration_id, &error)); |
186 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); | 119 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
187 | 120 |
188 // And then recreating the registration again should work fine. | 121 // And then recreating the registration again should work fine. |
189 ASSERT_NO_FATAL_FAILURE(CreateRegistration(registration_id, requests, options, | 122 ASSERT_NO_FATAL_FAILURE(CreateRegistration(registration_id, requests, options, |
190 &error, &initial_requests)); | 123 &error, &initial_requests)); |
191 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); | 124 EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
192 } | 125 } |
193 | 126 |
194 TEST_F(BackgroundFetchDataManagerTest, OutOfOrderCompletion) { | |
195 CreateRequests(10); | |
196 BackgroundFetchDataManager* data_manager = background_fetch_data_manager(); | |
197 const std::string& job_guid = BackgroundFetchDataManagerTest::job_guid(); | |
198 std::vector<std::string> request_guids; | |
199 | |
200 // Start half of the fetch requests. | |
201 for (int i = 0; i < 5; i++) { | |
202 ASSERT_TRUE(data_manager->HasRequestsRemaining(job_guid)); | |
203 const BackgroundFetchRequestInfo& request_info = | |
204 data_manager->GetNextBackgroundFetchRequestInfo(job_guid); | |
205 request_guids.push_back(request_info.guid()); | |
206 } | |
207 | |
208 // Complete all of the fetches out of order except for #1. | |
209 DownloadItem::DownloadState complete = DownloadItem::DownloadState::COMPLETE; | |
210 DownloadInterruptReason no_interrupt = | |
211 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE; | |
212 EXPECT_TRUE(data_manager->UpdateRequestState(job_guid, request_guids[3], | |
213 complete, no_interrupt)); | |
214 EXPECT_TRUE(data_manager->UpdateRequestState(job_guid, request_guids[2], | |
215 complete, no_interrupt)); | |
216 EXPECT_TRUE(data_manager->UpdateRequestState(job_guid, request_guids[4], | |
217 complete, no_interrupt)); | |
218 EXPECT_TRUE(data_manager->UpdateRequestState(job_guid, request_guids[0], | |
219 complete, no_interrupt)); | |
220 | |
221 EXPECT_TRUE(data_manager->HasRequestsRemaining(job_guid)); | |
222 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
223 | |
224 // Start and complete the remaining requests. | |
225 for (int i = 5; i < 10; i++) { | |
226 const BackgroundFetchRequestInfo& request_info = | |
227 data_manager->GetNextBackgroundFetchRequestInfo(job_guid); | |
228 request_guids.push_back(request_info.guid()); | |
229 data_manager->UpdateRequestState(job_guid, request_guids[i], complete, | |
230 no_interrupt); | |
231 } | |
232 | |
233 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
234 EXPECT_FALSE(data_manager->HasRequestsRemaining(job_guid)); | |
235 | |
236 // Complete the final request. | |
237 EXPECT_FALSE(data_manager->UpdateRequestState(job_guid, request_guids[1], | |
238 complete, no_interrupt)); | |
239 EXPECT_TRUE(data_manager->IsComplete(job_guid)); | |
240 } | |
241 | |
242 TEST_F(BackgroundFetchDataManagerTest, PauseAndResume) { | |
243 CreateRequests(1); | |
244 BackgroundFetchDataManager* data_manager = background_fetch_data_manager(); | |
245 const std::string& job_guid = BackgroundFetchDataManagerTest::job_guid(); | |
246 | |
247 // Start the request. | |
248 ASSERT_TRUE(data_manager->HasRequestsRemaining(job_guid)); | |
249 const BackgroundFetchRequestInfo& request_info = | |
250 data_manager->GetNextBackgroundFetchRequestInfo(job_guid); | |
251 | |
252 EXPECT_FALSE(data_manager->HasRequestsRemaining(job_guid)); | |
253 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
254 | |
255 // Set the request state to be paused. This should not complete the job. | |
256 EXPECT_FALSE(data_manager->UpdateRequestState( | |
257 job_guid, request_info.guid(), DownloadItem::DownloadState::INTERRUPTED, | |
258 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN)); | |
259 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
260 | |
261 // Unpause the request. | |
262 EXPECT_FALSE(data_manager->UpdateRequestState( | |
263 job_guid, request_info.guid(), DownloadItem::DownloadState::IN_PROGRESS, | |
264 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE)); | |
265 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
266 | |
267 // Complete the request. | |
268 EXPECT_FALSE(data_manager->UpdateRequestState( | |
269 job_guid, request_info.guid(), DownloadItem::DownloadState::COMPLETE, | |
270 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE)); | |
271 EXPECT_TRUE(data_manager->IsComplete(job_guid)); | |
272 } | |
273 | |
274 TEST_F(BackgroundFetchDataManagerTest, CancelledRequest) { | |
275 CreateRequests(1); | |
276 BackgroundFetchDataManager* data_manager = background_fetch_data_manager(); | |
277 const std::string& job_guid = BackgroundFetchDataManagerTest::job_guid(); | |
278 | |
279 // Start the request. | |
280 ASSERT_TRUE(data_manager->HasRequestsRemaining(job_guid)); | |
281 const BackgroundFetchRequestInfo& request_info = | |
282 data_manager->GetNextBackgroundFetchRequestInfo(job_guid); | |
283 | |
284 EXPECT_FALSE(data_manager->HasRequestsRemaining(job_guid)); | |
285 EXPECT_FALSE(data_manager->IsComplete(job_guid)); | |
286 | |
287 // Cancel the request. | |
288 EXPECT_FALSE(data_manager->UpdateRequestState( | |
289 job_guid, request_info.guid(), DownloadItem::DownloadState::CANCELLED, | |
290 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); | |
291 EXPECT_TRUE(data_manager->IsComplete(job_guid)); | |
292 } | |
293 | |
294 TEST_F(BackgroundFetchDataManagerTest, PrepareResponse) { | |
295 CreateRequests(1); | |
296 BackgroundFetchDataManager* data_manager = background_fetch_data_manager(); | |
297 const std::string& job_guid = BackgroundFetchDataManagerTest::job_guid(); | |
298 | |
299 const BackgroundFetchRequestInfo& request_info = | |
300 data_manager->GetNextBackgroundFetchRequestInfo(job_guid); | |
301 EXPECT_FALSE(data_manager->UpdateRequestState( | |
302 job_guid, request_info.guid(), DownloadItem::DownloadState::COMPLETE, | |
303 DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)); | |
304 EXPECT_TRUE(data_manager->IsComplete(job_guid)); | |
305 } | |
306 | |
307 } // namespace content | 127 } // namespace content |
OLD | NEW |