Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / shared_worker / shared_worker_service_impl_unittest.cc
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 <map>
6 #include <set>
7 #include <vector>
8
9 #include "base/atomic_sequence_num.h"
10 #include "base/basictypes.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/synchronization/lock.h"
16 #include "content/browser/message_port_message_filter.h"
17 #include "content/browser/shared_worker/shared_worker_message_filter.h"
18 #include "content/browser/shared_worker/shared_worker_service_impl.h"
19 #include "content/browser/shared_worker/worker_storage_partition.h"
20 #include "content/common/message_port_messages.h"
21 #include "content/common/view_messages.h"
22 #include "content/common/worker_messages.h"
23 #include "content/public/test/test_browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "content/public/test/test_utils.h"
26 #include "ipc/ipc_sync_message.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace content {
30
31 class SharedWorkerServiceImplTest : public testing::Test {
32  public:
33   static void RegisterRunningProcessID(int process_id) {
34     base::AutoLock lock(s_lock_);
35     s_running_process_id_set_.insert(process_id);
36   }
37   static void UnregisterRunningProcessID(int process_id) {
38     base::AutoLock lock(s_lock_);
39     s_running_process_id_set_.erase(process_id);
40   }
41
42  protected:
43   SharedWorkerServiceImplTest()
44       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
45         browser_context_(new TestBrowserContext()),
46         partition_(
47             new WorkerStoragePartition(browser_context_->GetRequestContext(),
48                                        NULL,
49                                        NULL,
50                                        NULL,
51                                        NULL,
52                                        NULL,
53                                        NULL,
54                                        NULL)) {
55     SharedWorkerServiceImpl::GetInstance()
56         ->ChangeUpdateWorkerDependencyFuncForTesting(
57             &SharedWorkerServiceImplTest::MockUpdateWorkerDependency);
58     SharedWorkerServiceImpl::GetInstance()
59         ->ChangeTryIncrementWorkerRefCountFuncForTesting(
60             &SharedWorkerServiceImplTest::MockTryIncrementWorkerRefCount);
61   }
62
63   virtual void SetUp() OVERRIDE {}
64   virtual void TearDown() OVERRIDE {
65     s_update_worker_dependency_call_count_ = 0;
66     s_worker_dependency_added_ids_.clear();
67     s_worker_dependency_removed_ids_.clear();
68     s_running_process_id_set_.clear();
69     SharedWorkerServiceImpl::GetInstance()->ResetForTesting();
70   }
71   static void MockUpdateWorkerDependency(const std::vector<int>& added_ids,
72                                          const std::vector<int>& removed_ids) {
73     ++s_update_worker_dependency_call_count_;
74     s_worker_dependency_added_ids_ = added_ids;
75     s_worker_dependency_removed_ids_ = removed_ids;
76   }
77   static bool MockTryIncrementWorkerRefCount(int worker_process_id) {
78     base::AutoLock lock(s_lock_);
79     return s_running_process_id_set_.find(worker_process_id) !=
80            s_running_process_id_set_.end();
81   }
82
83   TestBrowserThreadBundle browser_thread_bundle_;
84   scoped_ptr<TestBrowserContext> browser_context_;
85   scoped_ptr<WorkerStoragePartition> partition_;
86   static int s_update_worker_dependency_call_count_;
87   static std::vector<int> s_worker_dependency_added_ids_;
88   static std::vector<int> s_worker_dependency_removed_ids_;
89   static base::Lock s_lock_;
90   static std::set<int> s_running_process_id_set_;
91   DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest);
92 };
93
94 // static
95 int SharedWorkerServiceImplTest::s_update_worker_dependency_call_count_;
96 std::vector<int> SharedWorkerServiceImplTest::s_worker_dependency_added_ids_;
97 std::vector<int> SharedWorkerServiceImplTest::s_worker_dependency_removed_ids_;
98 base::Lock SharedWorkerServiceImplTest::s_lock_;
99 std::set<int> SharedWorkerServiceImplTest::s_running_process_id_set_;
100
101 namespace {
102
103 static const int kProcessIDs[] = {100, 101, 102};
104 static const unsigned long long kDocumentIDs[] = {200, 201, 202};
105 static const int kRenderFrameRouteIDs[] = {300, 301, 302};
106
107 class MockMessagePortMessageFilter : public MessagePortMessageFilter {
108  public:
109   MockMessagePortMessageFilter(const NextRoutingIDCallback& callback,
110                                ScopedVector<IPC::Message>* message_queue)
111       : MessagePortMessageFilter(callback), message_queue_(message_queue) {}
112
113   virtual bool Send(IPC::Message* message) OVERRIDE {
114     if (!message_queue_) {
115       delete message;
116       return false;
117     }
118     message_queue_->push_back(message);
119     return true;
120   }
121
122   void Close() {
123     message_queue_ = NULL;
124     OnChannelClosing();
125   }
126
127  private:
128   virtual ~MockMessagePortMessageFilter() {}
129   ScopedVector<IPC::Message>* message_queue_;
130 };
131
132 class MockSharedWorkerMessageFilter : public SharedWorkerMessageFilter {
133  public:
134   MockSharedWorkerMessageFilter(int render_process_id,
135                                 ResourceContext* resource_context,
136                                 const WorkerStoragePartition& partition,
137                                 MessagePortMessageFilter* message_port_filter,
138                                 ScopedVector<IPC::Message>* message_queue)
139       : SharedWorkerMessageFilter(render_process_id,
140                                   resource_context,
141                                   partition,
142                                   message_port_filter),
143         message_queue_(message_queue) {}
144
145   virtual bool Send(IPC::Message* message) OVERRIDE {
146     if (!message_queue_) {
147       delete message;
148       return false;
149     }
150     message_queue_->push_back(message);
151     return true;
152   }
153
154   void Close() {
155     message_queue_ = NULL;
156     OnChannelClosing();
157   }
158
159  private:
160   virtual ~MockSharedWorkerMessageFilter() {}
161   ScopedVector<IPC::Message>* message_queue_;
162 };
163
164 class MockRendererProcessHost {
165  public:
166   MockRendererProcessHost(int process_id,
167                           ResourceContext* resource_context,
168                           const WorkerStoragePartition& partition)
169       : process_id_(process_id),
170         message_filter_(new MockMessagePortMessageFilter(
171             base::Bind(&base::AtomicSequenceNumber::GetNext,
172                        base::Unretained(&next_routing_id_)),
173             &queued_messages_)),
174         worker_filter_(new MockSharedWorkerMessageFilter(process_id,
175                                                          resource_context,
176                                                          partition,
177                                                          message_filter_.get(),
178                                                          &queued_messages_)) {
179     SharedWorkerServiceImplTest::RegisterRunningProcessID(process_id);
180   }
181
182   ~MockRendererProcessHost() {
183     SharedWorkerServiceImplTest::UnregisterRunningProcessID(process_id_);
184     message_filter_->Close();
185     worker_filter_->Close();
186   }
187
188   bool OnMessageReceived(IPC::Message* message) {
189     scoped_ptr<IPC::Message> msg(message);
190     const bool ret = message_filter_->OnMessageReceived(*message) ||
191                      worker_filter_->OnMessageReceived(*message);
192     if (message->is_sync()) {
193       CHECK(!queued_messages_.empty());
194       const IPC::Message* response_msg = queued_messages_.back();
195       IPC::SyncMessage* sync_msg = static_cast<IPC::SyncMessage*>(message);
196       scoped_ptr<IPC::MessageReplyDeserializer> reply_serializer(
197           sync_msg->GetReplyDeserializer());
198       bool result = reply_serializer->SerializeOutputParameters(*response_msg);
199       CHECK(result);
200       queued_messages_.pop_back();
201     }
202     return ret;
203   }
204
205   size_t QueuedMessageCount() const { return queued_messages_.size(); }
206
207   scoped_ptr<IPC::Message> PopMessage() {
208     CHECK(queued_messages_.size());
209     scoped_ptr<IPC::Message> msg(*queued_messages_.begin());
210     queued_messages_.weak_erase(queued_messages_.begin());
211     return msg.Pass();
212   }
213
214   void FastShutdownIfPossible() {
215     SharedWorkerServiceImplTest::UnregisterRunningProcessID(process_id_);
216   }
217
218  private:
219   const int process_id_;
220   ScopedVector<IPC::Message> queued_messages_;
221   base::AtomicSequenceNumber next_routing_id_;
222   scoped_refptr<MockMessagePortMessageFilter> message_filter_;
223   scoped_refptr<MockSharedWorkerMessageFilter> worker_filter_;
224 };
225
226 void CreateMessagePortPair(MockRendererProcessHost* renderer,
227                            int* route_1,
228                            int* port_1,
229                            int* route_2,
230                            int* port_2) {
231   EXPECT_TRUE(renderer->OnMessageReceived(
232       new MessagePortHostMsg_CreateMessagePort(route_1, port_1)));
233   EXPECT_TRUE(renderer->OnMessageReceived(
234       new MessagePortHostMsg_CreateMessagePort(route_2, port_2)));
235   EXPECT_TRUE(renderer->OnMessageReceived(
236       new MessagePortHostMsg_Entangle(*port_1, *port_2)));
237   EXPECT_TRUE(renderer->OnMessageReceived(
238       new MessagePortHostMsg_Entangle(*port_2, *port_1)));
239 }
240
241 void PostCreateWorker(MockRendererProcessHost* renderer,
242                       const std::string& url,
243                       const std::string& name,
244                       unsigned long long document_id,
245                       int render_frame_route_id,
246                       int* connector_route_id) {
247   ViewHostMsg_CreateWorker_Params params;
248   params.url = GURL(url);
249   params.name = base::ASCIIToUTF16(name);
250   params.content_security_policy = base::string16();
251   params.security_policy_type = blink::WebContentSecurityPolicyTypeReport;
252   params.document_id = document_id;
253   params.render_frame_route_id = render_frame_route_id;
254   EXPECT_TRUE(renderer->OnMessageReceived(
255       new ViewHostMsg_CreateWorker(params, connector_route_id)));
256 }
257
258 class MockSharedWorkerConnector {
259  public:
260   MockSharedWorkerConnector(MockRendererProcessHost* renderer_host)
261       : renderer_host_(renderer_host),
262         temporary_remote_port_route_id_(0),
263         remote_port_id_(0),
264         local_port_route_id_(0),
265         local_port_id_(0),
266         route_id_(0) {}
267   void Create(const std::string& url,
268               const std::string& name,
269               unsigned long long document_id,
270               int render_frame_route_id) {
271     CreateMessagePortPair(renderer_host_,
272                           &temporary_remote_port_route_id_,
273                           &remote_port_id_,
274                           &local_port_route_id_,
275                           &local_port_id_);
276     PostCreateWorker(renderer_host_,
277                      url,
278                      name,
279                      document_id,
280                      render_frame_route_id,
281                      &route_id_);
282   }
283   void SendQueueMessages() {
284     EXPECT_TRUE(renderer_host_->OnMessageReceived(
285         new MessagePortHostMsg_QueueMessages(remote_port_id_)));
286   }
287   void SendPostMessage(std::string data) {
288     const std::vector<int> empty_ids;
289     EXPECT_TRUE(
290         renderer_host_->OnMessageReceived(new MessagePortHostMsg_PostMessage(
291             local_port_id_, base::ASCIIToUTF16(data), empty_ids)));
292   }
293   void SendConnect() {
294     EXPECT_TRUE(
295         renderer_host_->OnMessageReceived(new ViewHostMsg_ForwardToWorker(
296             WorkerMsg_Connect(route_id_, remote_port_id_, MSG_ROUTING_NONE))));
297   }
298   void SendSendQueuedMessages(
299       const std::vector<QueuedMessage>& queued_messages) {
300     EXPECT_TRUE(renderer_host_->OnMessageReceived(
301         new MessagePortHostMsg_SendQueuedMessages(remote_port_id_,
302                                                   queued_messages)));
303   }
304   int temporary_remote_port_route_id() {
305     return temporary_remote_port_route_id_;
306   }
307   int remote_port_id() { return remote_port_id_; }
308   int local_port_route_id() { return local_port_route_id_; }
309   int local_port_id() { return local_port_id_; }
310   int route_id() { return route_id_; }
311
312  private:
313   MockRendererProcessHost* renderer_host_;
314   int temporary_remote_port_route_id_;
315   int remote_port_id_;
316   int local_port_route_id_;
317   int local_port_id_;
318   int route_id_;
319 };
320
321 void CheckWorkerProcessMsgCreateWorker(
322     MockRendererProcessHost* renderer_host,
323     const std::string& expected_url,
324     const std::string& expected_name,
325     blink::WebContentSecurityPolicyType expected_security_policy_type,
326     int* route_id) {
327   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
328   EXPECT_EQ(WorkerProcessMsg_CreateWorker::ID, msg->type());
329   Tuple1<WorkerProcessMsg_CreateWorker_Params> param;
330   EXPECT_TRUE(WorkerProcessMsg_CreateWorker::Read(msg.get(), &param));
331   EXPECT_EQ(GURL(expected_url), param.a.url);
332   EXPECT_EQ(base::ASCIIToUTF16(expected_name), param.a.name);
333   EXPECT_EQ(expected_security_policy_type, param.a.security_policy_type);
334   *route_id = param.a.route_id;
335 }
336
337 void CheckViewMsgWorkerCreated(MockRendererProcessHost* renderer_host,
338                                MockSharedWorkerConnector* connector) {
339   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
340   EXPECT_EQ(ViewMsg_WorkerCreated::ID, msg->type());
341   EXPECT_EQ(connector->route_id(), msg->routing_id());
342 }
343
344 void CheckMessagePortMsgMessagesQueued(MockRendererProcessHost* renderer_host,
345                                        MockSharedWorkerConnector* connector) {
346   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
347   EXPECT_EQ(MessagePortMsg_MessagesQueued::ID, msg->type());
348   EXPECT_EQ(connector->temporary_remote_port_route_id(), msg->routing_id());
349 }
350
351 void CheckWorkerMsgConnect(MockRendererProcessHost* renderer_host,
352                            int expected_msg_route_id,
353                            int expected_sent_message_port_id,
354                            int* routing_id) {
355   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
356   EXPECT_EQ(WorkerMsg_Connect::ID, msg->type());
357   EXPECT_EQ(expected_msg_route_id, msg->routing_id());
358   WorkerMsg_Connect::Param params;
359   EXPECT_TRUE(WorkerMsg_Connect::Read(msg.get(), &params));
360   int port_id = params.a;
361   *routing_id = params.b;
362   EXPECT_EQ(expected_sent_message_port_id, port_id);
363 }
364
365 void CheckMessagePortMsgMessage(MockRendererProcessHost* renderer_host,
366                                 int expected_msg_route_id,
367                                 std::string expected_data) {
368   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
369   EXPECT_EQ(MessagePortMsg_Message::ID, msg->type());
370   EXPECT_EQ(expected_msg_route_id, msg->routing_id());
371   MessagePortMsg_Message::Param params;
372   EXPECT_TRUE(MessagePortMsg_Message::Read(msg.get(), &params));
373   base::string16 data = params.a;
374   EXPECT_EQ(base::ASCIIToUTF16(expected_data), data);
375 }
376
377 void CheckViewMsgWorkerConnected(MockRendererProcessHost* renderer_host,
378                                  MockSharedWorkerConnector* connector) {
379   scoped_ptr<IPC::Message> msg(renderer_host->PopMessage());
380   EXPECT_EQ(ViewMsg_WorkerConnected::ID, msg->type());
381   EXPECT_EQ(connector->route_id(), msg->routing_id());
382 }
383
384 }  // namespace
385
386 TEST_F(SharedWorkerServiceImplTest, BasicTest) {
387   scoped_ptr<MockRendererProcessHost> renderer_host(
388       new MockRendererProcessHost(kProcessIDs[0],
389                                   browser_context_->GetResourceContext(),
390                                   *partition_.get()));
391   scoped_ptr<MockSharedWorkerConnector> connector(
392       new MockSharedWorkerConnector(renderer_host.get()));
393   int worker_route_id;
394   int worker_msg_port_route_id;
395
396   // SharedWorkerConnector creates two message ports and sends
397   // ViewHostMsg_CreateWorker.
398   connector->Create("http://example.com/w.js",
399                     "name",
400                     kDocumentIDs[0],
401                     kRenderFrameRouteIDs[0]);
402   // We need to go to UI thread to call ReserveRenderProcessOnUI().
403   RunAllPendingInMessageLoop();
404   EXPECT_EQ(2U, renderer_host->QueuedMessageCount());
405   // WorkerProcessMsg_CreateWorker should be sent to the renderer in which
406   // SharedWorker will be created.
407   CheckWorkerProcessMsgCreateWorker(renderer_host.get(),
408                                     "http://example.com/w.js",
409                                     "name",
410                                     blink::WebContentSecurityPolicyTypeReport,
411                                     &worker_route_id);
412   // ViewMsg_WorkerCreated(1) should be sent back to SharedWorkerConnector side.
413   CheckViewMsgWorkerCreated(renderer_host.get(), connector.get());
414
415   // SharedWorkerConnector side sends MessagePortHostMsg_QueueMessages in
416   // WebSharedWorkerProxy::connect.
417   connector->SendQueueMessages();
418   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
419   // MessagePortMsg_MessagesQueued(2) should be sent back to
420   // SharedWorkerConnector side.
421   CheckMessagePortMsgMessagesQueued(renderer_host.get(), connector.get());
422
423   // When SharedWorkerConnector receives ViewMsg_WorkerCreated(1), it sends
424   // WorkerMsg_Connect wrapped in ViewHostMsg_ForwardToWorker.
425   connector->SendConnect();
426   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
427   // WorkerMsg_Connect should be sent to SharedWorker side.
428   CheckWorkerMsgConnect(renderer_host.get(),
429                         worker_route_id,
430                         connector->remote_port_id(),
431                         &worker_msg_port_route_id);
432
433   // When SharedWorkerConnector receives MessagePortMsg_MessagesQueued(2), it
434   // sends MessagePortHostMsg_SendQueuedMessages.
435   std::vector<QueuedMessage> empty_messages;
436   connector->SendSendQueuedMessages(empty_messages);
437   EXPECT_EQ(0U, renderer_host->QueuedMessageCount());
438
439   // SharedWorker sends WorkerHostMsg_WorkerReadyForInspection in
440   // EmbeddedSharedWorkerStub::WorkerReadyForInspection().
441   EXPECT_TRUE(renderer_host->OnMessageReceived(
442       new WorkerHostMsg_WorkerReadyForInspection(worker_route_id)));
443   EXPECT_EQ(0U, renderer_host->QueuedMessageCount());
444
445   // SharedWorker sends WorkerHostMsg_WorkerScriptLoaded in
446   // EmbeddedSharedWorkerStub::workerScriptLoaded().
447   EXPECT_TRUE(renderer_host->OnMessageReceived(
448       new WorkerHostMsg_WorkerScriptLoaded(worker_route_id)));
449   EXPECT_EQ(0U, renderer_host->QueuedMessageCount());
450
451   // SharedWorker sends WorkerHostMsg_WorkerConnected in
452   // EmbeddedSharedWorkerStub::workerScriptLoaded().
453   EXPECT_TRUE(
454       renderer_host->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
455           connector->remote_port_id(), worker_route_id)));
456   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
457   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
458   CheckViewMsgWorkerConnected(renderer_host.get(), connector.get());
459
460   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
461   // SharedWorker side shuold receive MessagePortMsg_Message.
462   connector->SendPostMessage("test1");
463   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
464   CheckMessagePortMsgMessage(
465       renderer_host.get(), worker_msg_port_route_id, "test1");
466
467   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
468   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
469   const std::vector<int> empty_ids;
470   EXPECT_TRUE(renderer_host->OnMessageReceived(
471       new MessagePortHostMsg_PostMessage(connector->remote_port_id(),
472                                          base::ASCIIToUTF16("test2"),
473                                          empty_ids)));
474   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
475   CheckMessagePortMsgMessage(
476       renderer_host.get(), connector->local_port_route_id(), "test2");
477
478   // UpdateWorkerDependency should not be called.
479   EXPECT_EQ(0, s_update_worker_dependency_call_count_);
480 }
481
482 TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
483   // The first renderer host.
484   scoped_ptr<MockRendererProcessHost> renderer_host0(
485       new MockRendererProcessHost(kProcessIDs[0],
486                                   browser_context_->GetResourceContext(),
487                                   *partition_.get()));
488   scoped_ptr<MockSharedWorkerConnector> connector0(
489       new MockSharedWorkerConnector(renderer_host0.get()));
490   int worker_route_id;
491   int worker_msg_port_route_id1;
492
493   // SharedWorkerConnector creates two message ports and sends
494   // ViewHostMsg_CreateWorker.
495   connector0->Create("http://example.com/w.js",
496                      "name",
497                      kDocumentIDs[0],
498                      kRenderFrameRouteIDs[0]);
499   // We need to go to UI thread to call ReserveRenderProcessOnUI().
500   RunAllPendingInMessageLoop();
501   EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
502   // WorkerProcessMsg_CreateWorker should be sent to the renderer in which
503   // SharedWorker will be created.
504   CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
505                                     "http://example.com/w.js",
506                                     "name",
507                                     blink::WebContentSecurityPolicyTypeReport,
508                                     &worker_route_id);
509   // ViewMsg_WorkerCreated(1) should be sent back to SharedWorkerConnector side.
510   CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
511
512   // SharedWorkerConnector side sends MessagePortHostMsg_QueueMessages in
513   // WebSharedWorkerProxy::connect.
514   connector0->SendQueueMessages();
515   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
516   // MessagePortMsg_MessagesQueued(2) should be sent back to
517   // SharedWorkerConnector side.
518   CheckMessagePortMsgMessagesQueued(renderer_host0.get(), connector0.get());
519
520   // When SharedWorkerConnector receives ViewMsg_WorkerCreated(1), it sends
521   // WorkerMsg_Connect wrapped in ViewHostMsg_ForwardToWorker.
522   connector0->SendConnect();
523   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
524   // WorkerMsg_Connect should be sent to SharedWorker side.
525   CheckWorkerMsgConnect(renderer_host0.get(),
526                         worker_route_id,
527                         connector0->remote_port_id(),
528                         &worker_msg_port_route_id1);
529
530   // When SharedWorkerConnector receives MessagePortMsg_MessagesQueued(2), it
531   // sends MessagePortHostMsg_SendQueuedMessages.
532   std::vector<QueuedMessage> empty_messages;
533   connector0->SendSendQueuedMessages(empty_messages);
534   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
535
536   // SharedWorker sends WorkerHostMsg_WorkerReadyForInspection in
537   // EmbeddedSharedWorkerStub::WorkerReadyForInspection().
538   EXPECT_TRUE(renderer_host0->OnMessageReceived(
539       new WorkerHostMsg_WorkerReadyForInspection(worker_route_id)));
540   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
541
542   // SharedWorker sends WorkerHostMsg_WorkerScriptLoaded in
543   // EmbeddedSharedWorkerStub::workerScriptLoaded().
544   EXPECT_TRUE(renderer_host0->OnMessageReceived(
545       new WorkerHostMsg_WorkerScriptLoaded(worker_route_id)));
546   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
547
548   // SharedWorker sends WorkerHostMsg_WorkerConnected in
549   // EmbeddedSharedWorkerStub::workerScriptLoaded().
550   EXPECT_TRUE(
551       renderer_host0->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
552           connector0->remote_port_id(), worker_route_id)));
553   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
554   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
555   CheckViewMsgWorkerConnected(renderer_host0.get(), connector0.get());
556
557   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
558   // SharedWorker side shuold receive MessagePortMsg_Message.
559   connector0->SendPostMessage("test1");
560   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
561   CheckMessagePortMsgMessage(
562       renderer_host0.get(), worker_msg_port_route_id1, "test1");
563
564   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
565   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
566   const std::vector<int> empty_ids;
567   EXPECT_TRUE(renderer_host0->OnMessageReceived(
568       new MessagePortHostMsg_PostMessage(connector0->remote_port_id(),
569                                          base::ASCIIToUTF16("test2"),
570                                          empty_ids)));
571   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
572   CheckMessagePortMsgMessage(
573       renderer_host0.get(), connector0->local_port_route_id(), "test2");
574
575   // The second renderer host.
576   scoped_ptr<MockRendererProcessHost> renderer_host1(
577       new MockRendererProcessHost(kProcessIDs[1],
578                                   browser_context_->GetResourceContext(),
579                                   *partition_.get()));
580   scoped_ptr<MockSharedWorkerConnector> connector1(
581       new MockSharedWorkerConnector(renderer_host1.get()));
582   int worker_msg_port_route_id2;
583
584   // UpdateWorkerDependency should not be called yet.
585   EXPECT_EQ(0, s_update_worker_dependency_call_count_);
586
587   // SharedWorkerConnector creates two message ports and sends
588   // ViewHostMsg_CreateWorker.
589   connector1->Create("http://example.com/w.js",
590                      "name",
591                      kDocumentIDs[1],
592                      kRenderFrameRouteIDs[1]);
593   // We need to go to UI thread to call ReserveRenderProcessOnUI().
594   RunAllPendingInMessageLoop();
595   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
596   // ViewMsg_WorkerCreated(3) should be sent back to SharedWorkerConnector side.
597   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
598
599   // UpdateWorkerDependency should be called.
600   EXPECT_EQ(1, s_update_worker_dependency_call_count_);
601   EXPECT_EQ(1U, s_worker_dependency_added_ids_.size());
602   EXPECT_EQ(kProcessIDs[0], s_worker_dependency_added_ids_[0]);
603   EXPECT_EQ(0U, s_worker_dependency_removed_ids_.size());
604
605   // SharedWorkerConnector side sends MessagePortHostMsg_QueueMessages in
606   // WebSharedWorkerProxy::connect.
607   connector1->SendQueueMessages();
608   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
609   // MessagePortMsg_MessagesQueued(4) should be sent back to
610   // SharedWorkerConnector side.
611   CheckMessagePortMsgMessagesQueued(renderer_host1.get(), connector1.get());
612
613   // When SharedWorkerConnector receives ViewMsg_WorkerCreated(3), it sends
614   // WorkerMsg_Connect wrapped in ViewHostMsg_ForwardToWorker.
615   connector1->SendConnect();
616   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
617   // WorkerMsg_Connect should be sent to SharedWorker side.
618   CheckWorkerMsgConnect(renderer_host0.get(),
619                         worker_route_id,
620                         connector1->remote_port_id(),
621                         &worker_msg_port_route_id2);
622
623   // When SharedWorkerConnector receives MessagePortMsg_MessagesQueued(4), it
624   // sends MessagePortHostMsg_SendQueuedMessages.
625   connector1->SendSendQueuedMessages(empty_messages);
626   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
627
628   // SharedWorker sends WorkerHostMsg_WorkerConnected in
629   // EmbeddedSharedWorkerStub::OnConnect().
630   EXPECT_TRUE(
631       renderer_host0->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
632           connector1->remote_port_id(), worker_route_id)));
633   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
634   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
635   CheckViewMsgWorkerConnected(renderer_host1.get(), connector1.get());
636
637   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
638   // SharedWorker side shuold receive MessagePortMsg_Message.
639   connector1->SendPostMessage("test3");
640   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
641   CheckMessagePortMsgMessage(
642       renderer_host0.get(), worker_msg_port_route_id2, "test3");
643
644   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
645   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
646   EXPECT_TRUE(renderer_host0->OnMessageReceived(
647       new MessagePortHostMsg_PostMessage(connector1->remote_port_id(),
648                                          base::ASCIIToUTF16("test4"),
649                                          empty_ids)));
650   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
651   CheckMessagePortMsgMessage(
652       renderer_host1.get(), connector1->local_port_route_id(), "test4");
653
654   EXPECT_EQ(1, s_update_worker_dependency_call_count_);
655   renderer_host1.reset();
656   // UpdateWorkerDependency should be called.
657   EXPECT_EQ(2, s_update_worker_dependency_call_count_);
658   EXPECT_EQ(0U, s_worker_dependency_added_ids_.size());
659   EXPECT_EQ(1U, s_worker_dependency_removed_ids_.size());
660   EXPECT_EQ(kProcessIDs[0], s_worker_dependency_removed_ids_[0]);
661 }
662
663 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest) {
664   // The first renderer host.
665   scoped_ptr<MockRendererProcessHost> renderer_host0(
666       new MockRendererProcessHost(kProcessIDs[0],
667                                   browser_context_->GetResourceContext(),
668                                   *partition_.get()));
669   // The second renderer host.
670   scoped_ptr<MockRendererProcessHost> renderer_host1(
671       new MockRendererProcessHost(kProcessIDs[1],
672                                   browser_context_->GetResourceContext(),
673                                   *partition_.get()));
674   int worker_route_id;
675
676   // Normal case.
677   {
678     scoped_ptr<MockSharedWorkerConnector> connector0(
679         new MockSharedWorkerConnector(renderer_host0.get()));
680     scoped_ptr<MockSharedWorkerConnector> connector1(
681         new MockSharedWorkerConnector(renderer_host1.get()));
682     connector0->Create("http://example.com/w1.js",
683                        "name1",
684                        kDocumentIDs[0],
685                        kRenderFrameRouteIDs[0]);
686     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
687     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
688     RunAllPendingInMessageLoop();
689     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
690     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
691                                       "http://example.com/w1.js",
692                                       "name1",
693                                       blink::WebContentSecurityPolicyTypeReport,
694                                       &worker_route_id);
695     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
696     connector1->Create("http://example.com/w1.js",
697                        "name1",
698                        kDocumentIDs[1],
699                        kRenderFrameRouteIDs[1]);
700     EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
701     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
702     RunAllPendingInMessageLoop();
703     EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
704     CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
705   }
706
707   // Normal case (URL mismatch).
708   {
709     scoped_ptr<MockSharedWorkerConnector> connector0(
710         new MockSharedWorkerConnector(renderer_host0.get()));
711     scoped_ptr<MockSharedWorkerConnector> connector1(
712         new MockSharedWorkerConnector(renderer_host1.get()));
713     connector0->Create("http://example.com/w2.js",
714                        "name2",
715                        kDocumentIDs[0],
716                        kRenderFrameRouteIDs[0]);
717     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
718     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
719     RunAllPendingInMessageLoop();
720     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
721     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
722                                       "http://example.com/w2.js",
723                                       "name2",
724                                       blink::WebContentSecurityPolicyTypeReport,
725                                       &worker_route_id);
726     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
727     connector1->Create("http://example.com/w2x.js",
728                        "name2",
729                        kDocumentIDs[1],
730                        kRenderFrameRouteIDs[1]);
731     EXPECT_EQ(MSG_ROUTING_NONE, connector1->route_id());
732     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
733     RunAllPendingInMessageLoop();
734     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
735   }
736
737   // Pending case.
738   {
739     scoped_ptr<MockSharedWorkerConnector> connector0(
740         new MockSharedWorkerConnector(renderer_host0.get()));
741     scoped_ptr<MockSharedWorkerConnector> connector1(
742         new MockSharedWorkerConnector(renderer_host1.get()));
743     connector0->Create("http://example.com/w3.js",
744                        "name3",
745                        kDocumentIDs[0],
746                        kRenderFrameRouteIDs[0]);
747     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
748     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
749     connector1->Create("http://example.com/w3.js",
750                        "name3",
751                        kDocumentIDs[1],
752                        kRenderFrameRouteIDs[1]);
753     EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
754     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
755     RunAllPendingInMessageLoop();
756     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
757     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
758                                       "http://example.com/w3.js",
759                                       "name3",
760                                       blink::WebContentSecurityPolicyTypeReport,
761                                       &worker_route_id);
762     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
763     EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
764     CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
765   }
766
767   // Pending case (URL mismatch).
768   {
769     scoped_ptr<MockSharedWorkerConnector> connector0(
770         new MockSharedWorkerConnector(renderer_host0.get()));
771     scoped_ptr<MockSharedWorkerConnector> connector1(
772         new MockSharedWorkerConnector(renderer_host1.get()));
773     connector0->Create("http://example.com/w4.js",
774                        "name4",
775                        kDocumentIDs[0],
776                        kRenderFrameRouteIDs[0]);
777     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
778     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
779     connector1->Create("http://example.com/w4x.js",
780                        "name4",
781                        kDocumentIDs[1],
782                        kRenderFrameRouteIDs[1]);
783     EXPECT_EQ(MSG_ROUTING_NONE, connector1->route_id());
784     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
785     RunAllPendingInMessageLoop();
786     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
787     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
788                                       "http://example.com/w4.js",
789                                       "name4",
790                                       blink::WebContentSecurityPolicyTypeReport,
791                                       &worker_route_id);
792     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
793     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
794   }
795 }
796
797 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
798   // Create three renderer hosts.
799   scoped_ptr<MockRendererProcessHost> renderer_host0(
800       new MockRendererProcessHost(kProcessIDs[0],
801                                   browser_context_->GetResourceContext(),
802                                   *partition_.get()));
803   scoped_ptr<MockRendererProcessHost> renderer_host1(
804       new MockRendererProcessHost(kProcessIDs[1],
805                                   browser_context_->GetResourceContext(),
806                                   *partition_.get()));
807   scoped_ptr<MockRendererProcessHost> renderer_host2(
808       new MockRendererProcessHost(kProcessIDs[2],
809                                   browser_context_->GetResourceContext(),
810                                   *partition_.get()));
811   int worker_route_id;
812
813   scoped_ptr<MockSharedWorkerConnector> connector0(
814       new MockSharedWorkerConnector(renderer_host0.get()));
815   scoped_ptr<MockSharedWorkerConnector> connector1(
816       new MockSharedWorkerConnector(renderer_host1.get()));
817   scoped_ptr<MockSharedWorkerConnector> connector2(
818       new MockSharedWorkerConnector(renderer_host2.get()));
819   connector0->Create("http://example.com/w1.js",
820                      "name1",
821                      kDocumentIDs[0],
822                      kRenderFrameRouteIDs[0]);
823   EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
824   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
825   RunAllPendingInMessageLoop();
826   EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
827   CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
828                                     "http://example.com/w1.js",
829                                     "name1",
830                                     blink::WebContentSecurityPolicyTypeReport,
831                                     &worker_route_id);
832   CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
833   renderer_host0->FastShutdownIfPossible();
834
835   connector1->Create("http://example.com/w1.js",
836                      "name1",
837                      kDocumentIDs[1],
838                      kRenderFrameRouteIDs[1]);
839   EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
840   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
841   RunAllPendingInMessageLoop();
842   EXPECT_EQ(2U, renderer_host1->QueuedMessageCount());
843   CheckWorkerProcessMsgCreateWorker(renderer_host1.get(),
844                                     "http://example.com/w1.js",
845                                     "name1",
846                                     blink::WebContentSecurityPolicyTypeReport,
847                                     &worker_route_id);
848   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
849
850   connector2->Create("http://example.com/w1.js",
851                      "name1",
852                      kDocumentIDs[2],
853                      kRenderFrameRouteIDs[2]);
854   EXPECT_NE(MSG_ROUTING_NONE, connector2->route_id());
855   EXPECT_EQ(0U, renderer_host2->QueuedMessageCount());
856   RunAllPendingInMessageLoop();
857   EXPECT_EQ(1U, renderer_host2->QueuedMessageCount());
858   CheckViewMsgWorkerCreated(renderer_host2.get(), connector2.get());
859 }
860
861 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
862   // Create three renderer hosts.
863   scoped_ptr<MockRendererProcessHost> renderer_host0(
864       new MockRendererProcessHost(kProcessIDs[0],
865                                   browser_context_->GetResourceContext(),
866                                   *partition_.get()));
867   scoped_ptr<MockRendererProcessHost> renderer_host1(
868       new MockRendererProcessHost(kProcessIDs[1],
869                                   browser_context_->GetResourceContext(),
870                                   *partition_.get()));
871   scoped_ptr<MockRendererProcessHost> renderer_host2(
872       new MockRendererProcessHost(kProcessIDs[2],
873                                   browser_context_->GetResourceContext(),
874                                   *partition_.get()));
875   int worker_route_id;
876
877   scoped_ptr<MockSharedWorkerConnector> connector0(
878       new MockSharedWorkerConnector(renderer_host0.get()));
879   scoped_ptr<MockSharedWorkerConnector> connector1(
880       new MockSharedWorkerConnector(renderer_host1.get()));
881   scoped_ptr<MockSharedWorkerConnector> connector2(
882       new MockSharedWorkerConnector(renderer_host2.get()));
883   connector0->Create("http://example.com/w1.js",
884                      "name1",
885                      kDocumentIDs[0],
886                      kRenderFrameRouteIDs[0]);
887   EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
888   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
889   renderer_host0->FastShutdownIfPossible();
890
891   connector1->Create("http://example.com/w1.js",
892                      "name1",
893                      kDocumentIDs[1],
894                      kRenderFrameRouteIDs[1]);
895   EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
896   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
897   RunAllPendingInMessageLoop();
898   EXPECT_EQ(2U, renderer_host1->QueuedMessageCount());
899   CheckWorkerProcessMsgCreateWorker(renderer_host1.get(),
900                                     "http://example.com/w1.js",
901                                     "name1",
902                                     blink::WebContentSecurityPolicyTypeReport,
903                                     &worker_route_id);
904   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
905
906   connector2->Create("http://example.com/w1.js",
907                      "name1",
908                      kDocumentIDs[2],
909                      kRenderFrameRouteIDs[2]);
910   EXPECT_NE(MSG_ROUTING_NONE, connector2->route_id());
911   EXPECT_EQ(0U, renderer_host2->QueuedMessageCount());
912   RunAllPendingInMessageLoop();
913   EXPECT_EQ(1U, renderer_host2->QueuedMessageCount());
914   CheckViewMsgWorkerCreated(renderer_host2.get(), connector2.get());
915 }
916
917 }  // namespace content