Commit 096b36b4 authored by Emi Morikawa's avatar Emi Morikawa Committed by Commit Bot

Add more ServiceWorkerURLLoaderJob tests: fallback and fetch event dispatch failure.

Bug: 748416
Change-Id: I0e8050ef5f25bd5224f555d6c4499dd5e14b2ce8
Reviewed-on: https://chromium-review.googlesource.com/623017
Commit-Queue: Emi Morikawa <emim@google.com>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#496616}
parent 18fdc89d
...@@ -57,6 +57,16 @@ class Helper : public EmbeddedWorkerTestHelper { ...@@ -57,6 +57,16 @@ class Helper : public EmbeddedWorkerTestHelper {
stream_handle_->stream = std::move(consumer_handle); stream_handle_->stream = std::move(consumer_handle);
} }
// Tells this helper to respond to fetch events with network fallback.
// i.e.,simulate the service worker not calling respondWith().
void RespondWithFallback() { response_mode_ = ResponseMode::kFallback; }
// Tells this helper to simulate failure to dispatch the fetch event to the
// service worker.
void FailToDispatchFetchEvent() {
response_mode_ = ResponseMode::kFailFetchEventDispatch;
}
protected: protected:
void OnFetchEvent( void OnFetchEvent(
int embedded_worker_id, int embedded_worker_id,
...@@ -102,12 +112,37 @@ class Helper : public EmbeddedWorkerTestHelper { ...@@ -102,12 +112,37 @@ class Helper : public EmbeddedWorkerTestHelper {
std::move(stream_handle_), base::Time::Now()); std::move(stream_handle_), base::Time::Now());
std::move(finish_callback).Run(SERVICE_WORKER_OK, base::Time::Now()); std::move(finish_callback).Run(SERVICE_WORKER_OK, base::Time::Now());
return; return;
case ResponseMode::kFallback:
response_callback->OnFallback(base::Time::Now());
std::move(finish_callback).Run(SERVICE_WORKER_OK, base::Time::Now());
return;
case ResponseMode::kFailFetchEventDispatch:
// Simulate failure by stopping the worker before the event finishes.
// This causes ServiceWorkerVersion::StartRequest() to call its error
// callback, which triggers ServiceWorkerURLLoaderJob's dispatch failed
// behavior.
SimulateWorkerStopped(embedded_worker_id);
// Finish the event by calling |finish_callback|.
// This is the Mojo callback for
// mojom::ServiceWorkerEventDispatcher::DispatchFetchEvent().
// If this is not called, Mojo will complain. In production code,
// ServiceWorkerContextClient would call this when it aborts all
// callbacks after an unexpected stop.
std::move(finish_callback)
.Run(SERVICE_WORKER_ERROR_ABORT, base::Time::Now());
return;
} }
NOTREACHED(); NOTREACHED();
} }
private: private:
enum class ResponseMode { kDefault, kBlob, kStream }; enum class ResponseMode {
kDefault,
kBlob,
kStream,
kFallback,
kFailFetchEventDispatch
};
ResponseMode response_mode_ = ResponseMode::kDefault; ResponseMode response_mode_ = ResponseMode::kDefault;
// For ResponseMode::kBlob. // For ResponseMode::kBlob.
...@@ -174,9 +209,16 @@ class ServiceWorkerURLLoaderJobTest ...@@ -174,9 +209,16 @@ class ServiceWorkerURLLoaderJobTest
return blob_context_.AsWeakPtr(); return blob_context_.AsWeakPtr();
} }
// Indicates whether ServiceWorkerURLLoaderJob decided to handle a request,
// i.e., it returned a non-null StartLoaderCallback for the request.
enum class JobResult {
kHandledRequest,
kDidNotHandleRequest,
};
// Performs a request. When this returns, |client_| will have information // Performs a request. When this returns, |client_| will have information
// about the response. // about the response.
void TestRequest() { JobResult TestRequest() {
ResourceRequest request; ResourceRequest request;
request.url = GURL("https://www.example.com/"); request.url = GURL("https://www.example.com/");
request.method = "GET"; request.method = "GET";
...@@ -189,16 +231,16 @@ class ServiceWorkerURLLoaderJobTest ...@@ -189,16 +231,16 @@ class ServiceWorkerURLLoaderJobTest
GetBlobStorageContext()); GetBlobStorageContext());
job->ForwardToServiceWorker(); job->ForwardToServiceWorker();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
// TODO(falken): When fallback to network tests are added, if (!callback)
// callback can be null. In that case this function should return cleanly return JobResult::kDidNotHandleRequest;
// and somehow tell the caller we're falling back to network.
EXPECT_FALSE(callback.is_null());
// Start the loader. It will load |request.url|. // Start the loader. It will load |request.url|.
mojom::URLLoaderPtr loader; mojom::URLLoaderPtr loader;
std::move(callback).Run(mojo::MakeRequest(&loader), std::move(callback).Run(mojo::MakeRequest(&loader),
client_.CreateInterfacePtr()); client_.CreateInterfacePtr());
client_.RunUntilComplete(); client_.RunUntilComplete();
return JobResult::kHandledRequest;
} }
void ExpectFetchedViaServiceWorker(const ResourceResponseHead& info) { void ExpectFetchedViaServiceWorker(const ResourceResponseHead& info) {
...@@ -228,7 +270,9 @@ class ServiceWorkerURLLoaderJobTest ...@@ -228,7 +270,9 @@ class ServiceWorkerURLLoaderJobTest
return true; return true;
} }
void MainResourceLoadFailed() override {} void MainResourceLoadFailed() override {
was_main_resource_load_failed_called_ = true;
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
TestBrowserThreadBundle thread_bundle_; TestBrowserThreadBundle thread_bundle_;
...@@ -237,10 +281,12 @@ class ServiceWorkerURLLoaderJobTest ...@@ -237,10 +281,12 @@ class ServiceWorkerURLLoaderJobTest
scoped_refptr<ServiceWorkerVersion> version_; scoped_refptr<ServiceWorkerVersion> version_;
storage::BlobStorageContext blob_context_; storage::BlobStorageContext blob_context_;
TestURLLoaderClient client_; TestURLLoaderClient client_;
bool was_main_resource_load_failed_called_ = false;
}; };
TEST_F(ServiceWorkerURLLoaderJobTest, Basic) { TEST_F(ServiceWorkerURLLoaderJobTest, Basic) {
TestRequest(); JobResult result = TestRequest();
EXPECT_EQ(JobResult::kHandledRequest, result);
EXPECT_EQ(net::OK, client_.completion_status().error_code); EXPECT_EQ(net::OK, client_.completion_status().error_code);
const ResourceResponseHead& info = client_.response_head(); const ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code()); EXPECT_EQ(200, info.headers->response_code());
...@@ -257,7 +303,8 @@ TEST_F(ServiceWorkerURLLoaderJobTest, BlobResponse) { ...@@ -257,7 +303,8 @@ TEST_F(ServiceWorkerURLLoaderJobTest, BlobResponse) {
helper_->RespondWithBlob(blob_handle->uuid(), blob_handle->size()); helper_->RespondWithBlob(blob_handle->uuid(), blob_handle->size());
// Perform the request. // Perform the request.
TestRequest(); JobResult result = TestRequest();
EXPECT_EQ(JobResult::kHandledRequest, result);
const ResourceResponseHead& info = client_.response_head(); const ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code()); EXPECT_EQ(200, info.headers->response_code());
ExpectFetchedViaServiceWorker(info); ExpectFetchedViaServiceWorker(info);
...@@ -279,16 +326,17 @@ TEST_F(ServiceWorkerURLLoaderJobTest, StreamResponse) { ...@@ -279,16 +326,17 @@ TEST_F(ServiceWorkerURLLoaderJobTest, StreamResponse) {
std::move(data_pipe.consumer_handle)); std::move(data_pipe.consumer_handle));
// Perform the request. // Perform the request.
TestRequest(); JobResult result = TestRequest();
EXPECT_EQ(JobResult::kHandledRequest, result);
const ResourceResponseHead& info = client_.response_head(); const ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code()); EXPECT_EQ(200, info.headers->response_code());
ExpectFetchedViaServiceWorker(info); ExpectFetchedViaServiceWorker(info);
// Write the body stream. // Write the body stream.
uint32_t written_bytes = sizeof(kResponseBody) - 1; uint32_t written_bytes = sizeof(kResponseBody) - 1;
MojoResult result = data_pipe.producer_handle->WriteData( MojoResult mojo_result = data_pipe.producer_handle->WriteData(
kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE); kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
ASSERT_EQ(MOJO_RESULT_OK, result); ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes); EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
stream_callback->OnCompleted(); stream_callback->OnCompleted();
data_pipe.producer_handle.reset(); data_pipe.producer_handle.reset();
...@@ -301,4 +349,28 @@ TEST_F(ServiceWorkerURLLoaderJobTest, StreamResponse) { ...@@ -301,4 +349,28 @@ TEST_F(ServiceWorkerURLLoaderJobTest, StreamResponse) {
EXPECT_EQ(kResponseBody, response); EXPECT_EQ(kResponseBody, response);
} }
// Test when the service worker responds with network fallback.
// i.e., does not call respondWith().
TEST_F(ServiceWorkerURLLoaderJobTest, Fallback) {
helper_->RespondWithFallback();
// Perform the request.
JobResult result = TestRequest();
EXPECT_EQ(JobResult::kDidNotHandleRequest, result);
// The request should not be handled by the job, but it shouldn't be a
// failure.
EXPECT_FALSE(was_main_resource_load_failed_called_);
}
// Test when dispatching the fetch event to the service worker failed.
TEST_F(ServiceWorkerURLLoaderJobTest, FailFetchDispatch) {
helper_->FailToDispatchFetchEvent();
// Perform the request.
JobResult result = TestRequest();
EXPECT_EQ(JobResult::kDidNotHandleRequest, result);
EXPECT_TRUE(was_main_resource_load_failed_called_);
}
} // namespace content } // namespace content
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