Home | History | Annotate | Download | only in devtools
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/devtools/embedded_worker_devtools_manager.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/run_loop.h"
     10 #include "content/browser/browser_thread_impl.h"
     11 #include "content/browser/devtools/devtools_manager_impl.h"
     12 #include "content/browser/shared_worker/shared_worker_instance.h"
     13 #include "content/browser/worker_host/worker_storage_partition.h"
     14 #include "content/public/browser/devtools_agent_host.h"
     15 #include "content/public/browser/devtools_client_host.h"
     16 #include "content/public/test/test_browser_context.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace content {
     20 namespace {
     21 
     22 class TestDevToolsClientHost : public DevToolsClientHost {
     23  public:
     24   TestDevToolsClientHost() {}
     25   virtual ~TestDevToolsClientHost() {}
     26   virtual void DispatchOnInspectorFrontend(
     27       const std::string& message) OVERRIDE {}
     28   virtual void InspectedContentsClosing() OVERRIDE {}
     29   virtual void ReplacedWithAnotherClient() OVERRIDE {}
     30 
     31  private:
     32   DISALLOW_COPY_AND_ASSIGN(TestDevToolsClientHost);
     33 };
     34 }
     35 
     36 class EmbeddedWorkerDevToolsManagerTest : public testing::Test {
     37  public:
     38   EmbeddedWorkerDevToolsManagerTest()
     39       : ui_thread_(BrowserThread::UI, &message_loop_),
     40         browser_context_(new TestBrowserContext()),
     41         partition_(
     42             new WorkerStoragePartition(browser_context_->GetRequestContext(),
     43                                        NULL,
     44                                        NULL,
     45                                        NULL,
     46                                        NULL,
     47                                        NULL,
     48                                        NULL,
     49                                        NULL)),
     50         partition_id_(*partition_.get()) {}
     51 
     52  protected:
     53   virtual void SetUp() OVERRIDE {
     54     manager_ = EmbeddedWorkerDevToolsManager::GetInstance();
     55   }
     56   virtual void TearDown() OVERRIDE {
     57     EmbeddedWorkerDevToolsManager::GetInstance()->ResetForTesting();
     58   }
     59 
     60   void CheckWorkerState(int worker_process_id,
     61                         int worker_route_id,
     62                         EmbeddedWorkerDevToolsManager::WorkerState state) {
     63     const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
     64                                                      worker_route_id);
     65     EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator it =
     66         manager_->workers_.find(id);
     67     EXPECT_TRUE(manager_->workers_.end() != it);
     68     EXPECT_EQ(state, it->second->state());
     69   }
     70 
     71   void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
     72     const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
     73                                                      worker_route_id);
     74     EXPECT_TRUE(manager_->workers_.end() == manager_->workers_.find(id));
     75   }
     76 
     77   void CheckWorkerCount(size_t size) {
     78     EXPECT_EQ(size, manager_->workers_.size());
     79   }
     80 
     81   void RegisterDevToolsClientHostFor(DevToolsAgentHost* agent_host,
     82                                      DevToolsClientHost* client_host) {
     83     DevToolsManagerImpl::GetInstance()->RegisterDevToolsClientHostFor(
     84         agent_host, client_host);
     85   }
     86 
     87   void ClientHostClosing(DevToolsClientHost* client_host) {
     88     DevToolsManagerImpl::GetInstance()->ClientHostClosing(client_host);
     89   }
     90 
     91   base::MessageLoopForIO message_loop_;
     92   BrowserThreadImpl ui_thread_;
     93   scoped_ptr<TestBrowserContext> browser_context_;
     94   scoped_ptr<WorkerStoragePartition> partition_;
     95   const WorkerStoragePartitionId partition_id_;
     96   EmbeddedWorkerDevToolsManager* manager_;
     97 };
     98 
     99 TEST_F(EmbeddedWorkerDevToolsManagerTest, BasicTest) {
    100   scoped_refptr<DevToolsAgentHost> agent_host;
    101 
    102   SharedWorkerInstance instance1(GURL("http://example.com/w.js"),
    103                                  base::string16(),
    104                                  base::string16(),
    105                                  blink::WebContentSecurityPolicyTypeReport,
    106                                  browser_context_->GetResourceContext(),
    107                                  partition_id_);
    108 
    109   agent_host = manager_->GetDevToolsAgentHostForWorker(1, 1);
    110   EXPECT_FALSE(agent_host.get());
    111 
    112   // Created -> Started -> Destroyed
    113   CheckWorkerNotExist(1, 1);
    114   manager_->SharedWorkerCreated(1, 1, instance1);
    115   CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    116   manager_->WorkerContextStarted(1, 1);
    117   CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    118   manager_->WorkerDestroyed(1, 1);
    119   CheckWorkerNotExist(1, 1);
    120 
    121   // Created -> GetDevToolsAgentHost -> Started -> Destroyed
    122   CheckWorkerNotExist(1, 2);
    123   manager_->SharedWorkerCreated(1, 2, instance1);
    124   CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    125   agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
    126   EXPECT_TRUE(agent_host.get());
    127   CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    128   EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
    129   manager_->WorkerContextStarted(1, 2);
    130   CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    131   manager_->WorkerDestroyed(1, 2);
    132   CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    133   agent_host = NULL;
    134   CheckWorkerNotExist(1, 2);
    135 
    136   // Created -> Started -> GetDevToolsAgentHost -> Destroyed
    137   CheckWorkerNotExist(1, 3);
    138   manager_->SharedWorkerCreated(1, 3, instance1);
    139   CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    140   manager_->WorkerContextStarted(1, 3);
    141   CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    142   agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
    143   EXPECT_TRUE(agent_host.get());
    144   CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    145   manager_->WorkerDestroyed(1, 3);
    146   CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    147   agent_host = NULL;
    148   CheckWorkerNotExist(1, 3);
    149 
    150   // Created -> Destroyed
    151   CheckWorkerNotExist(1, 4);
    152   manager_->SharedWorkerCreated(1, 4, instance1);
    153   CheckWorkerState(1, 4, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    154   manager_->WorkerDestroyed(1, 4);
    155   CheckWorkerNotExist(1, 4);
    156 
    157   // Created -> GetDevToolsAgentHost -> Destroyed
    158   CheckWorkerNotExist(1, 5);
    159   manager_->SharedWorkerCreated(1, 5, instance1);
    160   CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    161   agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
    162   EXPECT_TRUE(agent_host.get());
    163   CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    164   manager_->WorkerDestroyed(1, 5);
    165   CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    166   agent_host = NULL;
    167   CheckWorkerNotExist(1, 5);
    168 
    169   // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
    170   CheckWorkerNotExist(1, 6);
    171   manager_->SharedWorkerCreated(1, 6, instance1);
    172   CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    173   agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
    174   EXPECT_TRUE(agent_host.get());
    175   CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    176   agent_host = NULL;
    177   manager_->WorkerDestroyed(1, 6);
    178   CheckWorkerNotExist(1, 6);
    179 }
    180 
    181 TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
    182   scoped_refptr<DevToolsAgentHost> agent_host1;
    183   scoped_refptr<DevToolsAgentHost> agent_host2;
    184 
    185   SharedWorkerInstance instance1(GURL("http://example.com/w1.js"),
    186                                  base::string16(),
    187                                  base::string16(),
    188                                  blink::WebContentSecurityPolicyTypeReport,
    189                                  browser_context_->GetResourceContext(),
    190                                  partition_id_);
    191   SharedWorkerInstance instance2(GURL("http://example.com/w2.js"),
    192                                  base::string16(),
    193                                  base::string16(),
    194                                  blink::WebContentSecurityPolicyTypeReport,
    195                                  browser_context_->GetResourceContext(),
    196                                  partition_id_);
    197 
    198   // Created -> GetDevToolsAgentHost -> Register -> Started -> Destroyed
    199   scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
    200   CheckWorkerNotExist(2, 1);
    201   manager_->SharedWorkerCreated(2, 1, instance1);
    202   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    203   agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
    204   EXPECT_TRUE(agent_host1.get());
    205   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    206   EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
    207   RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get());
    208   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    209   manager_->WorkerContextStarted(2, 1);
    210   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    211   manager_->WorkerDestroyed(2, 1);
    212   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    213   EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
    214 
    215   // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
    216   scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost());
    217   manager_->SharedWorkerCreated(2, 2, instance2);
    218   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    219   manager_->WorkerContextStarted(2, 2);
    220   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED);
    221   agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
    222   EXPECT_TRUE(agent_host2.get());
    223   EXPECT_NE(agent_host1.get(), agent_host2.get());
    224   EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
    225   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    226   RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get());
    227   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    228   manager_->WorkerDestroyed(2, 2);
    229   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    230   EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
    231 
    232   // Re-created -> Started -> ClientHostClosing -> Destroyed
    233   CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    234   manager_->SharedWorkerCreated(2, 3, instance1);
    235   CheckWorkerNotExist(2, 1);
    236   CheckWorkerState(
    237       2, 3, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
    238   EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
    239   manager_->WorkerContextStarted(2, 3);
    240   CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
    241   ClientHostClosing(client_host1.get());
    242   manager_->WorkerDestroyed(2, 3);
    243   CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    244   agent_host1 = NULL;
    245   CheckWorkerNotExist(2, 3);
    246 
    247   // Re-created -> Destroyed
    248   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    249   manager_->SharedWorkerCreated(2, 4, instance2);
    250   CheckWorkerNotExist(2, 2);
    251   CheckWorkerState(
    252       2, 4, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
    253   EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
    254   manager_->WorkerDestroyed(2, 4);
    255   CheckWorkerNotExist(2, 4);
    256   CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
    257 
    258   // Re-created -> ClientHostClosing -> Destroyed
    259   manager_->SharedWorkerCreated(2, 5, instance2);
    260   CheckWorkerNotExist(2, 2);
    261   CheckWorkerState(
    262       2, 5, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
    263   EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
    264   ClientHostClosing(client_host2.get());
    265   CheckWorkerCount(1);
    266   agent_host2 = NULL;
    267   CheckWorkerCount(1);
    268   manager_->WorkerDestroyed(2, 5);
    269   CheckWorkerCount(0);
    270 }
    271 
    272 }  // namespace content
    273