| 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 |