// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/shared_worker/shared_worker_service_impl.h"

#include <memory>
#include <queue>
#include <set>
#include <string>

#include "base/macros.h"
#include "base/run_loop.h"
#include "content/browser/shared_worker/mock_shared_worker.h"
#include "content/browser/shared_worker/shared_worker_connector_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_utils.h"
#include "content/test/test_render_frame_host.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"

using blink::MessagePortChannel;

namespace content {

class SharedWorkerServiceImplTest : public RenderViewHostImplTestHarness {
 public:
  mojom::SharedWorkerConnectorPtr MakeSharedWorkerConnector(
      RenderProcessHost* process_host,
      int frame_id) {
    mojom::SharedWorkerConnectorPtr connector;
    SharedWorkerConnectorImpl::Create(process_host->GetID(), frame_id,
                                      mojo::MakeRequest(&connector));
    return connector;
  }

  static bool CheckReceivedFactoryRequest(
      mojom::SharedWorkerFactoryRequest* request) {
    if (s_factory_request_received_.empty())
      return false;
    *request = std::move(s_factory_request_received_.front());
    s_factory_request_received_.pop();
    return true;
  }

  static bool CheckNotReceivedFactoryRequest() {
    return s_factory_request_received_.empty();
  }

  static void BindSharedWorkerFactory(mojo::ScopedMessagePipeHandle handle) {
    s_factory_request_received_.push(
        mojom::SharedWorkerFactoryRequest(std::move(handle)));
  }

  std::unique_ptr<TestWebContents> CreateWebContents(const GURL& url) {
    std::unique_ptr<TestWebContents> web_contents(TestWebContents::Create(
        browser_context_.get(),
        SiteInstanceImpl::Create(browser_context_.get())));
    web_contents->NavigateAndCommit(url);
    return web_contents;
  }

 protected:
  SharedWorkerServiceImplTest() : browser_context_(new TestBrowserContext()) {}

  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();
    render_process_host_factory_ =
        std::make_unique<MockRenderProcessHostFactory>();
    RenderProcessHostImpl::set_render_process_host_factory_for_testing(
        render_process_host_factory_.get());
  }

  void TearDown() override {
    browser_context_.reset();
    RenderViewHostImplTestHarness::TearDown();
  }

  std::unique_ptr<TestBrowserContext> browser_context_;
  static std::queue<mojom::SharedWorkerFactoryRequest>
      s_factory_request_received_;
  std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest);
};

// static
std::queue<mojom::SharedWorkerFactoryRequest>
    SharedWorkerServiceImplTest::s_factory_request_received_;

namespace {

void ConnectToSharedWorker(mojom::SharedWorkerConnectorPtr connector,
                           const GURL& url,
                           const std::string& name,
                           MockSharedWorkerClient* client,
                           MessagePortChannel* local_port) {
  mojom::SharedWorkerInfoPtr info(mojom::SharedWorkerInfo::New(
      url, name, std::string(), blink::kWebContentSecurityPolicyTypeReport,
      blink::mojom::IPAddressSpace::kPublic));

  mojo::MessagePipe message_pipe;
  *local_port = MessagePortChannel(std::move(message_pipe.handle0));

  mojom::SharedWorkerClientPtr client_proxy;
  client->Bind(mojo::MakeRequest(&client_proxy));

  connector->Connect(std::move(info), std::move(client_proxy),
                     blink::mojom::SharedWorkerCreationContextType::kSecure,
                     std::move(message_pipe.handle1));
}

}  // namespace

