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