Home | History | Annotate | Download | only in shared_worker
      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/worker_host/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_WorkerScriptLoaded in
    440   // EmbeddedSharedWorkerStub::workerScriptLoaded().
    441   EXPECT_TRUE(renderer_host->OnMessageReceived(
    442       new WorkerHostMsg_WorkerScriptLoaded(worker_route_id)));
    443   EXPECT_EQ(0U, renderer_host->QueuedMessageCount());
    444 
    445   // SharedWorker sends WorkerHostMsg_WorkerConnected in
    446   // EmbeddedSharedWorkerStub::workerScriptLoaded().
    447   EXPECT_TRUE(
    448       renderer_host->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
    449           connector->remote_port_id(), worker_route_id)));
    450   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
    451   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
    452   CheckViewMsgWorkerConnected(renderer_host.get(), connector.get());
    453 
    454   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
    455   // SharedWorker side shuold receive MessagePortMsg_Message.
    456   connector->SendPostMessage("test1");
    457   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
    458   CheckMessagePortMsgMessage(
    459       renderer_host.get(), worker_msg_port_route_id, "test1");
    460 
    461   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
    462   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
    463   const std::vector<int> empty_ids;
    464   EXPECT_TRUE(renderer_host->OnMessageReceived(
    465       new MessagePortHostMsg_PostMessage(connector->remote_port_id(),
    466                                          base::ASCIIToUTF16("test2"),
    467                                          empty_ids)));
    468   EXPECT_EQ(1U, renderer_host->QueuedMessageCount());
    469   CheckMessagePortMsgMessage(
    470       renderer_host.get(), connector->local_port_route_id(), "test2");
    471 
    472   // UpdateWorkerDependency should not be called.
    473   EXPECT_EQ(0, s_update_worker_dependency_call_count_);
    474 }
    475 
    476 TEST_F(SharedWorkerServiceImplTest, TwoRendererTest) {
    477   // The first renderer host.
    478   scoped_ptr<MockRendererProcessHost> renderer_host0(
    479       new MockRendererProcessHost(kProcessIDs[0],
    480                                   browser_context_->GetResourceContext(),
    481                                   *partition_.get()));
    482   scoped_ptr<MockSharedWorkerConnector> connector0(
    483       new MockSharedWorkerConnector(renderer_host0.get()));
    484   int worker_route_id;
    485   int worker_msg_port_route_id1;
    486 
    487   // SharedWorkerConnector creates two message ports and sends
    488   // ViewHostMsg_CreateWorker.
    489   connector0->Create("http://example.com/w.js",
    490                      "name",
    491                      kDocumentIDs[0],
    492                      kRenderFrameRouteIDs[0]);
    493   // We need to go to UI thread to call ReserveRenderProcessOnUI().
    494   RunAllPendingInMessageLoop();
    495   EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    496   // WorkerProcessMsg_CreateWorker should be sent to the renderer in which
    497   // SharedWorker will be created.
    498   CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    499                                     "http://example.com/w.js",
    500                                     "name",
    501                                     blink::WebContentSecurityPolicyTypeReport,
    502                                     &worker_route_id);
    503   // ViewMsg_WorkerCreated(1) should be sent back to SharedWorkerConnector side.
    504   CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    505 
    506   // SharedWorkerConnector side sends MessagePortHostMsg_QueueMessages in
    507   // WebSharedWorkerProxy::connect.
    508   connector0->SendQueueMessages();
    509   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    510   // MessagePortMsg_MessagesQueued(2) should be sent back to
    511   // SharedWorkerConnector side.
    512   CheckMessagePortMsgMessagesQueued(renderer_host0.get(), connector0.get());
    513 
    514   // When SharedWorkerConnector receives ViewMsg_WorkerCreated(1), it sends
    515   // WorkerMsg_Connect wrapped in ViewHostMsg_ForwardToWorker.
    516   connector0->SendConnect();
    517   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    518   // WorkerMsg_Connect should be sent to SharedWorker side.
    519   CheckWorkerMsgConnect(renderer_host0.get(),
    520                         worker_route_id,
    521                         connector0->remote_port_id(),
    522                         &worker_msg_port_route_id1);
    523 
    524   // When SharedWorkerConnector receives MessagePortMsg_MessagesQueued(2), it
    525   // sends MessagePortHostMsg_SendQueuedMessages.
    526   std::vector<QueuedMessage> empty_messages;
    527   connector0->SendSendQueuedMessages(empty_messages);
    528   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    529 
    530   // SharedWorker sends WorkerHostMsg_WorkerScriptLoaded in
    531   // EmbeddedSharedWorkerStub::workerScriptLoaded().
    532   EXPECT_TRUE(renderer_host0->OnMessageReceived(
    533       new WorkerHostMsg_WorkerScriptLoaded(worker_route_id)));
    534   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    535 
    536   // SharedWorker sends WorkerHostMsg_WorkerConnected in
    537   // EmbeddedSharedWorkerStub::workerScriptLoaded().
    538   EXPECT_TRUE(
    539       renderer_host0->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
    540           connector0->remote_port_id(), worker_route_id)));
    541   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    542   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
    543   CheckViewMsgWorkerConnected(renderer_host0.get(), connector0.get());
    544 
    545   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
    546   // SharedWorker side shuold receive MessagePortMsg_Message.
    547   connector0->SendPostMessage("test1");
    548   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    549   CheckMessagePortMsgMessage(
    550       renderer_host0.get(), worker_msg_port_route_id1, "test1");
    551 
    552   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
    553   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
    554   const std::vector<int> empty_ids;
    555   EXPECT_TRUE(renderer_host0->OnMessageReceived(
    556       new MessagePortHostMsg_PostMessage(connector0->remote_port_id(),
    557                                          base::ASCIIToUTF16("test2"),
    558                                          empty_ids)));
    559   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    560   CheckMessagePortMsgMessage(
    561       renderer_host0.get(), connector0->local_port_route_id(), "test2");
    562 
    563   // The second renderer host.
    564   scoped_ptr<MockRendererProcessHost> renderer_host1(
    565       new MockRendererProcessHost(kProcessIDs[1],
    566                                   browser_context_->GetResourceContext(),
    567                                   *partition_.get()));
    568   scoped_ptr<MockSharedWorkerConnector> connector1(
    569       new MockSharedWorkerConnector(renderer_host1.get()));
    570   int worker_msg_port_route_id2;
    571 
    572   // UpdateWorkerDependency should not be called yet.
    573   EXPECT_EQ(0, s_update_worker_dependency_call_count_);
    574 
    575   // SharedWorkerConnector creates two message ports and sends
    576   // ViewHostMsg_CreateWorker.
    577   connector1->Create("http://example.com/w.js",
    578                      "name",
    579                      kDocumentIDs[1],
    580                      kRenderFrameRouteIDs[1]);
    581   // We need to go to UI thread to call ReserveRenderProcessOnUI().
    582   RunAllPendingInMessageLoop();
    583   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    584   // ViewMsg_WorkerCreated(3) should be sent back to SharedWorkerConnector side.
    585   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
    586 
    587   // UpdateWorkerDependency should be called.
    588   EXPECT_EQ(1, s_update_worker_dependency_call_count_);
    589   EXPECT_EQ(1U, s_worker_dependency_added_ids_.size());
    590   EXPECT_EQ(kProcessIDs[0], s_worker_dependency_added_ids_[0]);
    591   EXPECT_EQ(0U, s_worker_dependency_removed_ids_.size());
    592 
    593   // SharedWorkerConnector side sends MessagePortHostMsg_QueueMessages in
    594   // WebSharedWorkerProxy::connect.
    595   connector1->SendQueueMessages();
    596   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    597   // MessagePortMsg_MessagesQueued(4) should be sent back to
    598   // SharedWorkerConnector side.
    599   CheckMessagePortMsgMessagesQueued(renderer_host1.get(), connector1.get());
    600 
    601   // When SharedWorkerConnector receives ViewMsg_WorkerCreated(3), it sends
    602   // WorkerMsg_Connect wrapped in ViewHostMsg_ForwardToWorker.
    603   connector1->SendConnect();
    604   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    605   // WorkerMsg_Connect should be sent to SharedWorker side.
    606   CheckWorkerMsgConnect(renderer_host0.get(),
    607                         worker_route_id,
    608                         connector1->remote_port_id(),
    609                         &worker_msg_port_route_id2);
    610 
    611   // When SharedWorkerConnector receives MessagePortMsg_MessagesQueued(4), it
    612   // sends MessagePortHostMsg_SendQueuedMessages.
    613   connector1->SendSendQueuedMessages(empty_messages);
    614   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    615 
    616   // SharedWorker sends WorkerHostMsg_WorkerConnected in
    617   // EmbeddedSharedWorkerStub::OnConnect().
    618   EXPECT_TRUE(
    619       renderer_host0->OnMessageReceived(new WorkerHostMsg_WorkerConnected(
    620           connector1->remote_port_id(), worker_route_id)));
    621   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    622   // ViewMsg_WorkerConnected should be sent to SharedWorkerConnector side.
    623   CheckViewMsgWorkerConnected(renderer_host1.get(), connector1.get());
    624 
    625   // When SharedWorkerConnector side sends MessagePortHostMsg_PostMessage,
    626   // SharedWorker side shuold receive MessagePortMsg_Message.
    627   connector1->SendPostMessage("test3");
    628   EXPECT_EQ(1U, renderer_host0->QueuedMessageCount());
    629   CheckMessagePortMsgMessage(
    630       renderer_host0.get(), worker_msg_port_route_id2, "test3");
    631 
    632   // When SharedWorker side sends MessagePortHostMsg_PostMessage,
    633   // SharedWorkerConnector side shuold receive MessagePortMsg_Message.
    634   EXPECT_TRUE(renderer_host0->OnMessageReceived(
    635       new MessagePortHostMsg_PostMessage(connector1->remote_port_id(),
    636                                          base::ASCIIToUTF16("test4"),
    637                                          empty_ids)));
    638   EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    639   CheckMessagePortMsgMessage(
    640       renderer_host1.get(), connector1->local_port_route_id(), "test4");
    641 
    642   EXPECT_EQ(1, s_update_worker_dependency_call_count_);
    643   renderer_host1.reset();
    644   // UpdateWorkerDependency should be called.
    645   EXPECT_EQ(2, s_update_worker_dependency_call_count_);
    646   EXPECT_EQ(0U, s_worker_dependency_added_ids_.size());
    647   EXPECT_EQ(1U, s_worker_dependency_removed_ids_.size());
    648   EXPECT_EQ(kProcessIDs[0], s_worker_dependency_removed_ids_[0]);
    649 }
    650 
    651 TEST_F(SharedWorkerServiceImplTest, CreateWorkerTest) {
    652   // The first renderer host.
    653   scoped_ptr<MockRendererProcessHost> renderer_host0(
    654       new MockRendererProcessHost(kProcessIDs[0],
    655                                   browser_context_->GetResourceContext(),
    656                                   *partition_.get()));
    657   // The second renderer host.
    658   scoped_ptr<MockRendererProcessHost> renderer_host1(
    659       new MockRendererProcessHost(kProcessIDs[1],
    660                                   browser_context_->GetResourceContext(),
    661                                   *partition_.get()));
    662   int worker_route_id;
    663 
    664   // Normal case.
    665   {
    666     scoped_ptr<MockSharedWorkerConnector> connector0(
    667         new MockSharedWorkerConnector(renderer_host0.get()));
    668     scoped_ptr<MockSharedWorkerConnector> connector1(
    669         new MockSharedWorkerConnector(renderer_host1.get()));
    670     connector0->Create("http://example.com/w1.js",
    671                        "name1",
    672                        kDocumentIDs[0],
    673                        kRenderFrameRouteIDs[0]);
    674     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    675     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    676     RunAllPendingInMessageLoop();
    677     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    678     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    679                                       "http://example.com/w1.js",
    680                                       "name1",
    681                                       blink::WebContentSecurityPolicyTypeReport,
    682                                       &worker_route_id);
    683     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    684     connector1->Create("http://example.com/w1.js",
    685                        "name1",
    686                        kDocumentIDs[1],
    687                        kRenderFrameRouteIDs[1]);
    688     EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
    689     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    690     RunAllPendingInMessageLoop();
    691     EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    692     CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
    693   }
    694 
    695   // Normal case (URL mismatch).
    696   {
    697     scoped_ptr<MockSharedWorkerConnector> connector0(
    698         new MockSharedWorkerConnector(renderer_host0.get()));
    699     scoped_ptr<MockSharedWorkerConnector> connector1(
    700         new MockSharedWorkerConnector(renderer_host1.get()));
    701     connector0->Create("http://example.com/w2.js",
    702                        "name2",
    703                        kDocumentIDs[0],
    704                        kRenderFrameRouteIDs[0]);
    705     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    706     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    707     RunAllPendingInMessageLoop();
    708     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    709     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    710                                       "http://example.com/w2.js",
    711                                       "name2",
    712                                       blink::WebContentSecurityPolicyTypeReport,
    713                                       &worker_route_id);
    714     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    715     connector1->Create("http://example.com/w2x.js",
    716                        "name2",
    717                        kDocumentIDs[1],
    718                        kRenderFrameRouteIDs[1]);
    719     EXPECT_EQ(MSG_ROUTING_NONE, connector1->route_id());
    720     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    721     RunAllPendingInMessageLoop();
    722     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    723   }
    724 
    725   // Pending case.
    726   {
    727     scoped_ptr<MockSharedWorkerConnector> connector0(
    728         new MockSharedWorkerConnector(renderer_host0.get()));
    729     scoped_ptr<MockSharedWorkerConnector> connector1(
    730         new MockSharedWorkerConnector(renderer_host1.get()));
    731     connector0->Create("http://example.com/w3.js",
    732                        "name3",
    733                        kDocumentIDs[0],
    734                        kRenderFrameRouteIDs[0]);
    735     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    736     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    737     connector1->Create("http://example.com/w3.js",
    738                        "name3",
    739                        kDocumentIDs[1],
    740                        kRenderFrameRouteIDs[1]);
    741     EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
    742     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    743     RunAllPendingInMessageLoop();
    744     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    745     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    746                                       "http://example.com/w3.js",
    747                                       "name3",
    748                                       blink::WebContentSecurityPolicyTypeReport,
    749                                       &worker_route_id);
    750     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    751     EXPECT_EQ(1U, renderer_host1->QueuedMessageCount());
    752     CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
    753   }
    754 
    755   // Pending case (URL mismatch).
    756   {
    757     scoped_ptr<MockSharedWorkerConnector> connector0(
    758         new MockSharedWorkerConnector(renderer_host0.get()));
    759     scoped_ptr<MockSharedWorkerConnector> connector1(
    760         new MockSharedWorkerConnector(renderer_host1.get()));
    761     connector0->Create("http://example.com/w4.js",
    762                        "name4",
    763                        kDocumentIDs[0],
    764                        kRenderFrameRouteIDs[0]);
    765     EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    766     EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    767     connector1->Create("http://example.com/w4x.js",
    768                        "name4",
    769                        kDocumentIDs[1],
    770                        kRenderFrameRouteIDs[1]);
    771     EXPECT_EQ(MSG_ROUTING_NONE, connector1->route_id());
    772     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    773     RunAllPendingInMessageLoop();
    774     EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    775     CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    776                                       "http://example.com/w4.js",
    777                                       "name4",
    778                                       blink::WebContentSecurityPolicyTypeReport,
    779                                       &worker_route_id);
    780     CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    781     EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    782   }
    783 }
    784 
    785 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest) {
    786   // Create three renderer hosts.
    787   scoped_ptr<MockRendererProcessHost> renderer_host0(
    788       new MockRendererProcessHost(kProcessIDs[0],
    789                                   browser_context_->GetResourceContext(),
    790                                   *partition_.get()));
    791   scoped_ptr<MockRendererProcessHost> renderer_host1(
    792       new MockRendererProcessHost(kProcessIDs[1],
    793                                   browser_context_->GetResourceContext(),
    794                                   *partition_.get()));
    795   scoped_ptr<MockRendererProcessHost> renderer_host2(
    796       new MockRendererProcessHost(kProcessIDs[2],
    797                                   browser_context_->GetResourceContext(),
    798                                   *partition_.get()));
    799   int worker_route_id;
    800 
    801   scoped_ptr<MockSharedWorkerConnector> connector0(
    802       new MockSharedWorkerConnector(renderer_host0.get()));
    803   scoped_ptr<MockSharedWorkerConnector> connector1(
    804       new MockSharedWorkerConnector(renderer_host1.get()));
    805   scoped_ptr<MockSharedWorkerConnector> connector2(
    806       new MockSharedWorkerConnector(renderer_host2.get()));
    807   connector0->Create("http://example.com/w1.js",
    808                      "name1",
    809                      kDocumentIDs[0],
    810                      kRenderFrameRouteIDs[0]);
    811   EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    812   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    813   RunAllPendingInMessageLoop();
    814   EXPECT_EQ(2U, renderer_host0->QueuedMessageCount());
    815   CheckWorkerProcessMsgCreateWorker(renderer_host0.get(),
    816                                     "http://example.com/w1.js",
    817                                     "name1",
    818                                     blink::WebContentSecurityPolicyTypeReport,
    819                                     &worker_route_id);
    820   CheckViewMsgWorkerCreated(renderer_host0.get(), connector0.get());
    821   renderer_host0->FastShutdownIfPossible();
    822 
    823   connector1->Create("http://example.com/w1.js",
    824                      "name1",
    825                      kDocumentIDs[1],
    826                      kRenderFrameRouteIDs[1]);
    827   EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
    828   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    829   RunAllPendingInMessageLoop();
    830   EXPECT_EQ(2U, renderer_host1->QueuedMessageCount());
    831   CheckWorkerProcessMsgCreateWorker(renderer_host1.get(),
    832                                     "http://example.com/w1.js",
    833                                     "name1",
    834                                     blink::WebContentSecurityPolicyTypeReport,
    835                                     &worker_route_id);
    836   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
    837 
    838   connector2->Create("http://example.com/w1.js",
    839                      "name1",
    840                      kDocumentIDs[2],
    841                      kRenderFrameRouteIDs[2]);
    842   EXPECT_NE(MSG_ROUTING_NONE, connector2->route_id());
    843   EXPECT_EQ(0U, renderer_host2->QueuedMessageCount());
    844   RunAllPendingInMessageLoop();
    845   EXPECT_EQ(1U, renderer_host2->QueuedMessageCount());
    846   CheckViewMsgWorkerCreated(renderer_host2.get(), connector2.get());
    847 }
    848 
    849 TEST_F(SharedWorkerServiceImplTest, CreateWorkerRaceTest2) {
    850   // Create three renderer hosts.
    851   scoped_ptr<MockRendererProcessHost> renderer_host0(
    852       new MockRendererProcessHost(kProcessIDs[0],
    853                                   browser_context_->GetResourceContext(),
    854                                   *partition_.get()));
    855   scoped_ptr<MockRendererProcessHost> renderer_host1(
    856       new MockRendererProcessHost(kProcessIDs[1],
    857                                   browser_context_->GetResourceContext(),
    858                                   *partition_.get()));
    859   scoped_ptr<MockRendererProcessHost> renderer_host2(
    860       new MockRendererProcessHost(kProcessIDs[2],
    861                                   browser_context_->GetResourceContext(),
    862                                   *partition_.get()));
    863   int worker_route_id;
    864 
    865   scoped_ptr<MockSharedWorkerConnector> connector0(
    866       new MockSharedWorkerConnector(renderer_host0.get()));
    867   scoped_ptr<MockSharedWorkerConnector> connector1(
    868       new MockSharedWorkerConnector(renderer_host1.get()));
    869   scoped_ptr<MockSharedWorkerConnector> connector2(
    870       new MockSharedWorkerConnector(renderer_host2.get()));
    871   connector0->Create("http://example.com/w1.js",
    872                      "name1",
    873                      kDocumentIDs[0],
    874                      kRenderFrameRouteIDs[0]);
    875   EXPECT_NE(MSG_ROUTING_NONE, connector0->route_id());
    876   EXPECT_EQ(0U, renderer_host0->QueuedMessageCount());
    877   renderer_host0->FastShutdownIfPossible();
    878 
    879   connector1->Create("http://example.com/w1.js",
    880                      "name1",
    881                      kDocumentIDs[1],
    882                      kRenderFrameRouteIDs[1]);
    883   EXPECT_NE(MSG_ROUTING_NONE, connector1->route_id());
    884   EXPECT_EQ(0U, renderer_host1->QueuedMessageCount());
    885   RunAllPendingInMessageLoop();
    886   EXPECT_EQ(2U, renderer_host1->QueuedMessageCount());
    887   CheckWorkerProcessMsgCreateWorker(renderer_host1.get(),
    888                                     "http://example.com/w1.js",
    889                                     "name1",
    890                                     blink::WebContentSecurityPolicyTypeReport,
    891                                     &worker_route_id);
    892   CheckViewMsgWorkerCreated(renderer_host1.get(), connector1.get());
    893 
    894   connector2->Create("http://example.com/w1.js",
    895                      "name1",
    896                      kDocumentIDs[2],
    897                      kRenderFrameRouteIDs[2]);
    898   EXPECT_NE(MSG_ROUTING_NONE, connector2->route_id());
    899   EXPECT_EQ(0U, renderer_host2->QueuedMessageCount());
    900   RunAllPendingInMessageLoop();
    901   EXPECT_EQ(1U, renderer_host2->QueuedMessageCount());
    902   CheckViewMsgWorkerCreated(renderer_host2.get(), connector2.get());
    903 }
    904 
    905 }  // namespace content
    906