Index: content/browser/service_worker/service_worker_browsertest.cc |
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc |
index 443c87d0bcd6448cf994357501e15194f8986065..8e77613a746ceb688951c5040f9857d598a08f89 100644 |
--- a/content/browser/service_worker/service_worker_browsertest.cc |
+++ b/content/browser/service_worker/service_worker_browsertest.cc |
@@ -62,15 +62,21 @@ void RunAndQuit(const base::Closure& closure, |
original_message_loop->PostTask(FROM_HERE, quit); |
} |
-void RunOnIOThread(const base::Closure& closure) { |
+void RunOnIOThreadWithDelay(const base::Closure& closure, |
+ base::TimeDelta delay) { |
base::RunLoop run_loop; |
- BrowserThread::PostTask( |
+ BrowserThread::PostDelayedTask( |
BrowserThread::IO, FROM_HERE, |
base::Bind(&RunAndQuit, closure, run_loop.QuitClosure(), |
- base::MessageLoopProxy::current())); |
+ base::MessageLoopProxy::current()), |
+ delay); |
run_loop.Run(); |
} |
+void RunOnIOThread(const base::Closure& closure) { |
+ RunOnIOThreadWithDelay(closure, base::TimeDelta()); |
+} |
+ |
void RunOnIOThread( |
const base::Callback<void(const base::Closure& continuation)>& closure) { |
base::RunLoop run_loop; |
@@ -522,6 +528,12 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { |
AssociateRendererProcessToPattern(pattern); |
} |
+ void TimeoutWorkerOnIOThread() { |
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ version_->PingWorker(); |
+ version_->OnPingTimeout(); |
+ } |
+ |
void StartOnIOThread(const base::Closure& done, |
ServiceWorkerStatusCode* result) { |
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
@@ -699,6 +711,78 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, |
SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED); |
} |
+class WaitForLoaded : public EmbeddedWorkerInstance::Listener { |
+ public: |
+ WaitForLoaded(const base::Closure& quit) : quit_(quit) {} |
+ |
+ void OnScriptLoaded() override { |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_); |
+ } |
+ bool OnMessageReceived(const IPC::Message& message) override { return false; } |
+ |
+ private: |
+ base::Closure quit_; |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) { |
+ RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, this, |
+ "/service_worker/while_true_worker.js")); |
+ |
+ // Start a worker, waiting until the script is loaded. |
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; |
+ base::RunLoop start_run_loop; |
+ base::RunLoop load_run_loop; |
+ WaitForLoaded wait_for_load(load_run_loop.QuitClosure()); |
+ version_->embedded_worker()->AddListener(&wait_for_load); |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&self::StartOnIOThread, this, |
+ start_run_loop.QuitClosure(), &status)); |
+ load_run_loop.Run(); |
+ version_->embedded_worker()->RemoveListener(&wait_for_load); |
+ |
+ // The script has loaded but start has not completed yet. |
+ ASSERT_EQ(SERVICE_WORKER_ERROR_FAILED, status); |
+ EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status()); |
+ |
+ // Simulate execution timeout. Use a delay to prevent killing the worker |
+ // before it's started execution. |
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning()); |
+ RunOnIOThreadWithDelay(base::Bind(&self::TimeoutWorkerOnIOThread, this), |
+ base::TimeDelta::FromMilliseconds(100)); |
+ start_run_loop.Run(); |
+ |
+ EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) { |
+ RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, this, |
+ "/service_worker/while_true_in_install_worker.js")); |
+ |
+ // Start a worker. |
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; |
+ base::RunLoop start_run_loop; |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&self::StartOnIOThread, this, |
+ start_run_loop.QuitClosure(), &status)); |
+ start_run_loop.Run(); |
+ ASSERT_EQ(SERVICE_WORKER_OK, status); |
+ |
+ // Dispatch an event. |
+ base::RunLoop install_run_loop; |
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
+ base::Bind(&self::InstallOnIOThread, this, |
+ install_run_loop.QuitClosure(), &status)); |
+ |
+ // Simulate execution timeout. Use a delay to prevent killing the worker |
+ // before it's started execution. |
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning()); |
+ RunOnIOThreadWithDelay(base::Bind(&self::TimeoutWorkerOnIOThread, this), |
+ base::TimeDelta::FromMilliseconds(100)); |
+ install_run_loop.Run(); |
+ |
+ EXPECT_EQ(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED, status); |
+} |
+ |
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) { |
ServiceWorkerFetchEventResult result; |
ServiceWorkerResponse response; |