| 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 <map> |
| 5 #include <memory> | 6 #include <memory> |
| 7 #include <utility> |
| 6 | 8 |
| 9 #include "base/guid.h" |
| 7 #include "base/macros.h" | 10 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/memory/weak_ptr.h" |
| 9 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
| 14 #include "base/time/time.h" |
| 10 #include "content/browser/background_fetch/background_fetch_context.h" | 15 #include "content/browser/background_fetch/background_fetch_context.h" |
| 11 #include "content/browser/background_fetch/background_fetch_embedded_worker_test
_helper.h" | 16 #include "content/browser/background_fetch/background_fetch_embedded_worker_test
_helper.h" |
| 12 #include "content/browser/background_fetch/background_fetch_registration_id.h" | 17 #include "content/browser/background_fetch/background_fetch_registration_id.h" |
| 13 #include "content/browser/background_fetch/background_fetch_service_impl.h" | 18 #include "content/browser/background_fetch/background_fetch_service_impl.h" |
| 14 #include "content/browser/background_fetch/background_fetch_test_base.h" | 19 #include "content/browser/background_fetch/background_fetch_test_base.h" |
| 15 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 20 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 16 #include "content/browser/storage_partition_impl.h" | 21 #include "content/browser/storage_partition_impl.h" |
| 22 #include "content/common/service_worker/service_worker_types.h" |
| 23 #include "content/public/test/fake_download_item.h" |
| 24 #include "content/public/test/mock_download_manager.h" |
| 17 | 25 |
| 18 namespace content { | 26 namespace content { |
| 19 namespace { | 27 namespace { |
| 20 | 28 |
| 21 const char kExampleTag[] = "my-background-fetch"; | 29 const char kExampleTag[] = "my-background-fetch"; |
| 22 const char kAlternativeTag[] = "my-alternative-fetch"; | 30 const char kAlternativeTag[] = "my-alternative-fetch"; |
| 23 | 31 |
| 32 // Faked download manager that will respond to known HTTP requests with a test- |
| 33 // defined response. See CreateRequestWithProvidedResponse(). |
| 34 class RespondingDownloadManager : public MockDownloadManager { |
| 35 public: |
| 36 RespondingDownloadManager() : weak_ptr_factory_(this) {} |
| 37 ~RespondingDownloadManager() override = default; |
| 38 |
| 39 // Responds to requests to |url| with the |status_code| and |response_text|. |
| 40 void RegisterResponse(const GURL& url, |
| 41 int status_code, |
| 42 const std::string& response_text) { |
| 43 DCHECK_EQ(registered_responses_.count(url), 0u); |
| 44 registered_responses_[url] = std::make_pair(status_code, response_text); |
| 45 } |
| 46 |
| 47 // Called when the Background Fetch system starts a download, all information |
| 48 // for which is contained in the |params|. |
| 49 void DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override { |
| 50 auto iter = registered_responses_.find(params->url()); |
| 51 if (iter == registered_responses_.end()) |
| 52 return; |
| 53 |
| 54 std::unique_ptr<FakeDownloadItem> download_item = |
| 55 base::MakeUnique<FakeDownloadItem>(); |
| 56 |
| 57 download_item->SetURL(params->url()); |
| 58 download_item->SetState(DownloadItem::DownloadState::IN_PROGRESS); |
| 59 download_item->SetGuid(base::GenerateGUID()); |
| 60 download_item->SetStartTime(base::Time()); |
| 61 |
| 62 // Asynchronously invoke the callback set on the |params|, and then continue |
| 63 // dealing with the response in this class. |
| 64 BrowserThread::PostTaskAndReply( |
| 65 BrowserThread::UI, FROM_HERE, |
| 66 base::Bind(params->callback(), download_item.get(), |
| 67 DOWNLOAD_INTERRUPT_REASON_NONE), |
| 68 base::Bind(&RespondingDownloadManager::DidStartDownload, |
| 69 weak_ptr_factory_.GetWeakPtr(), download_item.get())); |
| 70 |
| 71 download_items_.push_back(std::move(download_item)); |
| 72 } |
| 73 |
| 74 private: |
| 75 // Called when the download has been "started" by the download manager. This |
| 76 // is where we finish the download by sending a single update. |
| 77 void DidStartDownload(FakeDownloadItem* download_item) { |
| 78 auto iter = registered_responses_.find(download_item->GetURL()); |
| 79 DCHECK(iter != registered_responses_.end()); |
| 80 |
| 81 const ResponseInfo& response_info = iter->second; |
| 82 |
| 83 download_item->SetState(DownloadItem::DownloadState::COMPLETE); |
| 84 download_item->SetEndTime(base::Time()); |
| 85 |
| 86 // TODO(peter): Set response body, status code and so on. |
| 87 download_item->SetReceivedBytes(response_info.second.size()); |
| 88 |
| 89 // Notify the Job Controller about the download having been updated. |
| 90 download_item->NotifyDownloadUpdated(); |
| 91 } |
| 92 |
| 93 using ResponseInfo = |
| 94 std::pair<int /* status_code */, std::string /* response_text */>; |
| 95 |
| 96 // Map of URL to the response information associated with that URL. |
| 97 std::map<GURL, ResponseInfo> registered_responses_; |
| 98 |
| 99 // Only used to guarantee the lifetime of the created FakeDownloadItems. |
| 100 std::vector<std::unique_ptr<FakeDownloadItem>> download_items_; |
| 101 |
| 102 base::WeakPtrFactory<RespondingDownloadManager> weak_ptr_factory_; |
| 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(RespondingDownloadManager); |
| 105 }; |
| 106 |
| 24 IconDefinition CreateIcon(std::string src, | 107 IconDefinition CreateIcon(std::string src, |
| 25 std::string sizes, | 108 std::string sizes, |
| 26 std::string type) { | 109 std::string type) { |
| 27 IconDefinition icon; | 110 IconDefinition icon; |
| 28 icon.src = std::move(src); | 111 icon.src = std::move(src); |
| 29 icon.sizes = std::move(sizes); | 112 icon.sizes = std::move(sizes); |
| 30 icon.type = std::move(type); | 113 icon.type = std::move(type); |
| 31 | 114 |
| 32 return icon; | 115 return icon; |
| 33 } | 116 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 base::RunLoop run_loop; | 189 base::RunLoop run_loop; |
| 107 service_->GetTags(registration_id.service_worker_registration_id(), | 190 service_->GetTags(registration_id.service_worker_registration_id(), |
| 108 registration_id.origin(), | 191 registration_id.origin(), |
| 109 base::Bind(&BackgroundFetchServiceTest::DidGetTags, | 192 base::Bind(&BackgroundFetchServiceTest::DidGetTags, |
| 110 base::Unretained(this), run_loop.QuitClosure(), | 193 base::Unretained(this), run_loop.QuitClosure(), |
| 111 out_error, out_tags)); | 194 out_error, out_tags)); |
| 112 | 195 |
| 113 run_loop.Run(); | 196 run_loop.Run(); |
| 114 } | 197 } |
| 115 | 198 |
| 199 // Creates a ServiceWorkerFetchRequest instance for the given details and |
| 200 // provides a faked response with |status_code| and |response_text| to the |
| 201 // download manager, that will resolve the download with that information. |
| 202 ServiceWorkerFetchRequest CreateRequestWithProvidedResponse( |
| 203 const std::string& method, |
| 204 const std::string& url_string, |
| 205 int status_code, |
| 206 const std::string& response_text) { |
| 207 GURL url(url_string); |
| 208 |
| 209 // Register the |status_code| and |response_text| with the download manager. |
| 210 download_manager_->RegisterResponse(GURL(url_string), status_code, |
| 211 response_text); |
| 212 |
| 213 // Create a ServiceWorkerFetchRequest request with the same information. |
| 214 return ServiceWorkerFetchRequest(url, method, ServiceWorkerHeaderMap(), |
| 215 Referrer(), false /* is_reload */); |
| 216 } |
| 217 |
| 116 // BackgroundFetchTestBase overrides: | 218 // BackgroundFetchTestBase overrides: |
| 117 void SetUp() override { | 219 void SetUp() override { |
| 118 BackgroundFetchTestBase::SetUp(); | 220 BackgroundFetchTestBase::SetUp(); |
| 221 |
| 222 download_manager_ = new RespondingDownloadManager(); |
| 223 |
| 224 // The |download_manager_| ownership is given to the BrowserContext, and the |
| 225 // BrowserContext will take care of deallocating it. |
| 226 BrowserContext::SetDownloadManagerForTesting(browser_context(), |
| 227 download_manager_); |
| 228 |
| 119 StoragePartitionImpl* storage_partition = | 229 StoragePartitionImpl* storage_partition = |
| 120 static_cast<StoragePartitionImpl*>( | 230 static_cast<StoragePartitionImpl*>( |
| 121 BrowserContext::GetDefaultStoragePartition(browser_context())); | 231 BrowserContext::GetDefaultStoragePartition(browser_context())); |
| 122 | 232 |
| 123 context_ = new BackgroundFetchContext( | 233 context_ = new BackgroundFetchContext( |
| 124 browser_context(), storage_partition, | 234 browser_context(), storage_partition, |
| 125 make_scoped_refptr(embedded_worker_test_helper()->context_wrapper())); | 235 make_scoped_refptr(embedded_worker_test_helper()->context_wrapper())); |
| 126 service_ = base::MakeUnique<BackgroundFetchServiceImpl>( | 236 service_ = base::MakeUnique<BackgroundFetchServiceImpl>( |
| 127 0 /* render_process_id */, context_); | 237 0 /* render_process_id */, context_); |
| 128 } | 238 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 const std::vector<std::string>& tags) { | 279 const std::vector<std::string>& tags) { |
| 170 *out_error = error; | 280 *out_error = error; |
| 171 *out_tags = tags; | 281 *out_tags = tags; |
| 172 | 282 |
| 173 quit_closure.Run(); | 283 quit_closure.Run(); |
| 174 } | 284 } |
| 175 | 285 |
| 176 scoped_refptr<BackgroundFetchContext> context_; | 286 scoped_refptr<BackgroundFetchContext> context_; |
| 177 std::unique_ptr<BackgroundFetchServiceImpl> service_; | 287 std::unique_ptr<BackgroundFetchServiceImpl> service_; |
| 178 | 288 |
| 289 RespondingDownloadManager* download_manager_; // BrowserContext owned |
| 290 |
| 179 DISALLOW_COPY_AND_ASSIGN(BackgroundFetchServiceTest); | 291 DISALLOW_COPY_AND_ASSIGN(BackgroundFetchServiceTest); |
| 180 }; | 292 }; |
| 181 | 293 |
| 182 TEST_F(BackgroundFetchServiceTest, FetchInvalidArguments) { | 294 TEST_F(BackgroundFetchServiceTest, FetchInvalidArguments) { |
| 183 // This test verifies that the Fetch() function will kill the renderer and | 295 // This test verifies that the Fetch() function will kill the renderer and |
| 184 // return INVALID_ARGUMENT when invalid data is send over the Mojo channel. | 296 // return INVALID_ARGUMENT when invalid data is send over the Mojo channel. |
| 185 | 297 |
| 186 BackgroundFetchOptions options; | 298 BackgroundFetchOptions options; |
| 187 | 299 |
| 188 // The `tag` must be a non-empty string. | 300 // The `tag` must be a non-empty string. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 412 |
| 301 blink::mojom::BackgroundFetchError second_error; | 413 blink::mojom::BackgroundFetchError second_error; |
| 302 BackgroundFetchRegistration second_registration; | 414 BackgroundFetchRegistration second_registration; |
| 303 | 415 |
| 304 // Create the second registration with the same data. This must fail. | 416 // Create the second registration with the same data. This must fail. |
| 305 ASSERT_NO_FATAL_FAILURE(Fetch(registration_id, requests, options, | 417 ASSERT_NO_FATAL_FAILURE(Fetch(registration_id, requests, options, |
| 306 &second_error, &second_registration)); | 418 &second_error, &second_registration)); |
| 307 ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::DUPLICATED_TAG); | 419 ASSERT_EQ(second_error, blink::mojom::BackgroundFetchError::DUPLICATED_TAG); |
| 308 } | 420 } |
| 309 | 421 |
| 422 TEST_F(BackgroundFetchServiceTest, FetchSuccessEventDispatch) { |
| 423 // This test starts a new Background Fetch, completes the registration, then |
| 424 // fetches all files to complete the job, and then verifies that the |
| 425 // `backgroundfetched` event will be dispatched with the expected contents. |
| 426 |
| 427 BackgroundFetchRegistrationId registration_id; |
| 428 ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
| 429 |
| 430 // base::RunLoop that we'll run until the event has been dispatched. If this |
| 431 // test times out, it means that the event could not be dispatched. |
| 432 base::RunLoop event_dispatched_loop; |
| 433 embedded_worker_test_helper()->set_fetched_event_closure( |
| 434 event_dispatched_loop.QuitClosure()); |
| 435 |
| 436 std::vector<ServiceWorkerFetchRequest> requests; |
| 437 requests.push_back(CreateRequestWithProvidedResponse( |
| 438 "GET", "https://example.com/funny_cat.txt", 200 /* status_code */, |
| 439 "This text describes a scenario involving a funny cat.")); |
| 440 requests.push_back(CreateRequestWithProvidedResponse( |
| 441 "GET", "https://example.com/crazy_cat.txt", 200 /* status_code */, |
| 442 "This text descrubes a scenario involving a crazy cat.")); |
| 443 |
| 444 // Create the registration with the given |requests|. |
| 445 { |
| 446 BackgroundFetchOptions options; |
| 447 |
| 448 blink::mojom::BackgroundFetchError error; |
| 449 BackgroundFetchRegistration registration; |
| 450 |
| 451 // Create the first registration. This must succeed. |
| 452 ASSERT_NO_FATAL_FAILURE( |
| 453 Fetch(registration_id, requests, options, &error, ®istration)); |
| 454 ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); |
| 455 } |
| 456 |
| 457 // Spin the |event_dispatched_loop| to wait for the dispatched event. |
| 458 event_dispatched_loop.Run(); |
| 459 |
| 460 ASSERT_TRUE(embedded_worker_test_helper()->last_tag().has_value()); |
| 461 EXPECT_EQ(kExampleTag, embedded_worker_test_helper()->last_tag().value()); |
| 462 |
| 463 ASSERT_TRUE(embedded_worker_test_helper()->last_fetches().has_value()); |
| 464 |
| 465 std::vector<BackgroundFetchSettledFetch> fetches = |
| 466 embedded_worker_test_helper()->last_fetches().value(); |
| 467 ASSERT_EQ(fetches.size(), requests.size()); |
| 468 |
| 469 for (size_t i = 0; i < fetches.size(); ++i) { |
| 470 ASSERT_EQ(fetches[i].request.url, requests[i].url); |
| 471 EXPECT_EQ(fetches[i].request.method, requests[i].method); |
| 472 |
| 473 EXPECT_EQ(fetches[i].request.url, fetches[i].response.url_list[0]); |
| 474 |
| 475 // TODO(peter): change-detector tests for unsupported properties. |
| 476 EXPECT_EQ(fetches[i].response.status_code, 0); |
| 477 EXPECT_TRUE(fetches[i].response.status_text.empty()); |
| 478 EXPECT_EQ(fetches[i].response.response_type, |
| 479 blink::WebServiceWorkerResponseTypeOpaque); |
| 480 EXPECT_TRUE(fetches[i].response.headers.empty()); |
| 481 EXPECT_EQ(fetches[i].response.error, |
| 482 blink::WebServiceWorkerResponseErrorUnknown); |
| 483 EXPECT_TRUE(fetches[i].response.response_time.is_null()); |
| 484 |
| 485 // TODO(peter): Change-detector tests for when bodies are supported. |
| 486 EXPECT_TRUE(fetches[i].response.blob_uuid.empty()); |
| 487 EXPECT_EQ(fetches[i].response.blob_size, 0u); |
| 488 } |
| 489 } |
| 490 |
| 310 TEST_F(BackgroundFetchServiceTest, Abort) { | 491 TEST_F(BackgroundFetchServiceTest, Abort) { |
| 311 // This test starts a new Background Fetch, completes the registration, and | 492 // This test starts a new Background Fetch, completes the registration, and |
| 312 // then aborts the Background Fetch mid-process. Tests all of StartFetch(), | 493 // then aborts the Background Fetch mid-process. Tests all of StartFetch(), |
| 313 // GetActiveFetches() and GetActiveTagsForServiceWorkerRegistration(). | 494 // GetActiveFetches() and GetActiveTagsForServiceWorkerRegistration(). |
| 314 | 495 |
| 315 BackgroundFetchRegistrationId registration_id; | 496 BackgroundFetchRegistrationId registration_id; |
| 316 ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); | 497 ASSERT_TRUE(CreateRegistrationId(kExampleTag, ®istration_id)); |
| 317 | 498 |
| 318 std::vector<ServiceWorkerFetchRequest> requests; | 499 std::vector<ServiceWorkerFetchRequest> requests; |
| 319 requests.emplace_back(); // empty, but valid | 500 requests.emplace_back(); // empty, but valid |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 const bool has_alternative_tag = | 616 const bool has_alternative_tag = |
| 436 tags[0] == kAlternativeTag || tags[1] == kAlternativeTag; | 617 tags[0] == kAlternativeTag || tags[1] == kAlternativeTag; |
| 437 | 618 |
| 438 EXPECT_TRUE(has_example_tag); | 619 EXPECT_TRUE(has_example_tag); |
| 439 EXPECT_TRUE(has_alternative_tag); | 620 EXPECT_TRUE(has_alternative_tag); |
| 440 } | 621 } |
| 441 } | 622 } |
| 442 | 623 |
| 443 } // namespace | 624 } // namespace |
| 444 } // namespace content | 625 } // namespace content |
| OLD | NEW |