TEST_F(SharedWorkerServiceImplTest, BasicTest) {
  std::unique_ptr<TestWebContents> web_contents =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
  MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
  renderer_host->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  MockSharedWorkerClient client;
  MessagePortChannel local_port;
  const GURL kUrl("http://example.com/w.js");
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host, render_frame_host->GetRoutingID()),
                        kUrl, "name", &client, &local_port);

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request));
  MockSharedWorkerFactory factory(std::move(factory_request));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host;
  mojom::SharedWorkerRequest worker_request;
  EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
      kUrl, "name", blink::kWebContentSecurityPolicyTypeReport, &worker_host,
      &worker_request));
  MockSharedWorker worker(std::move(worker_request));
  base::RunLoop().RunUntilIdle();

  int connection_request_id;
  MessagePortChannel port;
  EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id, &port));

  EXPECT_TRUE(client.CheckReceivedOnCreated());

  // Simulate events the shared worker would send.
  worker_host->OnReadyForInspection();
  worker_host->OnScriptLoaded();
  worker_host->OnConnected(connection_request_id);

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(
      client.CheckReceivedOnConnected(std::set<blink::mojom::WebFeature>()));

  // Verify that |port| corresponds to |connector->local_port()|.
  std::string expected_message("test1");
  EXPECT_TRUE(mojo::test::WriteTextMessage(local_port.GetHandle().get(),
                                           expected_message));
  std::string received_message;
  EXPECT_TRUE(
      mojo::test::ReadTextMessage(port.GetHandle().get(), &received_message));
  EXPECT_EQ(expected_message, received_message);

  // Send feature from shared worker to host.
  auto feature1 = static_cast<blink::mojom::WebFeature>(124);
  worker_host->OnFeatureUsed(feature1);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client.CheckReceivedOnFeatureUsed(feature1));

  // A message should be sent only one time per feature.
  worker_host->OnFeatureUsed(feature1);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client.CheckNotReceivedOnFeatureUsed());

  // Send another feature.
  auto feature2 = static_cast<blink::mojom::WebFeature>(901);
  worker_host->OnFeatureUsed(feature2);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client.CheckReceivedOnFeatureUsed(feature2));
}

TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  const GURL kUrl("http://example.com/w.js");
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, "name", &client0, &local_port0);

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request));
  MockSharedWorkerFactory factory(std::move(factory_request));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host;
  mojom::SharedWorkerRequest worker_request;
  EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
      kUrl, "name", blink::kWebContentSecurityPolicyTypeReport, &worker_host,
      &worker_request));
  MockSharedWorker worker(std::move(worker_request));
  base::RunLoop().RunUntilIdle();

  int connection_request_id0;
  MessagePortChannel port0;
  EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id0, &port0));

  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  // Simulate events the shared worker would send.
  worker_host->OnReadyForInspection();
  worker_host->OnScriptLoaded();
  worker_host->OnConnected(connection_request_id0);

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(
      client0.CheckReceivedOnConnected(std::set<blink::mojom::WebFeature>()));

  // Verify that |port0| corresponds to |connector0->local_port()|.
  std::string expected_message0("test1");
  EXPECT_TRUE(mojo::test::WriteTextMessage(local_port0.GetHandle().get(),
                                           expected_message0));
  std::string received_message0;
  EXPECT_TRUE(
      mojo::test::ReadTextMessage(port0.GetHandle().get(), &received_message0));
  EXPECT_EQ(expected_message0, received_message0);

  auto feature1 = static_cast<blink::mojom::WebFeature>(124);
  worker_host->OnFeatureUsed(feature1);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature1));
  auto feature2 = static_cast<blink::mojom::WebFeature>(901);
  worker_host->OnFeatureUsed(feature2);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature2));

  // Only a single worker instance in process 0.
  EXPECT_EQ(1u, renderer_host0->GetKeepAliveRefCount());

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, "name", &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // Should not have tried to create a new shared worker.
  EXPECT_TRUE(CheckNotReceivedFactoryRequest());

  int connection_request_id1;
  MessagePortChannel port1;
  EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id1, &port1));

  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Only a single worker instance in process 0.
  EXPECT_EQ(1u, renderer_host0->GetKeepAliveRefCount());
  EXPECT_EQ(0u, renderer_host1->GetKeepAliveRefCount());

  worker_host->OnConnected(connection_request_id1);

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(client1.CheckReceivedOnConnected({feature1, feature2}));

  // Verify that |worker_msg_port2| corresponds to |connector1->local_port()|.
  std::string expected_message1("test2");
  EXPECT_TRUE(mojo::test::WriteTextMessage(local_port1.GetHandle().get(),
                                           expected_message1));
  std::string received_message1;
  EXPECT_TRUE(
      mojo::test::ReadTextMessage(port1.GetHandle().get(), &received_message1));
  EXPECT_EQ(expected_message1, received_message1);

  worker_host->OnFeatureUsed(feature1);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client0.CheckNotReceivedOnFeatureUsed());
  EXPECT_TRUE(client1.CheckNotReceivedOnFeatureUsed());

  auto feature3 = static_cast<blink::mojom::WebFeature>(1019);
  worker_host->OnFeatureUsed(feature3);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature3));
  EXPECT_TRUE(client1.CheckReceivedOnFeatureUsed(feature3));
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase) {
  const GURL kUrl("http://example.com/w.js");
  const char kName[] = "name";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client, creates worker.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName, &client0, &local_port0);
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request));
  MockSharedWorkerFactory factory(std::move(factory_request));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host;
  mojom::SharedWorkerRequest worker_request;
  EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
      kUrl, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host,
      &worker_request));
  MockSharedWorker worker(std::move(worker_request));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  // Second client, same worker.

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName, &client1, &local_port1);
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(CheckNotReceivedFactoryRequest());

  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_URLMismatch) {
  const GURL kUrl0("http://example.com/w0.js");
  const GURL kUrl1("http://example.com/w1.js");
  const char kName[] = "name";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client, creates worker.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl0, kName, &client0, &local_port0);
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request0;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request0));
  MockSharedWorkerFactory factory0(std::move(factory_request0));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host0;
  mojom::SharedWorkerRequest worker_request0;
  EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
      kUrl0, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host0,
      &worker_request0));
  MockSharedWorker worker0(std::move(worker_request0));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  // Second client, creates worker.

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl1, kName, &client1, &local_port1);
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl1, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedTerminate());
  EXPECT_TRUE(worker1.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_NameMismatch) {
  const GURL kUrl("http://example.com/w.js");
  const char kName0[] = "name0";
  const char kName1[] = "name1";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client, creates worker.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName0, &client0, &local_port0);
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request0;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request0));
  MockSharedWorkerFactory factory0(std::move(factory_request0));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host0;
  mojom::SharedWorkerRequest worker_request0;
  EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
      kUrl, kName0, blink::kWebContentSecurityPolicyTypeReport, &worker_host0,
      &worker_request0));
  MockSharedWorker worker0(std::move(worker_request0));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  // Second client, creates worker.

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName1, &client1, &local_port1);
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));
  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl, kName1, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedTerminate());
  EXPECT_TRUE(worker1.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase) {
  const GURL kUrl("http://example.com/w.js");
  const char kName[] = "name";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client and second client are created before the worker starts.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName, &client0, &local_port0);

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName, &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // Check that the worker was created.

  mojom::SharedWorkerFactoryRequest factory_request;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request));
  MockSharedWorkerFactory factory(std::move(factory_request));

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host;
  mojom::SharedWorkerRequest worker_request;
  EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
      kUrl, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host,
      &worker_request));
  MockSharedWorker worker(std::move(worker_request));

  base::RunLoop().RunUntilIdle();

  // Check that the worker received two connections.

  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_URLMismatch) {
  const GURL kUrl0("http://example.com/w0.js");
  const GURL kUrl1("http://example.com/w1.js");
  const char kName[] = "name";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client and second client are created before the workers start.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl0, kName, &client0, &local_port0);

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl1, kName, &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // Check that both workers were created.

  mojom::SharedWorkerFactoryRequest factory_request0;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request0));
  MockSharedWorkerFactory factory0(std::move(factory_request0));

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host0;
  mojom::SharedWorkerRequest worker_request0;
  EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
      kUrl0, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host0,
      &worker_request0));
  MockSharedWorker worker0(std::move(worker_request0));

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl1, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));

  base::RunLoop().RunUntilIdle();

  // Check that the workers each received a connection.

  EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(worker0.CheckNotReceivedConnect());
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(worker1.CheckNotReceivedConnect());
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedTerminate());
  EXPECT_TRUE(worker1.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_NameMismatch) {
  const GURL kUrl("http://example.com/w.js");
  const char kName0[] = "name0";
  const char kName1[] = "name1";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // First client and second client are created before the workers start.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName0, &client0, &local_port0);

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName1, &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // Check that both workers were created.

  mojom::SharedWorkerFactoryRequest factory_request0;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request0));
  MockSharedWorkerFactory factory0(std::move(factory_request0));

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host0;
  mojom::SharedWorkerRequest worker_request0;
  EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
      kUrl, kName0, blink::kWebContentSecurityPolicyTypeReport, &worker_host0,
      &worker_request0));
  MockSharedWorker worker0(std::move(worker_request0));

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl, kName1, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));

  base::RunLoop().RunUntilIdle();

  // Check that the workers each received a connection.

  EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(worker0.CheckNotReceivedConnect());
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(worker1.CheckNotReceivedConnect());
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedTerminate());
  EXPECT_TRUE(worker1.CheckReceivedTerminate());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
  const GURL kUrl("http://example.com/w.js");
  const char kName[] = "name";

  // Create three renderer hosts.

  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  std::unique_ptr<TestWebContents> web_contents2 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
  MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
  renderer_host2->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName, &client0, &local_port0);

  base::RunLoop().RunUntilIdle();

  // Starts a worker.

  mojom::SharedWorkerFactoryRequest factory_request0;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request0));
  MockSharedWorkerFactory factory0(std::move(factory_request0));

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host0;
  mojom::SharedWorkerRequest worker_request0;
  EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
      kUrl, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host0,
      &worker_request0));
  MockSharedWorker worker0(std::move(worker_request0));

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client0.CheckReceivedOnCreated());

  // Kill this process, which should make worker0 unavailable.
  web_contents0.reset();
  renderer_host0->FastShutdownIfPossible(0, true);
  ASSERT_TRUE(renderer_host0->FastShutdownStarted());

  // Start a new client, attemping to connect to the same worker.
  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName, &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // The previous worker is unavailable, so a new worker is created.

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker0.CheckNotReceivedConnect());
  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Start another client to confirm that it can connect to the same worker.
  MockSharedWorkerClient client2;
  MessagePortChannel local_port2;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host2, render_frame_host2->GetRoutingID()),
                        kUrl, kName, &client2, &local_port2);

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(CheckNotReceivedFactoryRequest());

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client2.CheckReceivedOnCreated());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
  const GURL kUrl("http://example.com/w.js");
  const char kName[] = "name";

  // Create three renderer hosts.

  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  std::unique_ptr<TestWebContents> web_contents2 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
  MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
  renderer_host2->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::Bind(&SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kUrl, kName, &client0, &local_port0);

  // Kill this process, which should make worker0 unavailable.
  renderer_host0->FastShutdownIfPossible(0, true);

  // Start a new client, attemping to connect to the same worker.
  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kUrl, kName, &client1, &local_port1);

  base::RunLoop().RunUntilIdle();

  // The previous worker is unavailable, so a new worker is created.

  mojom::SharedWorkerFactoryRequest factory_request1;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request1));
  MockSharedWorkerFactory factory1(std::move(factory_request1));

  EXPECT_TRUE(CheckNotReceivedFactoryRequest());

  base::RunLoop().RunUntilIdle();

  mojom::SharedWorkerHostPtr worker_host1;
  mojom::SharedWorkerRequest worker_request1;
  EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
      kUrl, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host1,
      &worker_request1));
  MockSharedWorker worker1(std::move(worker_request1));

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client1.CheckReceivedOnCreated());

  // Start another client to confirm that it can connect to the same worker.
  MockSharedWorkerClient client2;
  MessagePortChannel local_port2;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host2, render_frame_host2->GetRoutingID()),
                        kUrl, kName, &client2, &local_port2);

  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(CheckNotReceivedFactoryRequest());

  EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
  EXPECT_TRUE(client2.CheckReceivedOnCreated());
}

TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest3) {
  const GURL kURL("http://example.com/w.js");
  const char kName[] = "name";

  // The first renderer host.
  std::unique_ptr<TestWebContents> web_contents0 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
  MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
  renderer_host0->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::BindRepeating(
          &SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // The second renderer host.
  std::unique_ptr<TestWebContents> web_contents1 =
      CreateWebContents(GURL("http://example.com/"));
  TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
  MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
  renderer_host1->OverrideBinderForTesting(
      mojom::SharedWorkerFactory::Name_,
      base::BindRepeating(
          &SharedWorkerServiceImplTest::BindSharedWorkerFactory));

  // Both clients try to connect/create a worker.

  MockSharedWorkerClient client0;
  MessagePortChannel local_port0;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host0, render_frame_host0->GetRoutingID()),
                        kURL, kName, &client0, &local_port0);

  MockSharedWorkerClient client1;
  MessagePortChannel local_port1;
  ConnectToSharedWorker(MakeSharedWorkerConnector(
                            renderer_host1, render_frame_host1->GetRoutingID()),
                        kURL, kName, &client1, &local_port1);
  base::RunLoop().RunUntilIdle();

  // Expect a factory request.
  mojom::SharedWorkerFactoryRequest factory_request;
  EXPECT_TRUE(CheckReceivedFactoryRequest(&factory_request));
  MockSharedWorkerFactory factory(std::move(factory_request));
  base::RunLoop().RunUntilIdle();

  // Expect a create shared worker.
  mojom::SharedWorkerHostPtr worker_host;
  mojom::SharedWorkerRequest worker_request;
  EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
      kURL, kName, blink::kWebContentSecurityPolicyTypeReport, &worker_host,
      &worker_request));
  MockSharedWorker worker(std::move(worker_request));
  base::RunLoop().RunUntilIdle();

  // Expect one connect for the first client.
  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  client0.CheckReceivedOnCreated();

  // Expect one connect for the second client.
  EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
  client1.CheckReceivedOnCreated();

  // Cleanup

  client0.Close();
  client1.Close();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(worker.CheckReceivedTerminate());
}

}  // namespace content
