| Index: content/browser/service_worker/embedded_worker_instance_unittest.cc
|
| diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc
|
| index 727fcca1f8208fd03ce9bba3f5d5ba1833509d3f..9afe0ee664dbdfa59017de43d08ed47a43a4f071 100644
|
| --- a/content/browser/service_worker/embedded_worker_instance_unittest.cc
|
| +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
|
| @@ -21,8 +21,11 @@ namespace {
|
|
|
| const int kRenderProcessId = 11;
|
|
|
| -void SaveStatus(ServiceWorkerStatusCode* out, ServiceWorkerStatusCode status) {
|
| - *out = status;
|
| +void DestroyWorker(scoped_ptr<EmbeddedWorkerInstance> worker,
|
| + ServiceWorkerStatusCode* out_status,
|
| + ServiceWorkerStatusCode status) {
|
| + *out_status = status;
|
| + worker.reset();
|
| }
|
|
|
| void SaveStatusAndCall(ServiceWorkerStatusCode* out,
|
| @@ -40,6 +43,11 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
|
| EmbeddedWorkerInstanceTest()
|
| : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
|
|
|
| + void OnStopped(EmbeddedWorkerInstance::Status old_status) override {
|
| + stopped_ = true;
|
| + stopped_old_status_ = old_status;
|
| + }
|
| +
|
| void OnDetached(EmbeddedWorkerInstance::Status old_status) override {
|
| detached_ = true;
|
| detached_old_status_ = old_status;
|
| @@ -79,11 +87,26 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
|
| bool detached_ = false;
|
| EmbeddedWorkerInstance::Status detached_old_status_ =
|
| EmbeddedWorkerInstance::STOPPED;
|
| + bool stopped_ = false;
|
| + EmbeddedWorkerInstance::Status stopped_old_status_ =
|
| + EmbeddedWorkerInstance::STOPPED;
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest);
|
| };
|
|
|
| +class FailToSendIPCHelper : public EmbeddedWorkerTestHelper {
|
| + public:
|
| + FailToSendIPCHelper()
|
| + : EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId) {}
|
| + ~FailToSendIPCHelper() override {}
|
| +
|
| + bool Send(IPC::Message* message) override {
|
| + delete message;
|
| + return false;
|
| + }
|
| +};
|
| +
|
| TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
|
| scoped_ptr<EmbeddedWorkerInstance> worker =
|
| embedded_worker_registry()->CreateWorker();
|
| @@ -232,14 +255,34 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
|
| TEST_F(EmbeddedWorkerInstanceTest, DetachDuringStart) {
|
| scoped_ptr<EmbeddedWorkerInstance> worker =
|
| embedded_worker_registry()->CreateWorker();
|
| + worker->AddListener(this);
|
| +
|
| scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
|
| new EmbeddedWorkerMsg_StartWorker_Params());
|
| ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| - // Pretend we had a process allocated but then got detached before
|
| - // the start sequence reached SendStartWorker.
|
| - worker->process_id_ = -1;
|
| - worker->SendStartWorker(params.Pass(), base::Bind(&SaveStatus, &status), true,
|
| - -1, false);
|
| +
|
| + // Pretend the worker got stopped before the start sequence reached
|
| + // SendStartWorker.
|
| + worker->status_ = EmbeddedWorkerInstance::STOPPED;
|
| + base::RunLoop run_loop;
|
| + worker->SendStartWorker(params.Pass(), base::Bind(&SaveStatusAndCall, &status,
|
| + run_loop.QuitClosure()),
|
| + true, -1, false);
|
| + run_loop.Run();
|
| + EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
|
| + // Don't expect SendStartWorker() to dispatch an OnStopped/Detached() message
|
| + // since the worker was already stopped.
|
| + EXPECT_FALSE(stopped_);
|
| + EXPECT_FALSE(detached_);
|
| +
|
| + // Repeat, this time have the start callback destroy the worker, as is
|
| + // usual when starting a worker fails, and ensure a crash doesn't occur.
|
| + worker->status_ = EmbeddedWorkerInstance::STOPPED;
|
| + EmbeddedWorkerInstance* worker_ptr = worker.get();
|
| + worker_ptr->SendStartWorker(
|
| + params.Pass(), base::Bind(&DestroyWorker, base::Passed(&worker), &status),
|
| + true, -1, false);
|
| + // No crash.
|
| EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
|
| }
|
|
|
| @@ -249,8 +292,6 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringStart) {
|
| scoped_ptr<EmbeddedWorkerInstance> worker =
|
| embedded_worker_registry()->CreateWorker();
|
| worker->AddListener(this);
|
| - scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
|
| - new EmbeddedWorkerMsg_StartWorker_Params());
|
| // Pretend we stop during starting before we got a process allocated.
|
| worker->status_ = EmbeddedWorkerInstance::STARTING;
|
| worker->process_id_ = -1;
|
| @@ -260,4 +301,31 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringStart) {
|
| EXPECT_EQ(EmbeddedWorkerInstance::STARTING, detached_old_status_);
|
| }
|
|
|
| +// Test for when sending the start IPC failed.
|
| +TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
|
| + helper_.reset(new FailToSendIPCHelper());
|
| +
|
| + const int64 version_id = 55L;
|
| + const GURL pattern("http://example.com/");
|
| + const GURL url("http://example.com/worker.js");
|
| +
|
| + scoped_ptr<EmbeddedWorkerInstance> worker =
|
| + embedded_worker_registry()->CreateWorker();
|
| + helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
|
| + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| + worker->AddListener(this);
|
| +
|
| + // Attempt to start the worker.
|
| + base::RunLoop run_loop;
|
| + worker->Start(
|
| + version_id, pattern, url,
|
| + base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| +
|
| + // The callback should have run, and we should have got an OnStopped message.
|
| + EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, status);
|
| + EXPECT_TRUE(stopped_);
|
| + EXPECT_EQ(EmbeddedWorkerInstance::STARTING, stopped_old_status_);
|
| +}
|
| +
|
| } // namespace content
|
|
|