1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/worker_host/shared_worker_service_impl.h"
6
7 #include <memory>
8 #include <set>
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/containers/flat_map.h"
13 #include "base/containers/queue.h"
14 #include "base/macros.h"
15 #include "base/run_loop.h"
16 #include "base/scoped_observer.h"
17 #include "build/build_config.h"
18 #include "content/browser/site_instance_impl.h"
19 #include "content/browser/worker_host/mock_shared_worker.h"
20 #include "content/browser/worker_host/shared_worker_connector_impl.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/storage_partition.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/public/test/test_utils.h"
26 #include "content/test/fake_network_url_loader_factory.h"
27 #include "content/test/not_implemented_network_url_loader_factory.h"
28 #include "content/test/test_render_frame_host.h"
29 #include "content/test/test_render_view_host.h"
30 #include "content/test/test_web_contents.h"
31 #include "mojo/public/cpp/bindings/pending_receiver.h"
32 #include "mojo/public/cpp/bindings/remote.h"
33 #include "mojo/public/cpp/test_support/test_utils.h"
34 #include "services/network/public/cpp/features.h"
35 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/blink/public/common/messaging/message_port_channel.h"
38 #include "third_party/blink/public/mojom/worker/shared_worker_info.mojom.h"
39
40 using blink::MessagePortChannel;
41
42 namespace content {
43
44 namespace {
45
ConnectToSharedWorker(mojo::Remote<blink::mojom::SharedWorkerConnector> connector,const GURL & url,const std::string & name,MockSharedWorkerClient * client,MessagePortChannel * local_port)46 void ConnectToSharedWorker(
47 mojo::Remote<blink::mojom::SharedWorkerConnector> connector,
48 const GURL& url,
49 const std::string& name,
50 MockSharedWorkerClient* client,
51 MessagePortChannel* local_port) {
52 auto options = blink::mojom::WorkerOptions::New();
53 options->name = name;
54 blink::mojom::SharedWorkerInfoPtr info(blink::mojom::SharedWorkerInfo::New(
55 url, std::move(options), std::string(),
56 network::mojom::ContentSecurityPolicyType::kReport,
57 network::mojom::IPAddressSpace::kPublic,
58 blink::mojom::FetchClientSettingsObject::New(
59 network::mojom::ReferrerPolicy::kDefault, GURL(),
60 blink::mojom::InsecureRequestsPolicy::kDoNotUpgrade)));
61
62 mojo::MessagePipe message_pipe;
63 *local_port = MessagePortChannel(std::move(message_pipe.handle0));
64
65 mojo::PendingRemote<blink::mojom::SharedWorkerClient> client_proxy;
66 client->Bind(client_proxy.InitWithNewPipeAndPassReceiver());
67
68 connector->Connect(std::move(info), std::move(client_proxy),
69 blink::mojom::SharedWorkerCreationContextType::kSecure,
70 std::move(message_pipe.handle1), mojo::NullRemote());
71 }
72
73 // Helper to delete the given WebContents and shut down its process. This is
74 // useful because if FastShutdownIfPossible() is called without deleting the
75 // WebContents first, shutdown does not actually start.
KillProcess(std::unique_ptr<WebContents> web_contents)76 void KillProcess(std::unique_ptr<WebContents> web_contents) {
77 RenderFrameHost* frame_host = web_contents->GetMainFrame();
78 RenderProcessHost* process_host = frame_host->GetProcess();
79 web_contents.reset();
80 process_host->FastShutdownIfPossible(/*page_count=*/0,
81 /*skip_unload_handlers=*/true);
82 ASSERT_TRUE(process_host->FastShutdownStarted());
83 }
84
85 } // namespace
86
87 class SharedWorkerServiceImplTest : public RenderViewHostImplTestHarness {
88 public:
MakeSharedWorkerConnector(GlobalFrameRoutingId render_frame_host_id)89 mojo::Remote<blink::mojom::SharedWorkerConnector> MakeSharedWorkerConnector(
90 GlobalFrameRoutingId render_frame_host_id) {
91 mojo::Remote<blink::mojom::SharedWorkerConnector> connector;
92 SharedWorkerConnectorImpl::Create(render_frame_host_id,
93 connector.BindNewPipeAndPassReceiver());
94 return connector;
95 }
96
97 // Waits until a mojo::PendingReceiver<blink::mojom::SharedWorkerFactory>
98 // from the given process is received. kInvalidUniqueID means any process.
99 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory>
WaitForFactoryReceiver(int process_id)100 WaitForFactoryReceiver(int process_id) {
101 if (CheckNotReceivedFactoryReceiver(process_id)) {
102 base::RunLoop run_loop;
103 factory_receiver_callback_ = run_loop.QuitClosure();
104 factory_receiver_callback_process_id_ = process_id;
105 run_loop.Run();
106 }
107 auto iter = (process_id == ChildProcessHost::kInvalidUniqueID)
108 ? factorys_receivers_.begin()
109 : factorys_receivers_.find(process_id);
110 DCHECK(iter != factorys_receivers_.end());
111 auto& queue = iter->second;
112 DCHECK(!queue.empty());
113 auto rv = std::move(queue.front());
114 queue.pop();
115 if (queue.empty())
116 factorys_receivers_.erase(iter);
117 return rv;
118 }
119
CheckNotReceivedFactoryReceiver(int process_id)120 bool CheckNotReceivedFactoryReceiver(int process_id) {
121 if (process_id == ChildProcessHost::kInvalidUniqueID)
122 return factorys_receivers_.empty();
123 return !base::Contains(factorys_receivers_, process_id);
124 }
125
126 // Receives a PendingReceiver<blink::mojom::SharedWorkerFactory>.
BindSharedWorkerFactory(int process_id,mojo::ScopedMessagePipeHandle handle)127 void BindSharedWorkerFactory(int process_id,
128 mojo::ScopedMessagePipeHandle handle) {
129 if (factory_receiver_callback_ &&
130 (factory_receiver_callback_process_id_ == process_id ||
131 factory_receiver_callback_process_id_ ==
132 ChildProcessHost::kInvalidUniqueID)) {
133 factory_receiver_callback_process_id_ =
134 ChildProcessHost::kInvalidUniqueID;
135 std::move(factory_receiver_callback_).Run();
136 }
137
138 if (!base::Contains(factorys_receivers_, process_id)) {
139 factorys_receivers_.emplace(
140 process_id,
141 base::queue<
142 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory>>());
143 }
144 factorys_receivers_[process_id].emplace(std::move(handle));
145 }
146
CreateWebContents(const GURL & url)147 std::unique_ptr<TestWebContents> CreateWebContents(const GURL& url) {
148 std::unique_ptr<TestWebContents> web_contents(TestWebContents::Create(
149 browser_context_.get(),
150 SiteInstanceImpl::Create(browser_context_.get())));
151 web_contents->NavigateAndCommit(url);
152 return web_contents;
153 }
154
155 protected:
SharedWorkerServiceImplTest()156 SharedWorkerServiceImplTest() : browser_context_(new TestBrowserContext()) {}
157
SetUp()158 void SetUp() override {
159 RenderViewHostImplTestHarness::SetUp();
160 render_process_host_factory_ =
161 std::make_unique<MockRenderProcessHostFactory>();
162 RenderProcessHostImpl::set_render_process_host_factory_for_testing(
163 render_process_host_factory_.get());
164
165 fake_url_loader_factory_ = std::make_unique<FakeNetworkURLLoaderFactory>();
166 url_loader_factory_wrapper_ =
167 base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
168 fake_url_loader_factory_.get());
169 static_cast<SharedWorkerServiceImpl*>(
170 BrowserContext::GetDefaultStoragePartition(browser_context_.get())
171 ->GetSharedWorkerService())
172 ->SetURLLoaderFactoryForTesting(url_loader_factory_wrapper_);
173 }
174
TearDown()175 void TearDown() override {
176 if (url_loader_factory_wrapper_)
177 url_loader_factory_wrapper_->Detach();
178 browser_context_.reset();
179 RenderViewHostImplTestHarness::TearDown();
180 }
181
182 std::unique_ptr<TestBrowserContext> browser_context_;
183
184 // Holds pending receivers of SharedWorkerFactory for each process.
185 base::flat_map<
186 int /* process_id */,
187 base::queue<mojo::PendingReceiver<blink::mojom::SharedWorkerFactory>>>
188 factorys_receivers_;
189
190 // The callback is called when a pending receiver of SharedWorkerFactory for
191 // the specified process is received. kInvalidUniqueID means any process.
192 base::OnceClosure factory_receiver_callback_;
193 int factory_receiver_callback_process_id_ =
194 ChildProcessHost::kInvalidUniqueID;
195
196 std::unique_ptr<MockRenderProcessHostFactory> render_process_host_factory_;
197
198 std::unique_ptr<FakeNetworkURLLoaderFactory> fake_url_loader_factory_;
199 scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
200 url_loader_factory_wrapper_;
201
202 private:
203 DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest);
204 };
205
TEST_F(SharedWorkerServiceImplTest,BasicTest)206 TEST_F(SharedWorkerServiceImplTest, BasicTest) {
207 std::unique_ptr<TestWebContents> web_contents =
208 CreateWebContents(GURL("http://example.com/"));
209 TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
210 MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
211 const int process_id = renderer_host->GetID();
212 renderer_host->OverrideBinderForTesting(
213 blink::mojom::SharedWorkerFactory::Name_,
214 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
215 base::Unretained(this), process_id));
216
217 MockSharedWorkerClient client;
218 MessagePortChannel local_port;
219 const GURL kUrl("http://example.com/w.js");
220 ConnectToSharedWorker(
221 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
222 kUrl, "name", &client, &local_port);
223
224 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
225 WaitForFactoryReceiver(process_id);
226 MockSharedWorkerFactory factory(std::move(factory_receiver));
227 base::RunLoop().RunUntilIdle();
228
229 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
230 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
231 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
232 kUrl, "name", network::mojom::ContentSecurityPolicyType::kReport,
233 &worker_host, &worker_receiver));
234 MockSharedWorker worker(std::move(worker_receiver));
235 base::RunLoop().RunUntilIdle();
236
237 int connection_request_id;
238 MessagePortChannel port;
239 EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id, &port));
240
241 EXPECT_TRUE(client.CheckReceivedOnCreated());
242
243 // Simulate events the shared worker would send.
244
245 // Create message pipes. We may need to keep |devtools_agent_receiver| and
246 // |devtools_agent_host_remote| if we want not to invoke connection error
247 // handlers.
248 mojo::PendingRemote<blink::mojom::DevToolsAgent> devtools_agent_remote;
249 mojo::PendingReceiver<blink::mojom::DevToolsAgent> devtools_agent_receiver =
250 devtools_agent_remote.InitWithNewPipeAndPassReceiver();
251 mojo::PendingRemote<blink::mojom::DevToolsAgentHost>
252 devtools_agent_host_remote;
253 worker_host->OnReadyForInspection(
254 std::move(devtools_agent_remote),
255 devtools_agent_host_remote.InitWithNewPipeAndPassReceiver());
256
257 worker_host->OnConnected(connection_request_id);
258
259 base::RunLoop().RunUntilIdle();
260
261 EXPECT_TRUE(
262 client.CheckReceivedOnConnected(std::set<blink::mojom::WebFeature>()));
263
264 // Verify that |port| corresponds to |connector->local_port()|.
265 std::string expected_message("test1");
266 EXPECT_TRUE(mojo::test::WriteTextMessage(local_port.GetHandle().get(),
267 expected_message));
268 std::string received_message;
269 EXPECT_TRUE(
270 mojo::test::ReadTextMessage(port.GetHandle().get(), &received_message));
271 EXPECT_EQ(expected_message, received_message);
272
273 // Send feature from shared worker to host.
274 auto feature1 = static_cast<blink::mojom::WebFeature>(124);
275 worker_host->OnFeatureUsed(feature1);
276 base::RunLoop().RunUntilIdle();
277 EXPECT_TRUE(client.CheckReceivedOnFeatureUsed(feature1));
278
279 // A message should be sent only one time per feature.
280 worker_host->OnFeatureUsed(feature1);
281 base::RunLoop().RunUntilIdle();
282 EXPECT_TRUE(client.CheckNotReceivedOnFeatureUsed());
283
284 // Send another feature.
285 auto feature2 = static_cast<blink::mojom::WebFeature>(901);
286 worker_host->OnFeatureUsed(feature2);
287 base::RunLoop().RunUntilIdle();
288 EXPECT_TRUE(client.CheckReceivedOnFeatureUsed(feature2));
289
290 // Tear down the worker host.
291 worker_host->OnContextClosed();
292 base::RunLoop().RunUntilIdle();
293 }
294
295 // Tests that the shared worker will not be started if the hosting web contents
296 // is destroyed while the script is being fetched.
297 // TODO(https://crbug.com/1029434): Flaky on at least Fuchsia and Linux.
TEST_F(SharedWorkerServiceImplTest,DISABLED_WebContentsDestroyed)298 TEST_F(SharedWorkerServiceImplTest, DISABLED_WebContentsDestroyed) {
299 std::unique_ptr<TestWebContents> web_contents =
300 CreateWebContents(GURL("http://example.com/"));
301 TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
302 MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
303 const int process_id = renderer_host->GetID();
304 renderer_host->OverrideBinderForTesting(
305 blink::mojom::SharedWorkerFactory::Name_,
306 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
307 base::Unretained(this), process_id));
308
309 MockSharedWorkerClient client;
310 MessagePortChannel local_port;
311 const GURL kUrl("http://example.com/w.js");
312 ConnectToSharedWorker(
313 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
314 kUrl, "name", &client, &local_port);
315
316 // Now asynchronously destroy |web_contents| so that the startup sequence at
317 // least reaches SharedWorkerServiceImpl::StartWorker().
318 base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
319 std::move(web_contents));
320
321 base::RunLoop().RunUntilIdle();
322
323 // The shared worker creation failed, which means the client never connects
324 // and receives OnScriptLoadFailed().
325 EXPECT_TRUE(client.CheckReceivedOnCreated());
326 EXPECT_FALSE(client.CheckReceivedOnConnected({}));
327 EXPECT_TRUE(client.CheckReceivedOnScriptLoadFailed());
328 }
329
TEST_F(SharedWorkerServiceImplTest,TwoRendererTest)330 TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
331 // The first renderer host.
332 std::unique_ptr<TestWebContents> web_contents0 =
333 CreateWebContents(GURL("http://example.com/"));
334 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
335 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
336 const int process_id0 = renderer_host0->GetID();
337 renderer_host0->OverrideBinderForTesting(
338 blink::mojom::SharedWorkerFactory::Name_,
339 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
340 base::Unretained(this), process_id0));
341
342 MockSharedWorkerClient client0;
343 MessagePortChannel local_port0;
344 const GURL kUrl("http://example.com/w.js");
345 ConnectToSharedWorker(
346 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
347 kUrl, "name", &client0, &local_port0);
348
349 base::RunLoop().RunUntilIdle();
350
351 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
352 WaitForFactoryReceiver(process_id0);
353 MockSharedWorkerFactory factory(std::move(factory_receiver));
354 base::RunLoop().RunUntilIdle();
355
356 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
357 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
358 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
359 kUrl, "name", network::mojom::ContentSecurityPolicyType::kReport,
360 &worker_host, &worker_receiver));
361 MockSharedWorker worker(std::move(worker_receiver));
362 base::RunLoop().RunUntilIdle();
363
364 int connection_request_id0;
365 MessagePortChannel port0;
366 EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id0, &port0));
367
368 EXPECT_TRUE(client0.CheckReceivedOnCreated());
369
370 // Simulate events the shared worker would send.
371
372 // Create message pipes. We may need to keep |devtools_agent_receiver| and
373 // |devtools_agent_host_remote| if we want not to invoke connection error
374 // handlers.
375 mojo::PendingRemote<blink::mojom::DevToolsAgent> devtools_agent_remote;
376 mojo::PendingReceiver<blink::mojom::DevToolsAgent> devtools_agent_receiver =
377 devtools_agent_remote.InitWithNewPipeAndPassReceiver();
378 mojo::PendingRemote<blink::mojom::DevToolsAgentHost>
379 devtools_agent_host_remote;
380 worker_host->OnReadyForInspection(
381 std::move(devtools_agent_remote),
382 devtools_agent_host_remote.InitWithNewPipeAndPassReceiver());
383 worker_host->OnConnected(connection_request_id0);
384
385 base::RunLoop().RunUntilIdle();
386
387 EXPECT_TRUE(
388 client0.CheckReceivedOnConnected(std::set<blink::mojom::WebFeature>()));
389
390 // Verify that |port0| corresponds to |connector0->local_port()|.
391 std::string expected_message0("test1");
392 EXPECT_TRUE(mojo::test::WriteTextMessage(local_port0.GetHandle().get(),
393 expected_message0));
394 std::string received_message0;
395 EXPECT_TRUE(
396 mojo::test::ReadTextMessage(port0.GetHandle().get(), &received_message0));
397 EXPECT_EQ(expected_message0, received_message0);
398
399 auto feature1 = static_cast<blink::mojom::WebFeature>(124);
400 worker_host->OnFeatureUsed(feature1);
401 base::RunLoop().RunUntilIdle();
402 EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature1));
403 auto feature2 = static_cast<blink::mojom::WebFeature>(901);
404 worker_host->OnFeatureUsed(feature2);
405 base::RunLoop().RunUntilIdle();
406 EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature2));
407
408 // Only a single worker instance in process 0.
409 EXPECT_EQ(1u, renderer_host0->GetKeepAliveRefCount());
410
411 // The second renderer host.
412 std::unique_ptr<TestWebContents> web_contents1 =
413 CreateWebContents(GURL("http://example.com/"));
414 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
415 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
416 const int process_id1 = renderer_host1->GetID();
417 renderer_host1->OverrideBinderForTesting(
418 blink::mojom::SharedWorkerFactory::Name_,
419 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
420 base::Unretained(this), process_id1));
421
422 MockSharedWorkerClient client1;
423 MessagePortChannel local_port1;
424 ConnectToSharedWorker(
425 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
426 kUrl, "name", &client1, &local_port1);
427
428 base::RunLoop().RunUntilIdle();
429
430 // Should not have tried to create a new shared worker.
431 EXPECT_TRUE(CheckNotReceivedFactoryReceiver(process_id1));
432
433 int connection_request_id1;
434 MessagePortChannel port1;
435 EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id1, &port1));
436
437 EXPECT_TRUE(client1.CheckReceivedOnCreated());
438
439 // Only a single worker instance in process 0.
440 EXPECT_EQ(1u, renderer_host0->GetKeepAliveRefCount());
441 EXPECT_EQ(0u, renderer_host1->GetKeepAliveRefCount());
442
443 worker_host->OnConnected(connection_request_id1);
444
445 base::RunLoop().RunUntilIdle();
446
447 EXPECT_TRUE(client1.CheckReceivedOnConnected({feature1, feature2}));
448
449 // Verify that |worker_msg_port2| corresponds to |connector1->local_port()|.
450 std::string expected_message1("test2");
451 EXPECT_TRUE(mojo::test::WriteTextMessage(local_port1.GetHandle().get(),
452 expected_message1));
453 std::string received_message1;
454 EXPECT_TRUE(
455 mojo::test::ReadTextMessage(port1.GetHandle().get(), &received_message1));
456 EXPECT_EQ(expected_message1, received_message1);
457
458 worker_host->OnFeatureUsed(feature1);
459 base::RunLoop().RunUntilIdle();
460 EXPECT_TRUE(client0.CheckNotReceivedOnFeatureUsed());
461 EXPECT_TRUE(client1.CheckNotReceivedOnFeatureUsed());
462
463 auto feature3 = static_cast<blink::mojom::WebFeature>(1019);
464 worker_host->OnFeatureUsed(feature3);
465 base::RunLoop().RunUntilIdle();
466 EXPECT_TRUE(client0.CheckReceivedOnFeatureUsed(feature3));
467 EXPECT_TRUE(client1.CheckReceivedOnFeatureUsed(feature3));
468
469 // Tear down the worker host.
470 worker_host->OnContextClosed();
471 base::RunLoop().RunUntilIdle();
472 }
473
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_NormalCase)474 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase) {
475 const GURL kUrl("http://example.com/w.js");
476 const char kName[] = "name";
477
478 // The first renderer host.
479 std::unique_ptr<TestWebContents> web_contents0 =
480 CreateWebContents(GURL("http://example.com/"));
481 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
482 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
483 const int process_id0 = renderer_host0->GetID();
484 renderer_host0->OverrideBinderForTesting(
485 blink::mojom::SharedWorkerFactory::Name_,
486 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
487 base::Unretained(this), process_id0));
488
489 // The second renderer host.
490 std::unique_ptr<TestWebContents> web_contents1 =
491 CreateWebContents(GURL("http://example.com/"));
492 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
493 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
494 const int process_id1 = renderer_host1->GetID();
495 renderer_host1->OverrideBinderForTesting(
496 blink::mojom::SharedWorkerFactory::Name_,
497 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
498 base::Unretained(this), process_id1));
499
500 // First client, creates worker.
501
502 MockSharedWorkerClient client0;
503 MessagePortChannel local_port0;
504 ConnectToSharedWorker(
505 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
506 kUrl, kName, &client0, &local_port0);
507 base::RunLoop().RunUntilIdle();
508
509 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
510 WaitForFactoryReceiver(process_id0);
511 MockSharedWorkerFactory factory(std::move(factory_receiver));
512 base::RunLoop().RunUntilIdle();
513
514 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
515 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
516 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
517 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
518 &worker_host, &worker_receiver));
519 MockSharedWorker worker(std::move(worker_receiver));
520 base::RunLoop().RunUntilIdle();
521
522 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
523 EXPECT_TRUE(client0.CheckReceivedOnCreated());
524
525 // Second client, same worker.
526
527 MockSharedWorkerClient client1;
528 MessagePortChannel local_port1;
529 ConnectToSharedWorker(
530 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
531 kUrl, kName, &client1, &local_port1);
532 base::RunLoop().RunUntilIdle();
533
534 EXPECT_TRUE(CheckNotReceivedFactoryReceiver(process_id1));
535
536 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
537 EXPECT_TRUE(client1.CheckReceivedOnCreated());
538
539 // Cleanup
540
541 client0.Close();
542 client1.Close();
543 base::RunLoop().RunUntilIdle();
544
545 EXPECT_TRUE(worker.CheckReceivedTerminate());
546 }
547
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_NormalCase_URLMismatch)548 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_URLMismatch) {
549 const GURL kUrl0("http://example.com/w0.js");
550 const GURL kUrl1("http://example.com/w1.js");
551 const char kName[] = "name";
552
553 // The first renderer host.
554 std::unique_ptr<TestWebContents> web_contents0 =
555 CreateWebContents(GURL("http://example.com/"));
556 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
557 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
558 const int process_id0 = renderer_host0->GetID();
559 renderer_host0->OverrideBinderForTesting(
560 blink::mojom::SharedWorkerFactory::Name_,
561 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
562 base::Unretained(this), process_id0));
563
564 // The second renderer host.
565 std::unique_ptr<TestWebContents> web_contents1 =
566 CreateWebContents(GURL("http://example.com/"));
567 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
568 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
569 const int process_id1 = renderer_host1->GetID();
570 renderer_host1->OverrideBinderForTesting(
571 blink::mojom::SharedWorkerFactory::Name_,
572 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
573 base::Unretained(this), process_id1));
574
575 // First client, creates worker.
576
577 MockSharedWorkerClient client0;
578 MessagePortChannel local_port0;
579 ConnectToSharedWorker(
580 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
581 kUrl0, kName, &client0, &local_port0);
582 base::RunLoop().RunUntilIdle();
583
584 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
585 WaitForFactoryReceiver(process_id0);
586 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
587 base::RunLoop().RunUntilIdle();
588
589 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host0;
590 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver0;
591 EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
592 kUrl0, kName, network::mojom::ContentSecurityPolicyType::kReport,
593 &worker_host0, &worker_receiver0));
594 MockSharedWorker worker0(std::move(worker_receiver0));
595 base::RunLoop().RunUntilIdle();
596
597 EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
598 EXPECT_TRUE(client0.CheckReceivedOnCreated());
599
600 // Second client, creates worker.
601
602 MockSharedWorkerClient client1;
603 MessagePortChannel local_port1;
604 ConnectToSharedWorker(
605 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
606 kUrl1, kName, &client1, &local_port1);
607 base::RunLoop().RunUntilIdle();
608
609 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
610 WaitForFactoryReceiver(process_id1);
611 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
612 base::RunLoop().RunUntilIdle();
613
614 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
615 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
616 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
617 kUrl1, kName, network::mojom::ContentSecurityPolicyType::kReport,
618 &worker_host1, &worker_receiver1));
619 MockSharedWorker worker1(std::move(worker_receiver1));
620 base::RunLoop().RunUntilIdle();
621
622 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
623 EXPECT_TRUE(client1.CheckReceivedOnCreated());
624
625 // Cleanup
626
627 client0.Close();
628 client1.Close();
629 base::RunLoop().RunUntilIdle();
630
631 EXPECT_TRUE(worker0.CheckReceivedTerminate());
632 EXPECT_TRUE(worker1.CheckReceivedTerminate());
633 }
634
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_NormalCase_NameMismatch)635 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_NormalCase_NameMismatch) {
636 const GURL kUrl("http://example.com/w.js");
637 const char kName0[] = "name0";
638 const char kName1[] = "name1";
639
640 // The first renderer host.
641 std::unique_ptr<TestWebContents> web_contents0 =
642 CreateWebContents(GURL("http://example.com/"));
643 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
644 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
645 const int process_id0 = renderer_host0->GetID();
646 renderer_host0->OverrideBinderForTesting(
647 blink::mojom::SharedWorkerFactory::Name_,
648 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
649 base::Unretained(this), process_id0));
650
651 // The second renderer host.
652 std::unique_ptr<TestWebContents> web_contents1 =
653 CreateWebContents(GURL("http://example.com/"));
654 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
655 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
656 const int process_id1 = renderer_host1->GetID();
657 renderer_host1->OverrideBinderForTesting(
658 blink::mojom::SharedWorkerFactory::Name_,
659 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
660 base::Unretained(this), process_id1));
661
662 // First client, creates worker.
663
664 MockSharedWorkerClient client0;
665 MessagePortChannel local_port0;
666 ConnectToSharedWorker(
667 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
668 kUrl, kName0, &client0, &local_port0);
669 base::RunLoop().RunUntilIdle();
670
671 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
672 WaitForFactoryReceiver(process_id0);
673 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
674 base::RunLoop().RunUntilIdle();
675
676 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host0;
677 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver0;
678 EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
679 kUrl, kName0, network::mojom::ContentSecurityPolicyType::kReport,
680 &worker_host0, &worker_receiver0));
681 MockSharedWorker worker0(std::move(worker_receiver0));
682 base::RunLoop().RunUntilIdle();
683
684 EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
685 EXPECT_TRUE(client0.CheckReceivedOnCreated());
686
687 // Second client, creates worker.
688
689 MockSharedWorkerClient client1;
690 MessagePortChannel local_port1;
691 ConnectToSharedWorker(
692 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
693 kUrl, kName1, &client1, &local_port1);
694 base::RunLoop().RunUntilIdle();
695
696 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
697 WaitForFactoryReceiver(process_id1);
698 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
699 base::RunLoop().RunUntilIdle();
700
701 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
702 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
703 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
704 kUrl, kName1, network::mojom::ContentSecurityPolicyType::kReport,
705 &worker_host1, &worker_receiver1));
706 MockSharedWorker worker1(std::move(worker_receiver1));
707 base::RunLoop().RunUntilIdle();
708
709 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
710 EXPECT_TRUE(client1.CheckReceivedOnCreated());
711
712 // Cleanup
713
714 client0.Close();
715 client1.Close();
716 base::RunLoop().RunUntilIdle();
717
718 EXPECT_TRUE(worker0.CheckReceivedTerminate());
719 EXPECT_TRUE(worker1.CheckReceivedTerminate());
720 }
721
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_PendingCase)722 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase) {
723 const GURL kUrl("http://example.com/w.js");
724 const char kName[] = "name";
725
726 // The first renderer host.
727 std::unique_ptr<TestWebContents> web_contents0 =
728 CreateWebContents(GURL("http://example.com/"));
729 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
730 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
731 const int process_id0 = renderer_host0->GetID();
732 renderer_host0->OverrideBinderForTesting(
733 blink::mojom::SharedWorkerFactory::Name_,
734 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
735 base::Unretained(this), process_id0));
736
737 // The second renderer host.
738 std::unique_ptr<TestWebContents> web_contents1 =
739 CreateWebContents(GURL("http://example.com/"));
740 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
741 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
742 const int process_id1 = renderer_host1->GetID();
743 renderer_host1->OverrideBinderForTesting(
744 blink::mojom::SharedWorkerFactory::Name_,
745 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
746 base::Unretained(this), process_id1));
747
748 // First client and second client are created before the worker starts.
749
750 MockSharedWorkerClient client0;
751 MessagePortChannel local_port0;
752 ConnectToSharedWorker(
753 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
754 kUrl, kName, &client0, &local_port0);
755
756 MockSharedWorkerClient client1;
757 MessagePortChannel local_port1;
758 ConnectToSharedWorker(
759 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
760 kUrl, kName, &client1, &local_port1);
761
762 base::RunLoop().RunUntilIdle();
763
764 // Check that the worker was created. The receiver could come from either
765 // process.
766
767 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
768 WaitForFactoryReceiver(ChildProcessHost::kInvalidUniqueID);
769 MockSharedWorkerFactory factory(std::move(factory_receiver));
770
771 base::RunLoop().RunUntilIdle();
772
773 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
774 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
775 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
776 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
777 &worker_host, &worker_receiver));
778 MockSharedWorker worker(std::move(worker_receiver));
779
780 base::RunLoop().RunUntilIdle();
781
782 // Check that the worker received two connections.
783
784 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
785 EXPECT_TRUE(client0.CheckReceivedOnCreated());
786
787 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
788 EXPECT_TRUE(client1.CheckReceivedOnCreated());
789
790 // Cleanup
791
792 client0.Close();
793 client1.Close();
794 base::RunLoop().RunUntilIdle();
795
796 EXPECT_TRUE(worker.CheckReceivedTerminate());
797 }
798
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_PendingCase_URLMismatch)799 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_URLMismatch) {
800 const GURL kUrl0("http://example.com/w0.js");
801 const GURL kUrl1("http://example.com/w1.js");
802 const char kName[] = "name";
803
804 // The first renderer host.
805 std::unique_ptr<TestWebContents> web_contents0 =
806 CreateWebContents(GURL("http://example.com/"));
807 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
808 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
809 renderer_host0->OverrideBinderForTesting(
810 blink::mojom::SharedWorkerFactory::Name_,
811 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
812 base::Unretained(this), renderer_host0->GetID()));
813
814 // The second renderer host.
815 std::unique_ptr<TestWebContents> web_contents1 =
816 CreateWebContents(GURL("http://example.com/"));
817 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
818 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
819 renderer_host1->OverrideBinderForTesting(
820 blink::mojom::SharedWorkerFactory::Name_,
821 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
822 base::Unretained(this), renderer_host1->GetID()));
823
824 // First client and second client are created before the workers start.
825
826 MockSharedWorkerClient client0;
827 MessagePortChannel local_port0;
828 ConnectToSharedWorker(
829 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
830 kUrl0, kName, &client0, &local_port0);
831
832 MockSharedWorkerClient client1;
833 MessagePortChannel local_port1;
834 ConnectToSharedWorker(
835 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
836 kUrl1, kName, &client1, &local_port1);
837
838 base::RunLoop().RunUntilIdle();
839
840 // Check that both workers were created.
841
842 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
843 WaitForFactoryReceiver(renderer_host0->GetID());
844 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
845
846 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
847 WaitForFactoryReceiver(renderer_host1->GetID());
848 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
849
850 base::RunLoop().RunUntilIdle();
851
852 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host0;
853 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver0;
854 EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
855 kUrl0, kName, network::mojom::ContentSecurityPolicyType::kReport,
856 &worker_host0, &worker_receiver0));
857 MockSharedWorker worker0(std::move(worker_receiver0));
858
859 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
860 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
861 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
862 kUrl1, kName, network::mojom::ContentSecurityPolicyType::kReport,
863 &worker_host1, &worker_receiver1));
864 MockSharedWorker worker1(std::move(worker_receiver1));
865
866 base::RunLoop().RunUntilIdle();
867
868 // Check that the workers each received a connection.
869
870 EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
871 EXPECT_TRUE(worker0.CheckNotReceivedConnect());
872 EXPECT_TRUE(client0.CheckReceivedOnCreated());
873
874 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
875 EXPECT_TRUE(worker1.CheckNotReceivedConnect());
876 EXPECT_TRUE(client1.CheckReceivedOnCreated());
877
878 // Cleanup
879
880 client0.Close();
881 client1.Close();
882 base::RunLoop().RunUntilIdle();
883
884 EXPECT_TRUE(worker0.CheckReceivedTerminate());
885 EXPECT_TRUE(worker1.CheckReceivedTerminate());
886 }
887
TEST_F(SharedWorkerServiceImplTest,CreateWorkerTest_PendingCase_NameMismatch)888 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest_PendingCase_NameMismatch) {
889 const GURL kUrl("http://example.com/w.js");
890 const char kName0[] = "name0";
891 const char kName1[] = "name1";
892
893 // The first renderer host.
894 std::unique_ptr<TestWebContents> web_contents0 =
895 CreateWebContents(GURL("http://example.com/"));
896 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
897 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
898 const int process_id0 = renderer_host0->GetID();
899 renderer_host0->OverrideBinderForTesting(
900 blink::mojom::SharedWorkerFactory::Name_,
901 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
902 base::Unretained(this), process_id0));
903
904 // The second renderer host.
905 std::unique_ptr<TestWebContents> web_contents1 =
906 CreateWebContents(GURL("http://example.com/"));
907 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
908 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
909 const int process_id1 = renderer_host1->GetID();
910 renderer_host1->OverrideBinderForTesting(
911 blink::mojom::SharedWorkerFactory::Name_,
912 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
913 base::Unretained(this), process_id1));
914
915 // First client and second client are created before the workers start.
916
917 MockSharedWorkerClient client0;
918 MessagePortChannel local_port0;
919 ConnectToSharedWorker(
920 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
921 kUrl, kName0, &client0, &local_port0);
922
923 MockSharedWorkerClient client1;
924 MessagePortChannel local_port1;
925 ConnectToSharedWorker(
926 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
927 kUrl, kName1, &client1, &local_port1);
928
929 base::RunLoop().RunUntilIdle();
930
931 // Check that both workers were created.
932
933 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
934 WaitForFactoryReceiver(process_id0);
935 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
936
937 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
938 WaitForFactoryReceiver(process_id1);
939 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
940
941 base::RunLoop().RunUntilIdle();
942
943 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host0;
944 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver0;
945 EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
946 kUrl, kName0, network::mojom::ContentSecurityPolicyType::kReport,
947 &worker_host0, &worker_receiver0));
948 MockSharedWorker worker0(std::move(worker_receiver0));
949
950 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
951 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
952 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
953 kUrl, kName1, network::mojom::ContentSecurityPolicyType::kReport,
954 &worker_host1, &worker_receiver1));
955 MockSharedWorker worker1(std::move(worker_receiver1));
956
957 base::RunLoop().RunUntilIdle();
958
959 // Check that the workers each received a connection.
960
961 EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
962 EXPECT_TRUE(worker0.CheckNotReceivedConnect());
963 EXPECT_TRUE(client0.CheckReceivedOnCreated());
964
965 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
966 EXPECT_TRUE(worker1.CheckNotReceivedConnect());
967 EXPECT_TRUE(client1.CheckReceivedOnCreated());
968
969 // Cleanup
970
971 client0.Close();
972 client1.Close();
973 base::RunLoop().RunUntilIdle();
974
975 EXPECT_TRUE(worker0.CheckReceivedTerminate());
976 EXPECT_TRUE(worker1.CheckReceivedTerminate());
977 }
978
TEST_F(SharedWorkerServiceImplTest,CreateWorkerRaceTest)979 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
980 const GURL kUrl("http://example.com/w.js");
981 const char kName[] = "name";
982
983 // Create three renderer hosts.
984
985 std::unique_ptr<TestWebContents> web_contents0 =
986 CreateWebContents(GURL("http://example.com/"));
987 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
988 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
989 const int process_id0 = renderer_host0->GetID();
990 renderer_host0->OverrideBinderForTesting(
991 blink::mojom::SharedWorkerFactory::Name_,
992 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
993 base::Unretained(this), process_id0));
994
995 std::unique_ptr<TestWebContents> web_contents1 =
996 CreateWebContents(GURL("http://example.com/"));
997 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
998 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
999 const int process_id1 = renderer_host1->GetID();
1000 renderer_host1->OverrideBinderForTesting(
1001 blink::mojom::SharedWorkerFactory::Name_,
1002 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1003 base::Unretained(this), process_id1));
1004
1005 std::unique_ptr<TestWebContents> web_contents2 =
1006 CreateWebContents(GURL("http://example.com/"));
1007 TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
1008 MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
1009 const int process_id2 = renderer_host2->GetID();
1010 renderer_host2->OverrideBinderForTesting(
1011 blink::mojom::SharedWorkerFactory::Name_,
1012 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1013 base::Unretained(this), process_id2));
1014
1015 MockSharedWorkerClient client0;
1016 MessagePortChannel local_port0;
1017 ConnectToSharedWorker(
1018 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
1019 kUrl, kName, &client0, &local_port0);
1020
1021 base::RunLoop().RunUntilIdle();
1022
1023 // Starts a worker.
1024
1025 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
1026 WaitForFactoryReceiver(process_id0);
1027 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
1028
1029 base::RunLoop().RunUntilIdle();
1030
1031 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host0;
1032 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver0;
1033 EXPECT_TRUE(factory0.CheckReceivedCreateSharedWorker(
1034 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
1035 &worker_host0, &worker_receiver0));
1036 MockSharedWorker worker0(std::move(worker_receiver0));
1037
1038 base::RunLoop().RunUntilIdle();
1039
1040 EXPECT_TRUE(worker0.CheckReceivedConnect(nullptr, nullptr));
1041 EXPECT_TRUE(client0.CheckReceivedOnCreated());
1042
1043 // Kill this process, which should make worker0 unavailable.
1044 KillProcess(std::move(web_contents0));
1045
1046 // Start a new client, attemping to connect to the same worker.
1047 MockSharedWorkerClient client1;
1048 MessagePortChannel local_port1;
1049 ConnectToSharedWorker(
1050 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
1051 kUrl, kName, &client1, &local_port1);
1052
1053 base::RunLoop().RunUntilIdle();
1054
1055 // The previous worker is unavailable, so a new worker is created.
1056
1057 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
1058 WaitForFactoryReceiver(process_id1);
1059 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
1060
1061 base::RunLoop().RunUntilIdle();
1062
1063 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
1064 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
1065 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
1066 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
1067 &worker_host1, &worker_receiver1));
1068 MockSharedWorker worker1(std::move(worker_receiver1));
1069
1070 base::RunLoop().RunUntilIdle();
1071
1072 EXPECT_TRUE(worker0.CheckNotReceivedConnect());
1073 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
1074 EXPECT_TRUE(client1.CheckReceivedOnCreated());
1075
1076 // Start another client to confirm that it can connect to the same worker.
1077 MockSharedWorkerClient client2;
1078 MessagePortChannel local_port2;
1079 ConnectToSharedWorker(
1080 MakeSharedWorkerConnector(render_frame_host2->GetGlobalFrameRoutingId()),
1081 kUrl, kName, &client2, &local_port2);
1082
1083 base::RunLoop().RunUntilIdle();
1084
1085 EXPECT_TRUE(CheckNotReceivedFactoryReceiver(process_id2));
1086
1087 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
1088 EXPECT_TRUE(client2.CheckReceivedOnCreated());
1089
1090 // Tear down the worker host.
1091 worker_host1->OnContextClosed();
1092 base::RunLoop().RunUntilIdle();
1093 }
1094
TEST_F(SharedWorkerServiceImplTest,CreateWorkerRaceTest2)1095 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
1096 const GURL kUrl("http://example.com/w.js");
1097 const char kName[] = "name";
1098
1099 // Create three renderer hosts.
1100
1101 std::unique_ptr<TestWebContents> web_contents0 =
1102 CreateWebContents(GURL("http://example.com/"));
1103 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
1104 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
1105 const int process_id0 = renderer_host0->GetID();
1106 renderer_host0->OverrideBinderForTesting(
1107 blink::mojom::SharedWorkerFactory::Name_,
1108 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1109 base::Unretained(this), process_id0));
1110
1111 std::unique_ptr<TestWebContents> web_contents1 =
1112 CreateWebContents(GURL("http://example.com/"));
1113 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
1114 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
1115 const int process_id1 = renderer_host1->GetID();
1116 renderer_host1->OverrideBinderForTesting(
1117 blink::mojom::SharedWorkerFactory::Name_,
1118 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1119 base::Unretained(this), process_id1));
1120
1121 std::unique_ptr<TestWebContents> web_contents2 =
1122 CreateWebContents(GURL("http://example.com/"));
1123 TestRenderFrameHost* render_frame_host2 = web_contents2->GetMainFrame();
1124 MockRenderProcessHost* renderer_host2 = render_frame_host2->GetProcess();
1125 const int process_id2 = renderer_host2->GetID();
1126 renderer_host2->OverrideBinderForTesting(
1127 blink::mojom::SharedWorkerFactory::Name_,
1128 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1129 base::Unretained(this), process_id2));
1130
1131 MockSharedWorkerClient client0;
1132 MessagePortChannel local_port0;
1133 ConnectToSharedWorker(
1134 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
1135 kUrl, kName, &client0, &local_port0);
1136
1137 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver0 =
1138 WaitForFactoryReceiver(process_id0);
1139 MockSharedWorkerFactory factory0(std::move(factory_receiver0));
1140
1141 // Kill this process, which should make worker0 unavailable.
1142 KillProcess(std::move(web_contents0));
1143
1144 // Start a new client, attempting to connect to the same worker.
1145 MockSharedWorkerClient client1;
1146 MessagePortChannel local_port1;
1147 ConnectToSharedWorker(
1148 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
1149 kUrl, kName, &client1, &local_port1);
1150
1151 base::RunLoop().RunUntilIdle();
1152
1153 // The previous worker is unavailable, so a new worker is created.
1154
1155 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver1 =
1156 WaitForFactoryReceiver(process_id1);
1157 MockSharedWorkerFactory factory1(std::move(factory_receiver1));
1158
1159 EXPECT_TRUE(
1160 CheckNotReceivedFactoryReceiver(ChildProcessHost::kInvalidUniqueID));
1161
1162 base::RunLoop().RunUntilIdle();
1163
1164 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host1;
1165 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver1;
1166 EXPECT_TRUE(factory1.CheckReceivedCreateSharedWorker(
1167 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
1168 &worker_host1, &worker_receiver1));
1169 MockSharedWorker worker1(std::move(worker_receiver1));
1170
1171 base::RunLoop().RunUntilIdle();
1172
1173 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
1174 EXPECT_TRUE(client1.CheckReceivedOnCreated());
1175
1176 // Start another client to confirm that it can connect to the same worker.
1177 MockSharedWorkerClient client2;
1178 MessagePortChannel local_port2;
1179 ConnectToSharedWorker(
1180 MakeSharedWorkerConnector(render_frame_host2->GetGlobalFrameRoutingId()),
1181 kUrl, kName, &client2, &local_port2);
1182
1183 base::RunLoop().RunUntilIdle();
1184
1185 EXPECT_TRUE(
1186 CheckNotReceivedFactoryReceiver(ChildProcessHost::kInvalidUniqueID));
1187
1188 EXPECT_TRUE(worker1.CheckReceivedConnect(nullptr, nullptr));
1189 EXPECT_TRUE(client2.CheckReceivedOnCreated());
1190
1191 // Tear down the worker host.
1192 worker_host1->OnContextClosed();
1193 base::RunLoop().RunUntilIdle();
1194 }
1195
TEST_F(SharedWorkerServiceImplTest,CreateWorkerRaceTest3)1196 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest3) {
1197 const GURL kURL("http://example.com/w.js");
1198 const char kName[] = "name";
1199
1200 // The first renderer host.
1201 std::unique_ptr<TestWebContents> web_contents0 =
1202 CreateWebContents(GURL("http://example.com/"));
1203 TestRenderFrameHost* render_frame_host0 = web_contents0->GetMainFrame();
1204 MockRenderProcessHost* renderer_host0 = render_frame_host0->GetProcess();
1205 const int process_id0 = renderer_host0->GetID();
1206 renderer_host0->OverrideBinderForTesting(
1207 blink::mojom::SharedWorkerFactory::Name_,
1208 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1209 base::Unretained(this), process_id0));
1210
1211 // The second renderer host.
1212 std::unique_ptr<TestWebContents> web_contents1 =
1213 CreateWebContents(GURL("http://example.com/"));
1214 TestRenderFrameHost* render_frame_host1 = web_contents1->GetMainFrame();
1215 MockRenderProcessHost* renderer_host1 = render_frame_host1->GetProcess();
1216 const int process_id1 = renderer_host1->GetID();
1217 renderer_host1->OverrideBinderForTesting(
1218 blink::mojom::SharedWorkerFactory::Name_,
1219 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1220 base::Unretained(this), process_id1));
1221
1222 // Both clients try to connect/create a worker.
1223
1224 MockSharedWorkerClient client0;
1225 MessagePortChannel local_port0;
1226 ConnectToSharedWorker(
1227 MakeSharedWorkerConnector(render_frame_host0->GetGlobalFrameRoutingId()),
1228 kURL, kName, &client0, &local_port0);
1229
1230 MockSharedWorkerClient client1;
1231 MessagePortChannel local_port1;
1232 ConnectToSharedWorker(
1233 MakeSharedWorkerConnector(render_frame_host1->GetGlobalFrameRoutingId()),
1234 kURL, kName, &client1, &local_port1);
1235 base::RunLoop().RunUntilIdle();
1236
1237 // Expect a factory receiver. It can come from either process.
1238 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
1239 WaitForFactoryReceiver(ChildProcessHost::kInvalidUniqueID);
1240 MockSharedWorkerFactory factory(std::move(factory_receiver));
1241 base::RunLoop().RunUntilIdle();
1242
1243 // Expect a create shared worker.
1244 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
1245 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
1246 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
1247 kURL, kName, network::mojom::ContentSecurityPolicyType::kReport,
1248 &worker_host, &worker_receiver));
1249 MockSharedWorker worker(std::move(worker_receiver));
1250 base::RunLoop().RunUntilIdle();
1251
1252 // Expect one connect for the first client.
1253 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
1254 client0.CheckReceivedOnCreated();
1255
1256 // Expect one connect for the second client.
1257 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
1258 client1.CheckReceivedOnCreated();
1259
1260 // Cleanup
1261
1262 client0.Close();
1263 client1.Close();
1264 base::RunLoop().RunUntilIdle();
1265
1266 EXPECT_TRUE(worker.CheckReceivedTerminate());
1267 }
1268
1269 class TestSharedWorkerServiceObserver : public SharedWorkerService::Observer {
1270 public:
1271 TestSharedWorkerServiceObserver() = default;
1272 ~TestSharedWorkerServiceObserver() override = default;
1273
1274 // SharedWorkerService::Observer:
OnWorkerStarted(SharedWorkerId shared_worker_id,int worker_process_id,const base::UnguessableToken & dev_tools_token)1275 void OnWorkerStarted(SharedWorkerId shared_worker_id,
1276 int worker_process_id,
1277 const base::UnguessableToken& dev_tools_token) override {
1278 EXPECT_TRUE(running_workers_.insert({shared_worker_id, {}}).second);
1279 }
OnBeforeWorkerTerminated(SharedWorkerId shared_worker_id)1280 void OnBeforeWorkerTerminated(SharedWorkerId shared_worker_id) override {
1281 EXPECT_EQ(1u, running_workers_.erase(shared_worker_id));
1282 }
OnFinalResponseURLDetermined(SharedWorkerId shared_worker_id,const GURL & url)1283 void OnFinalResponseURLDetermined(SharedWorkerId shared_worker_id,
1284 const GURL& url) override {}
OnClientAdded(SharedWorkerId shared_worker_id,GlobalFrameRoutingId client_render_frame_host_id)1285 void OnClientAdded(
1286 SharedWorkerId shared_worker_id,
1287 GlobalFrameRoutingId client_render_frame_host_id) override {
1288 auto it = running_workers_.find(shared_worker_id);
1289 EXPECT_TRUE(it != running_workers_.end());
1290 std::set<GlobalFrameRoutingId>& clients = it->second;
1291 EXPECT_TRUE(clients.insert(client_render_frame_host_id).second);
1292 }
OnClientRemoved(SharedWorkerId shared_worker_id,GlobalFrameRoutingId client_render_frame_host_id)1293 void OnClientRemoved(
1294 SharedWorkerId shared_worker_id,
1295 GlobalFrameRoutingId client_render_frame_host_id) override {
1296 auto it = running_workers_.find(shared_worker_id);
1297 EXPECT_TRUE(it != running_workers_.end());
1298 std::set<GlobalFrameRoutingId>& clients = it->second;
1299 EXPECT_EQ(1u, clients.erase(client_render_frame_host_id));
1300 }
1301
GetWorkerCount()1302 size_t GetWorkerCount() { return running_workers_.size(); }
1303
GetClientCount()1304 size_t GetClientCount() {
1305 size_t client_count = 0;
1306 for (const auto& worker : running_workers_)
1307 client_count += worker.second.size();
1308 return client_count;
1309 }
1310
1311 private:
1312 base::flat_map<SharedWorkerId, std::set<GlobalFrameRoutingId>>
1313 running_workers_;
1314
1315 DISALLOW_COPY_AND_ASSIGN(TestSharedWorkerServiceObserver);
1316 };
1317
TEST_F(SharedWorkerServiceImplTest,Observer)1318 TEST_F(SharedWorkerServiceImplTest, Observer) {
1319 TestSharedWorkerServiceObserver observer;
1320
1321 ScopedObserver<SharedWorkerService, SharedWorkerService::Observer>
1322 scoped_observer(&observer);
1323 scoped_observer.Add(content::BrowserContext::GetDefaultStoragePartition(
1324 browser_context_.get())
1325 ->GetSharedWorkerService());
1326
1327 std::unique_ptr<TestWebContents> web_contents =
1328 CreateWebContents(GURL("http://example.com/"));
1329 TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
1330 MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
1331 const int process_id = renderer_host->GetID();
1332 renderer_host->OverrideBinderForTesting(
1333 blink::mojom::SharedWorkerFactory::Name_,
1334 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1335 base::Unretained(this), process_id));
1336
1337 MockSharedWorkerClient client;
1338 MessagePortChannel local_port;
1339 const GURL kUrl("http://example.com/w.js");
1340 ConnectToSharedWorker(
1341 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
1342 kUrl, "name", &client, &local_port);
1343
1344 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
1345 WaitForFactoryReceiver(process_id);
1346 MockSharedWorkerFactory factory(std::move(factory_receiver));
1347 base::RunLoop().RunUntilIdle();
1348
1349 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
1350 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
1351 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
1352 kUrl, "name", network::mojom::ContentSecurityPolicyType::kReport,
1353 &worker_host, &worker_receiver));
1354 MockSharedWorker worker(std::move(worker_receiver));
1355 base::RunLoop().RunUntilIdle();
1356
1357 int connection_request_id;
1358 MessagePortChannel port;
1359 EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id, &port));
1360
1361 EXPECT_TRUE(client.CheckReceivedOnCreated());
1362
1363 EXPECT_EQ(1u, observer.GetWorkerCount());
1364 EXPECT_EQ(1u, observer.GetClientCount());
1365
1366 // Tear down the worker host.
1367 worker_host->OnContextClosed();
1368 base::RunLoop().RunUntilIdle();
1369
1370 EXPECT_EQ(0u, observer.GetWorkerCount());
1371 EXPECT_EQ(0u, observer.GetClientCount());
1372 }
1373
TEST_F(SharedWorkerServiceImplTest,EnumerateSharedWorkers)1374 TEST_F(SharedWorkerServiceImplTest, EnumerateSharedWorkers) {
1375 TestSharedWorkerServiceObserver observer;
1376
1377 std::unique_ptr<TestWebContents> web_contents =
1378 CreateWebContents(GURL("http://example.com/"));
1379 TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
1380 MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
1381 const int process_id = renderer_host->GetID();
1382 renderer_host->OverrideBinderForTesting(
1383 blink::mojom::SharedWorkerFactory::Name_,
1384 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1385 base::Unretained(this), process_id));
1386
1387 MockSharedWorkerClient client;
1388 MessagePortChannel local_port;
1389 const GURL kUrl("http://example.com/w.js");
1390 ConnectToSharedWorker(
1391 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
1392 kUrl, "name", &client, &local_port);
1393
1394 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
1395 WaitForFactoryReceiver(process_id);
1396 MockSharedWorkerFactory factory(std::move(factory_receiver));
1397 base::RunLoop().RunUntilIdle();
1398
1399 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
1400 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
1401 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
1402 kUrl, "name", network::mojom::ContentSecurityPolicyType::kReport,
1403 &worker_host, &worker_receiver));
1404 MockSharedWorker worker(std::move(worker_receiver));
1405 base::RunLoop().RunUntilIdle();
1406
1407 int connection_request_id;
1408 MessagePortChannel port;
1409 EXPECT_TRUE(worker.CheckReceivedConnect(&connection_request_id, &port));
1410
1411 EXPECT_TRUE(client.CheckReceivedOnCreated());
1412
1413 // The observer was never registered to the SharedWorkerService.
1414 EXPECT_EQ(0u, observer.GetWorkerCount());
1415
1416 // Retrieve running shared workers.
1417 content::BrowserContext::GetDefaultStoragePartition(browser_context_.get())
1418 ->GetSharedWorkerService()
1419 ->EnumerateSharedWorkers(&observer);
1420
1421 EXPECT_EQ(1u, observer.GetWorkerCount());
1422
1423 // Cleanup.
1424 worker_host->OnContextClosed();
1425 base::RunLoop().RunUntilIdle();
1426 }
1427
TEST_F(SharedWorkerServiceImplTest,CollapseDuplicateNotifications)1428 TEST_F(SharedWorkerServiceImplTest, CollapseDuplicateNotifications) {
1429 TestSharedWorkerServiceObserver observer;
1430
1431 ScopedObserver<SharedWorkerService, SharedWorkerService::Observer>
1432 scoped_observer(&observer);
1433 scoped_observer.Add(content::BrowserContext::GetDefaultStoragePartition(
1434 browser_context_.get())
1435 ->GetSharedWorkerService());
1436
1437 const GURL kUrl("http://example.com/w.js");
1438 const char kName[] = "name";
1439
1440 // The first renderer host.
1441 std::unique_ptr<TestWebContents> web_contents =
1442 CreateWebContents(GURL("http://example.com/"));
1443 TestRenderFrameHost* render_frame_host = web_contents->GetMainFrame();
1444 MockRenderProcessHost* renderer_host = render_frame_host->GetProcess();
1445 const int process_id = renderer_host->GetID();
1446 renderer_host->OverrideBinderForTesting(
1447 blink::mojom::SharedWorkerFactory::Name_,
1448 base::BindRepeating(&SharedWorkerServiceImplTest::BindSharedWorkerFactory,
1449 base::Unretained(this), process_id));
1450
1451 // First client, creates worker.
1452
1453 MockSharedWorkerClient client0;
1454 MessagePortChannel local_port0;
1455 ConnectToSharedWorker(
1456 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
1457 kUrl, kName, &client0, &local_port0);
1458 base::RunLoop().RunUntilIdle();
1459
1460 mojo::PendingReceiver<blink::mojom::SharedWorkerFactory> factory_receiver =
1461 WaitForFactoryReceiver(process_id);
1462 MockSharedWorkerFactory factory(std::move(factory_receiver));
1463 base::RunLoop().RunUntilIdle();
1464
1465 mojo::Remote<blink::mojom::SharedWorkerHost> worker_host;
1466 mojo::PendingReceiver<blink::mojom::SharedWorker> worker_receiver;
1467 EXPECT_TRUE(factory.CheckReceivedCreateSharedWorker(
1468 kUrl, kName, network::mojom::ContentSecurityPolicyType::kReport,
1469 &worker_host, &worker_receiver));
1470 MockSharedWorker worker(std::move(worker_receiver));
1471 base::RunLoop().RunUntilIdle();
1472
1473 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
1474 EXPECT_TRUE(client0.CheckReceivedOnCreated());
1475
1476 // The observer now sees one worker with one client.
1477 EXPECT_EQ(1u, observer.GetWorkerCount());
1478 EXPECT_EQ(1u, observer.GetClientCount());
1479
1480 // Now the same frame connects to the same worker.
1481 MockSharedWorkerClient client1;
1482 MessagePortChannel local_port1;
1483 ConnectToSharedWorker(
1484 MakeSharedWorkerConnector(render_frame_host->GetGlobalFrameRoutingId()),
1485 kUrl, kName, &client1, &local_port1);
1486 base::RunLoop().RunUntilIdle();
1487
1488 EXPECT_TRUE(CheckNotReceivedFactoryReceiver(process_id));
1489
1490 EXPECT_TRUE(worker.CheckReceivedConnect(nullptr, nullptr));
1491 EXPECT_TRUE(client1.CheckReceivedOnCreated());
1492
1493 // Duplicate notification for the same client/worker pair are not sent.
1494 EXPECT_EQ(1u, observer.GetWorkerCount());
1495 EXPECT_EQ(1u, observer.GetClientCount());
1496
1497 // Cleanup
1498
1499 client0.Close();
1500 base::RunLoop().RunUntilIdle();
1501
1502 // With the first connection closed, the observer is still aware of one
1503 // client.
1504 EXPECT_EQ(1u, observer.GetWorkerCount());
1505 EXPECT_EQ(1u, observer.GetClientCount());
1506
1507 client1.Close();
1508 base::RunLoop().RunUntilIdle();
1509
1510 // Both connection are closed, the worker is stopped and there's no active
1511 // clients.
1512 EXPECT_EQ(0u, observer.GetWorkerCount());
1513 EXPECT_EQ(0u, observer.GetClientCount());
1514
1515 EXPECT_TRUE(worker.CheckReceivedTerminate());
1516 }
1517
1518 } // namespace content
1519