Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: content/browser/service_worker/service_worker_version_unittest.cc

Issue 912753002: Stop Service Workers that execute JavaScript for too long. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase? Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/service_worker/service_worker_version_unittest.cc
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index 40115716a72512acd92acf5ded87ebbef8ae7b0f..d2d9ae21018b6b383c9e5ac1202c28e28e5aca37 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -187,6 +187,70 @@ class ServiceWorkerFailToStartTest : public ServiceWorkerVersionTest {
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerFailToStartTest);
};
+class MessageReceiverHangAtScriptEvaluation : public MessageReceiver {
+ public:
+ MessageReceiverHangAtScriptEvaluation() : MessageReceiver() {}
+ ~MessageReceiverHangAtScriptEvaluation() override {}
+
+ void OnStartWorker(int embedded_worker_id,
+ int64 service_worker_version_id,
+ const GURL& scope,
+ const GURL& script_url,
+ bool pause_after_download) override {
+ if (pause_after_download) {
+ SimulatePausedAfterDownload(embedded_worker_id);
+ return;
+ }
+ SimulateWorkerReadyForInspection(embedded_worker_id);
+ SimulateWorkerScriptLoaded(next_thread_id_++, embedded_worker_id);
+ // To simulate while(true) {} in the script, don't call the following:
+ // SimulateWorkerScriptEvaluated(embedded_worker_id);
+ // SimulateWorkerStarted(embedded_worker_id);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MessageReceiverHangAtScriptEvaluation);
+};
+
+class MessageReceiverHangAtInstall : public MessageReceiver {
+ public:
+ MessageReceiverHangAtInstall() : MessageReceiver() {}
+ ~MessageReceiverHangAtInstall() override {}
+
+ void OnInstallEvent(int embedded_worker_id,
+ int request_id,
+ int active_version_id) override {
+ // Do nothing.
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MessageReceiverHangAtInstall);
+};
+
+class ServiceWorkerStartTimeoutTest : public ServiceWorkerVersionTest {
+ protected:
+ ServiceWorkerStartTimeoutTest() : ServiceWorkerVersionTest() {}
+
+ scoped_ptr<MessageReceiver> GetMessageReceiver() override {
+ return make_scoped_ptr(new MessageReceiverHangAtScriptEvaluation());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStartTimeoutTest);
+};
+
+class ServiceWorkerEventTimeoutTest : public ServiceWorkerVersionTest {
+ protected:
+ ServiceWorkerEventTimeoutTest() : ServiceWorkerVersionTest() {}
+
+ scoped_ptr<MessageReceiver> GetMessageReceiver() override {
+ return make_scoped_ptr(new MessageReceiverHangAtInstall());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerEventTimeoutTest);
+};
+
TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
// Call StartWorker() multiple times.
ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
@@ -442,4 +506,59 @@ TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
}
+// Test starting a "while(true) {}" worker. StartWorker should timeout.
+TEST_F(ServiceWorkerStartTimeoutTest, ScriptEvaluationTimeout) {
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+
+ // The start callback has not completed yet.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status);
+ EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
+
+ // The pings have started.
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning());
+
+ // Simulate timing out.
+ version_->PingWorker();
+ version_->OnPingTimeout();
+ base::RunLoop().RunUntilIdle();
+
+ // The start callback should have completed with failure.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+}
+
+// Test "while(true) {}" after successful startup (e.g., in an event
+// handler). The worker should be stopped.
+TEST_F(ServiceWorkerEventTimeoutTest, EventTimeout) {
+ ServiceWorkerStatusCode status;
+ version_->StartWorker(CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(SERVICE_WORKER_OK, status);
+
+ // The pings have started.
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning());
+
+ // Simulate a successful ping.
+ version_->PingWorker();
+ version_->OnPongFromWorker();
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning());
+
+ // Dispatch an event.
+ version_->SetStatus(ServiceWorkerVersion::INSTALLING);
+ version_->DispatchInstallEvent(0, CreateReceiverOnCurrentThread(&status));
+
+ // Simulate timing out.
+ EXPECT_TRUE(version_->ping_worker_timer_.IsRunning());
+ version_->PingWorker();
+ version_->OnPingTimeout();
+ base::RunLoop().RunUntilIdle();
+
+ // The event callback should have completed with failure.
+ EXPECT_EQ(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED, status);
+ EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698