Commit 5c5b274f authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

service worker: Add blob test for ServiceWorkerURLLoaderJob.

Bug: 748416
Change-Id: I37d13c799e61fff05bc75675a888ce2630995aa0
Reviewed-on: https://chromium-review.googlesource.com/597576
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491651}
parent 2359bbad
......@@ -13,9 +13,11 @@
#include "content/public/common/resource_response.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_url_loader_client.h"
#include "mojo/common/data_pipe_utils.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/modules/fetch/fetch_api_request.mojom.h"
......@@ -31,6 +33,65 @@ void ReceiveStartLoaderCallback(StartLoaderCallback* out_callback,
} // namespace
// Helper simulates a service worker handling fetch events. The response can be
// customized via RespondWith* functions.
class Helper : public EmbeddedWorkerTestHelper {
public:
Helper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~Helper() override = default;
// Tells this helper to respond to fetch events with the specified blob.
void RespondWithBlob(const std::string blob_uuid, uint64_t blob_size) {
response_mode_ = ResponseMode::kBlob;
blob_uuid_ = blob_uuid;
blob_size_ = blob_size;
}
protected:
void OnFetchEvent(
int embedded_worker_id,
int fetch_event_id,
const ServiceWorkerFetchRequest& request,
mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
FetchCallback finish_callback) override {
switch (response_mode_) {
case ResponseMode::kDefault:
EmbeddedWorkerTestHelper::OnFetchEvent(
embedded_worker_id, fetch_event_id, request,
std::move(preload_handle), std::move(response_callback),
std::move(finish_callback));
return;
case ResponseMode::kBlob:
response_callback->OnResponse(
ServiceWorkerResponse(
base::MakeUnique<std::vector<GURL>>(), 200, "OK",
blink::mojom::FetchResponseType::kDefault,
base::MakeUnique<ServiceWorkerHeaderMap>(), blob_uuid_,
blob_size_, nullptr /* blob */,
blink::kWebServiceWorkerResponseErrorUnknown, base::Time(),
false /* response_is_in_cache_storage */,
std::string() /* response_cache_storage_cache_name */,
base::MakeUnique<
ServiceWorkerHeaderList>() /* cors_exposed_header_names */),
base::Time::Now());
std::move(finish_callback).Run(SERVICE_WORKER_OK, base::Time::Now());
return;
}
NOTREACHED();
}
private:
enum class ResponseMode { kDefault, kBlob };
ResponseMode response_mode_ = ResponseMode::kDefault;
// For ResponseMode::kBlob.
std::string blob_uuid_;
uint64_t blob_size_ = 0;
DISALLOW_COPY_AND_ASSIGN(Helper);
};
// ServiceWorkerURLLoaderJobTest is for testing the handling of requests
// by a service worker via ServiceWorkerURLLoaderJob.
//
......@@ -48,7 +109,7 @@ class ServiceWorkerURLLoaderJobTest
public:
ServiceWorkerURLLoaderJobTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
helper_(base::MakeUnique<EmbeddedWorkerTestHelper>(base::FilePath())) {}
helper_(base::MakeUnique<Helper>()) {}
~ServiceWorkerURLLoaderJobTest() override = default;
void SetUp() override {
......@@ -77,8 +138,6 @@ class ServiceWorkerURLLoaderJobTest
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
ASSERT_EQ(SERVICE_WORKER_OK, status);
// TODO(falken): Also setup blob_context_ for tests that will need it.
}
ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
......@@ -87,6 +146,46 @@ class ServiceWorkerURLLoaderJobTest
return blob_context_.AsWeakPtr();
}
// Performs a request. When this returns, |client_| will have information
// about the response.
void TestRequest() {
ResourceRequest request;
request.url = GURL("https://www.example.com/");
request.method = "GET";
// Start a ServiceWorkerURLLoaderJob. It should return a
// StartLoaderCallback.
StartLoaderCallback callback;
auto job = base::MakeUnique<ServiceWorkerURLLoaderJob>(
base::BindOnce(&ReceiveStartLoaderCallback, &callback), this, request,
GetBlobStorageContext());
job->ForwardToServiceWorker();
base::RunLoop().RunUntilIdle();
// TODO(falken): When fallback to network tests are added,
// callback can be null. In that case this function should return cleanly
// and somehow tell the caller we're falling back to network.
EXPECT_FALSE(callback.is_null());
// Start the loader. It will load |request.url|.
mojom::URLLoaderPtr loader;
std::move(callback).Run(mojo::MakeRequest(&loader),
client_.CreateInterfacePtr());
client_.RunUntilComplete();
}
void ExpectFetchedViaServiceWorker(const ResourceResponseHead& info) {
EXPECT_TRUE(info.was_fetched_via_service_worker);
EXPECT_FALSE(info.was_fallback_required_by_service_worker);
EXPECT_TRUE(info.url_list_via_service_worker.empty());
EXPECT_EQ(blink::mojom::FetchResponseType::kDefault,
info.response_type_via_service_worker);
// TODO(falken): start and ready time should be set.
EXPECT_TRUE(info.service_worker_start_time.is_null());
EXPECT_TRUE(info.service_worker_ready_time.is_null());
EXPECT_FALSE(info.is_in_cache_storage);
EXPECT_EQ(std::string(), info.cache_storage_cache_name);
}
protected:
// ServiceWorkerURLLoaderJob::Delegate --------------------------------------
void OnPrepareToRestart() override {}
......@@ -105,47 +204,45 @@ class ServiceWorkerURLLoaderJobTest
// --------------------------------------------------------------------------
TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
std::unique_ptr<Helper> helper_;
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
storage::BlobStorageContext blob_context_;
TestURLLoaderClient client_;
};
TEST_F(ServiceWorkerURLLoaderJobTest, Basic) {
ResourceRequest request;
request.url = GURL("https://www.example.com/");
request.method = "GET";
// Start a ServiceWorkerURLLoaderJob. It should return a StartLoaderCallback.
StartLoaderCallback callback;
auto job = base::MakeUnique<ServiceWorkerURLLoaderJob>(
base::BindOnce(&ReceiveStartLoaderCallback, &callback), this, request,
GetBlobStorageContext());
job->ForwardToServiceWorker();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(callback.is_null());
// Start the loader. It will load the URL.
TestURLLoaderClient client;
mojom::URLLoaderPtr loader;
std::move(callback).Run(mojo::MakeRequest(&loader),
client.CreateInterfacePtr());
client.RunUntilComplete();
EXPECT_EQ(net::OK, client.completion_status().error_code);
// The URL should have loaded successfully via service worker.
const ResourceResponseHead& info = client.response_head();
TestRequest();
EXPECT_EQ(net::OK, client_.completion_status().error_code);
const ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code());
EXPECT_TRUE(info.was_fetched_via_service_worker);
EXPECT_FALSE(info.was_fallback_required_by_service_worker);
EXPECT_TRUE(info.url_list_via_service_worker.empty());
EXPECT_EQ(blink::mojom::FetchResponseType::kDefault,
info.response_type_via_service_worker);
// TODO(falken): start and ready time should be set.
EXPECT_TRUE(info.service_worker_start_time.is_null());
EXPECT_TRUE(info.service_worker_ready_time.is_null());
EXPECT_FALSE(info.is_in_cache_storage);
EXPECT_EQ(std::string(), info.cache_storage_cache_name);
ExpectFetchedViaServiceWorker(info);
}
TEST_F(ServiceWorkerURLLoaderJobTest, BlobResponse) {
// Construct the blob to respond with.
const std::string kResponseBody = "Here is sample text for the blob.";
auto blob_data = base::MakeUnique<storage::BlobDataBuilder>("blob-id:myblob");
blob_data->AppendData(kResponseBody);
std::unique_ptr<storage::BlobDataHandle> blob_handle =
blob_context_.AddFinishedBlob(blob_data.get());
helper_->RespondWithBlob(blob_handle->uuid(), blob_handle->size());
// Perform the request.
TestRequest();
const ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code());
ExpectFetchedViaServiceWorker(info);
// Test the body.
std::string response;
EXPECT_TRUE(client_.response_body().is_valid());
EXPECT_TRUE(mojo::common::BlockingCopyToString(
client_.response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
}
// TODO(falken): Add tests for stream response, network fallback, etc. Basically
// everything in ServiceWorkerURLRequestJobTest.
} // namespace content
......@@ -788,7 +788,7 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
: EmbeddedWorkerTestHelper(base::FilePath()),
blob_uuid_(blob_uuid),
blob_size_(blob_size) {}
~BlobResponder() override {}
~BlobResponder() override = default;
protected:
void OnFetchEvent(
......
......@@ -162,6 +162,7 @@ struct CONTENT_EXPORT ServiceWorkerResponse {
// ServiceWorkerFetchResponseCallback.
std::string blob_uuid;
uint64_t blob_size;
// |blob| is only used when features::kMojoBlobs is enabled.
scoped_refptr<storage::BlobHandle> blob;
blink::WebServiceWorkerResponseError error;
base::Time response_time;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment