Chromium Code Reviews| 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 20976748db6df08a660c6cb8c21fdffd38d8b0a1..a5cf9468bc8be0fd7fdf106a6dcf4f1cc7fc0149 100644 |
| --- a/content/browser/service_worker/embedded_worker_instance_unittest.cc |
| +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc |
| @@ -17,13 +17,11 @@ |
| #include "content/browser/service_worker/embedded_worker_test_helper.h" |
| #include "content/browser/service_worker/service_worker_context_core.h" |
| #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| -#include "content/common/service_worker/embedded_worker.mojom.h" |
| #include "content/common/service_worker/embedded_worker_messages.h" |
| #include "content/common/service_worker/embedded_worker_start_params.h" |
| #include "content/public/common/child_process_host.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| -#include "mojo/public/cpp/bindings/strong_binding.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -31,6 +29,8 @@ namespace content { |
| namespace { |
| +void NoOpStatusCallback(ServiceWorkerStatusCode code) {} |
| + |
| void SaveStatusAndCall(ServiceWorkerStatusCode* out, |
| const base::Closure& callback, |
| ServiceWorkerStatusCode status) { |
| @@ -119,6 +119,12 @@ class EmbeddedWorkerInstanceTest : public testing::Test, |
| IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } |
| + std::vector<std::unique_ptr< |
| + EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient>>* |
| + mock_instance_clients() { |
| + return helper_->mock_instance_clients(); |
| + } |
| + |
| TestBrowserThreadBundle thread_bundle_; |
| std::unique_ptr<EmbeddedWorkerTestHelper> helper_; |
| std::vector<EventLog> events_; |
| @@ -228,10 +234,9 @@ TEST_P(EmbeddedWorkerInstanceTestP, StartAndStop) { |
| // Verify that we've sent two messages to start and terminate the worker. |
| ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( |
| EmbeddedWorkerMsg_StartWorker::ID)); |
| + ASSERT_TRUE( |
|
horo
2016/09/13 08:25:33
Keep this comment.
// StopWorker should be sent i
shimazu
2016/09/20 04:56:20
The comment means StopWorker massage should be sen
|
| + ipc_sink()->GetUniqueMessageMatching(EmbeddedWorkerMsg_StopWorker::ID)); |
| } |
| - // StopWorker should be sent in either case. |
| - ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( |
| - EmbeddedWorkerMsg_StopWorker::ID)); |
| // Check if the IPCs are fired in expected order. |
| ASSERT_EQ(4u, events_.size()); |
| @@ -243,7 +248,7 @@ TEST_P(EmbeddedWorkerInstanceTestP, StartAndStop) { |
| // Test that a worker that failed twice will use a new render process |
| // on the next attempt. |
| -TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, ForceNewProcess) { |
| std::unique_ptr<EmbeddedWorkerInstance> worker = |
| embedded_worker_registry()->CreateWorker(); |
| EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status()); |
| @@ -307,7 +312,7 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) { |
| } |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, StopWhenDevToolsAttached) { |
| std::unique_ptr<EmbeddedWorkerInstance> worker = |
| embedded_worker_registry()->CreateWorker(); |
| EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status()); |
| @@ -354,7 +359,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) { |
| // Test that the removal of a worker from the registry doesn't remove |
| // other workers in the same process. |
| -TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, RemoveWorkerInSharedProcess) { |
| std::unique_ptr<EmbeddedWorkerInstance> worker1 = |
| embedded_worker_registry()->CreateWorker(); |
| std::unique_ptr<EmbeddedWorkerInstance> worker2 = |
| @@ -409,7 +414,7 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) { |
| worker2->Stop(); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, DetachDuringProcessAllocation) { |
| const int64_t version_id = 55L; |
| const GURL scope("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -440,7 +445,7 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) { |
| EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, DetachAfterSendingStartWorkerMessage) { |
| const int64_t version_id = 55L; |
| const GURL scope("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -479,7 +484,7 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) { |
| EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, StopDuringProcessAllocation) { |
| const int64_t version_id = 55L; |
| const GURL scope("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -508,7 +513,6 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) { |
| // "PROCESS_ALLOCATED" event should not be recorded. |
| ASSERT_EQ(1u, events_.size()); |
| EXPECT_EQ(DETACHED, events_[0].type); |
| - EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status); |
| events_.clear(); |
| // Restart the worker. |
| @@ -529,7 +533,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) { |
| worker->Stop(); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, StopDuringPausedAfterDownload) { |
| const int64_t version_id = 55L; |
| const GURL scope("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -560,7 +564,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) { |
| EmbeddedWorkerMsg_ResumeAfterDownload::ID)); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, StopAfterSendingStartWorkerMessage) { |
| const int64_t version_id = 55L; |
| const GURL scope("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -621,7 +625,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) { |
| worker->Stop(); |
| } |
| -TEST_F(EmbeddedWorkerInstanceTest, Detach) { |
| +TEST_P(EmbeddedWorkerInstanceTestP, Detach) { |
| const int64_t version_id = 55L; |
| const GURL pattern("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| @@ -653,13 +657,18 @@ TEST_F(EmbeddedWorkerInstanceTest, Detach) { |
| } |
| // Test for when sending the start IPC failed. |
| -TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) { |
| - helper_.reset(new FailToSendIPCHelper()); |
| - |
| +TEST_P(EmbeddedWorkerInstanceTestP, FailToSendStartIPC) { |
| const int64_t version_id = 55L; |
| const GURL pattern("http://example.com/"); |
| const GURL url("http://example.com/worker.js"); |
| + if (is_mojo_enabled()) { |
| + // Let StartWorker fail; mojo IPC fails to connect to a remote interface. |
| + helper_->RegisterMockInstanceClient(nullptr); |
| + } else { |
| + helper_.reset(new FailToSendIPCHelper()); |
| + } |
| + |
| std::unique_ptr<EmbeddedWorkerInstance> worker = |
| embedded_worker_registry()->CreateWorker(); |
| helper_->SimulateAddProcessToPattern(pattern, |
| @@ -668,19 +677,81 @@ TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) { |
| worker->AddListener(this); |
| // Attempt to start the worker. |
| - base::RunLoop run_loop; |
| std::unique_ptr<EmbeddedWorkerStartParams> params( |
| CreateStartParams(version_id, pattern, url)); |
| - worker->Start(std::move(params), base::Bind(&SaveStatusAndCall, &status, |
| - run_loop.QuitClosure())); |
| - run_loop.Run(); |
| + if (is_mojo_enabled()) { |
| + worker->Start(std::move(params), base::Bind(&NoOpStatusCallback)); |
| + base::RunLoop().RunUntilIdle(); |
| + } else { |
| + base::RunLoop run_loop; |
| + worker->Start(std::move(params), 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); |
| - ASSERT_EQ(2u, events_.size()); |
| + if (is_mojo_enabled()) { |
| + // Worker should handle the failure of binding as detach. |
| + ASSERT_EQ(3u, events_.size()); |
| + EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type); |
| + EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type); |
| + EXPECT_EQ(DETACHED, events_[2].type); |
| + EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status); |
| + } else { |
| + // The callback should have run, and we should have got an OnStopped |
| + // message. |
| + EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, status); |
| + ASSERT_EQ(2u, events_.size()); |
| + EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type); |
| + EXPECT_EQ(STOPPED, events_[1].type); |
| + EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[1].status); |
| + } |
| +} |
| + |
| +class FailEmbeddedWorkerInstanceClientImpl |
| + : public EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient { |
| + public: |
| + explicit FailEmbeddedWorkerInstanceClientImpl( |
| + base::WeakPtr<EmbeddedWorkerTestHelper> helper) |
| + : EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient(helper) {} |
| + |
| + private: |
| + void StartWorker(const EmbeddedWorkerStartParams& /* unused */) override { |
| + helper_->mock_instance_clients()->clear(); |
| + } |
| +}; |
| + |
| +TEST_P(EmbeddedWorkerInstanceTestP, RemoveRemoteInterface) { |
| + if (!is_mojo_enabled()) |
| + return; |
| + |
| + const int64_t version_id = 55L; |
| + const GURL pattern("http://example.com/"); |
| + const GURL url("http://example.com/worker.js"); |
| + |
| + // Let StartWorker fail; binding is discarded in the middle of IPC |
| + helper_->RegisterMockInstanceClient( |
| + base::MakeUnique<FailEmbeddedWorkerInstanceClientImpl>( |
| + helper_->AsWeakPtr())); |
| + ASSERT_EQ(mock_instance_clients()->size(), 1UL); |
| + |
| + std::unique_ptr<EmbeddedWorkerInstance> worker = |
| + embedded_worker_registry()->CreateWorker(); |
| + helper_->SimulateAddProcessToPattern(pattern, |
| + helper_->mock_render_process_id()); |
| + worker->AddListener(this); |
| + |
| + // Attempt to start the worker. |
| + std::unique_ptr<EmbeddedWorkerStartParams> params( |
| + CreateStartParams(version_id, pattern, url)); |
| + worker->Start(std::move(params), base::Bind(&NoOpStatusCallback)); |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Worker should handle the sudden shutdown as detach. |
| + ASSERT_EQ(3u, events_.size()); |
| EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type); |
| - EXPECT_EQ(STOPPED, events_[1].type); |
| - EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[1].status); |
| + EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type); |
| + EXPECT_EQ(DETACHED, events_[2].type); |
| + EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status); |
| } |
| INSTANTIATE_TEST_CASE_P(EmbeddedWorkerInstanceTest, |