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/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
    918