| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_process_manager.h" | 5 #include "content/browser/service_worker/service_worker_process_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/macros.h" | 8 #include "base/macros.h" |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 const int kEmbeddedWorkerId2 = 200; | 131 const int kEmbeddedWorkerId2 = 200; |
| 132 const int kEmbeddedWorkerId3 = 300; | 132 const int kEmbeddedWorkerId3 = 300; |
| 133 GURL scope1("http://example.com/scope1"); | 133 GURL scope1("http://example.com/scope1"); |
| 134 GURL scope2("http://example.com/scope2"); | 134 GURL scope2("http://example.com/scope2"); |
| 135 | 135 |
| 136 // Set up mock renderer process hosts. | 136 // Set up mock renderer process hosts. |
| 137 std::unique_ptr<MockRenderProcessHost> host1(CreateRenderProcessHost()); | 137 std::unique_ptr<MockRenderProcessHost> host1(CreateRenderProcessHost()); |
| 138 std::unique_ptr<MockRenderProcessHost> host2(CreateRenderProcessHost()); | 138 std::unique_ptr<MockRenderProcessHost> host2(CreateRenderProcessHost()); |
| 139 process_manager_->AddProcessReferenceToPattern(scope1, host1->GetID()); | 139 process_manager_->AddProcessReferenceToPattern(scope1, host1->GetID()); |
| 140 process_manager_->AddProcessReferenceToPattern(scope2, host2->GetID()); | 140 process_manager_->AddProcessReferenceToPattern(scope2, host2->GetID()); |
| 141 ASSERT_EQ(0, host1->worker_ref_count()); | 141 ASSERT_EQ(0u, host1->GetWorkerRefCount()); |
| 142 ASSERT_EQ(0, host2->worker_ref_count()); | 142 ASSERT_EQ(0u, host2->GetWorkerRefCount()); |
| 143 | 143 |
| 144 std::map<int, ServiceWorkerProcessManager::ProcessInfo>& instance_info = | 144 std::map<int, ServiceWorkerProcessManager::ProcessInfo>& instance_info = |
| 145 process_manager_->instance_info_; | 145 process_manager_->instance_info_; |
| 146 | 146 |
| 147 // (1) Allocate a process to a worker. | 147 // (1) Allocate a process to a worker. |
| 148 base::RunLoop run_loop1; | 148 base::RunLoop run_loop1; |
| 149 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; | 149 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 150 int process_id = -10; | 150 int process_id = -10; |
| 151 bool is_new_process = true; | 151 bool is_new_process = true; |
| 152 process_manager_->AllocateWorkerProcess( | 152 process_manager_->AllocateWorkerProcess( |
| 153 kEmbeddedWorkerId1, scope1, script_url_, | 153 kEmbeddedWorkerId1, scope1, script_url_, |
| 154 true /* can_use_existing_process */, | 154 true /* can_use_existing_process */, |
| 155 base::Bind(&DidAllocateWorkerProcess, run_loop1.QuitClosure(), &status, | 155 base::Bind(&DidAllocateWorkerProcess, run_loop1.QuitClosure(), &status, |
| 156 &process_id, &is_new_process)); | 156 &process_id, &is_new_process)); |
| 157 run_loop1.Run(); | 157 run_loop1.Run(); |
| 158 | 158 |
| 159 // An existing process should be allocated to the worker. | 159 // An existing process should be allocated to the worker. |
| 160 EXPECT_EQ(SERVICE_WORKER_OK, status); | 160 EXPECT_EQ(SERVICE_WORKER_OK, status); |
| 161 EXPECT_EQ(host1->GetID(), process_id); | 161 EXPECT_EQ(host1->GetID(), process_id); |
| 162 EXPECT_FALSE(is_new_process); | 162 EXPECT_FALSE(is_new_process); |
| 163 EXPECT_EQ(1, host1->worker_ref_count()); | 163 EXPECT_EQ(1u, host1->GetWorkerRefCount()); |
| 164 EXPECT_EQ(0, host2->worker_ref_count()); | 164 EXPECT_EQ(0u, host2->GetWorkerRefCount()); |
| 165 EXPECT_EQ(1u, instance_info.size()); | 165 EXPECT_EQ(1u, instance_info.size()); |
| 166 std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found = | 166 std::map<int, ServiceWorkerProcessManager::ProcessInfo>::iterator found = |
| 167 instance_info.find(kEmbeddedWorkerId1); | 167 instance_info.find(kEmbeddedWorkerId1); |
| 168 ASSERT_TRUE(found != instance_info.end()); | 168 ASSERT_TRUE(found != instance_info.end()); |
| 169 EXPECT_EQ(host1->GetID(), found->second.process_id); | 169 EXPECT_EQ(host1->GetID(), found->second.process_id); |
| 170 | 170 |
| 171 // (2) Allocate a process to another worker whose scope is the same with the | 171 // (2) Allocate a process to another worker whose scope is the same with the |
| 172 // first worker. | 172 // first worker. |
| 173 base::RunLoop run_loop2; | 173 base::RunLoop run_loop2; |
| 174 status = SERVICE_WORKER_ERROR_MAX_VALUE; | 174 status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 175 process_id = -10; | 175 process_id = -10; |
| 176 is_new_process = true; | 176 is_new_process = true; |
| 177 process_manager_->AllocateWorkerProcess( | 177 process_manager_->AllocateWorkerProcess( |
| 178 kEmbeddedWorkerId2, scope1, script_url_, | 178 kEmbeddedWorkerId2, scope1, script_url_, |
| 179 true /* can_use_existing_process */, | 179 true /* can_use_existing_process */, |
| 180 base::Bind(&DidAllocateWorkerProcess, run_loop2.QuitClosure(), &status, | 180 base::Bind(&DidAllocateWorkerProcess, run_loop2.QuitClosure(), &status, |
| 181 &process_id, &is_new_process)); | 181 &process_id, &is_new_process)); |
| 182 run_loop2.Run(); | 182 run_loop2.Run(); |
| 183 | 183 |
| 184 // The same process should be allocated to the second worker. | 184 // The same process should be allocated to the second worker. |
| 185 EXPECT_EQ(SERVICE_WORKER_OK, status); | 185 EXPECT_EQ(SERVICE_WORKER_OK, status); |
| 186 EXPECT_EQ(host1->GetID(), process_id); | 186 EXPECT_EQ(host1->GetID(), process_id); |
| 187 EXPECT_FALSE(is_new_process); | 187 EXPECT_FALSE(is_new_process); |
| 188 EXPECT_EQ(2, host1->worker_ref_count()); | 188 EXPECT_EQ(2u, host1->GetWorkerRefCount()); |
| 189 EXPECT_EQ(0, host2->worker_ref_count()); | 189 EXPECT_EQ(0u, host2->GetWorkerRefCount()); |
| 190 EXPECT_EQ(2u, instance_info.size()); | 190 EXPECT_EQ(2u, instance_info.size()); |
| 191 found = instance_info.find(kEmbeddedWorkerId2); | 191 found = instance_info.find(kEmbeddedWorkerId2); |
| 192 ASSERT_TRUE(found != instance_info.end()); | 192 ASSERT_TRUE(found != instance_info.end()); |
| 193 EXPECT_EQ(host1->GetID(), found->second.process_id); | 193 EXPECT_EQ(host1->GetID(), found->second.process_id); |
| 194 | 194 |
| 195 // (3) Allocate a process to a third worker whose scope is different from | 195 // (3) Allocate a process to a third worker whose scope is different from |
| 196 // other workers. | 196 // other workers. |
| 197 base::RunLoop run_loop3; | 197 base::RunLoop run_loop3; |
| 198 status = SERVICE_WORKER_ERROR_MAX_VALUE; | 198 status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 199 process_id = -10; | 199 process_id = -10; |
| 200 is_new_process = true; | 200 is_new_process = true; |
| 201 process_manager_->AllocateWorkerProcess( | 201 process_manager_->AllocateWorkerProcess( |
| 202 kEmbeddedWorkerId3, scope2, script_url_, | 202 kEmbeddedWorkerId3, scope2, script_url_, |
| 203 true /* can_use_existing_process */, | 203 true /* can_use_existing_process */, |
| 204 base::Bind(&DidAllocateWorkerProcess, run_loop3.QuitClosure(), &status, | 204 base::Bind(&DidAllocateWorkerProcess, run_loop3.QuitClosure(), &status, |
| 205 &process_id, &is_new_process)); | 205 &process_id, &is_new_process)); |
| 206 run_loop3.Run(); | 206 run_loop3.Run(); |
| 207 | 207 |
| 208 // A different existing process should be allocated to the third worker. | 208 // A different existing process should be allocated to the third worker. |
| 209 EXPECT_EQ(SERVICE_WORKER_OK, status); | 209 EXPECT_EQ(SERVICE_WORKER_OK, status); |
| 210 EXPECT_EQ(host2->GetID(), process_id); | 210 EXPECT_EQ(host2->GetID(), process_id); |
| 211 EXPECT_FALSE(is_new_process); | 211 EXPECT_FALSE(is_new_process); |
| 212 EXPECT_EQ(2, host1->worker_ref_count()); | 212 EXPECT_EQ(2u, host1->GetWorkerRefCount()); |
| 213 EXPECT_EQ(1, host2->worker_ref_count()); | 213 EXPECT_EQ(1u, host2->GetWorkerRefCount()); |
| 214 EXPECT_EQ(3u, instance_info.size()); | 214 EXPECT_EQ(3u, instance_info.size()); |
| 215 found = instance_info.find(kEmbeddedWorkerId3); | 215 found = instance_info.find(kEmbeddedWorkerId3); |
| 216 ASSERT_TRUE(found != instance_info.end()); | 216 ASSERT_TRUE(found != instance_info.end()); |
| 217 EXPECT_EQ(host2->GetID(), found->second.process_id); | 217 EXPECT_EQ(host2->GetID(), found->second.process_id); |
| 218 | 218 |
| 219 // The instance map should be updated by process release. | 219 // The instance map should be updated by process release. |
| 220 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId3); | 220 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId3); |
| 221 EXPECT_EQ(2, host1->worker_ref_count()); | 221 EXPECT_EQ(2u, host1->GetWorkerRefCount()); |
| 222 EXPECT_EQ(0, host2->worker_ref_count()); | 222 EXPECT_EQ(0u, host2->GetWorkerRefCount()); |
| 223 EXPECT_EQ(2u, instance_info.size()); | 223 EXPECT_EQ(2u, instance_info.size()); |
| 224 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId1)); | 224 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId1)); |
| 225 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); | 225 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); |
| 226 | 226 |
| 227 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId1); | 227 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId1); |
| 228 EXPECT_EQ(1, host1->worker_ref_count()); | 228 EXPECT_EQ(1u, host1->GetWorkerRefCount()); |
| 229 EXPECT_EQ(0, host2->worker_ref_count()); | 229 EXPECT_EQ(0u, host2->GetWorkerRefCount()); |
| 230 EXPECT_EQ(1u, instance_info.size()); | 230 EXPECT_EQ(1u, instance_info.size()); |
| 231 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); | 231 EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); |
| 232 | 232 |
| 233 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId2); | 233 process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId2); |
| 234 EXPECT_EQ(0, host1->worker_ref_count()); | 234 EXPECT_EQ(0u, host1->GetWorkerRefCount()); |
| 235 EXPECT_EQ(0, host2->worker_ref_count()); | 235 EXPECT_EQ(0u, host2->GetWorkerRefCount()); |
| 236 EXPECT_TRUE(instance_info.empty()); | 236 EXPECT_TRUE(instance_info.empty()); |
| 237 } | 237 } |
| 238 | 238 |
| 239 TEST_P(ServiceWorkerProcessManagerTestP, AllocateWorkerProcess_InShutdown) { | 239 TEST_P(ServiceWorkerProcessManagerTestP, AllocateWorkerProcess_InShutdown) { |
| 240 process_manager_->Shutdown(); | 240 process_manager_->Shutdown(); |
| 241 ASSERT_TRUE(process_manager_->IsShutdown()); | 241 ASSERT_TRUE(process_manager_->IsShutdown()); |
| 242 | 242 |
| 243 base::RunLoop run_loop; | 243 base::RunLoop run_loop; |
| 244 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; | 244 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 245 int process_id = -10; | 245 int process_id = -10; |
| 246 bool is_new_process = true; | 246 bool is_new_process = true; |
| 247 process_manager_->AllocateWorkerProcess( | 247 process_manager_->AllocateWorkerProcess( |
| 248 1, pattern_, script_url_, true /* can_use_existing_process */, | 248 1, pattern_, script_url_, true /* can_use_existing_process */, |
| 249 base::Bind(&DidAllocateWorkerProcess, run_loop.QuitClosure(), &status, | 249 base::Bind(&DidAllocateWorkerProcess, run_loop.QuitClosure(), &status, |
| 250 &process_id, &is_new_process)); | 250 &process_id, &is_new_process)); |
| 251 run_loop.Run(); | 251 run_loop.Run(); |
| 252 | 252 |
| 253 // Allocating a process in shutdown should abort. | 253 // Allocating a process in shutdown should abort. |
| 254 EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status); | 254 EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status); |
| 255 EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, process_id); | 255 EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, process_id); |
| 256 EXPECT_FALSE(is_new_process); | 256 EXPECT_FALSE(is_new_process); |
| 257 EXPECT_TRUE(process_manager_->instance_info_.empty()); | 257 EXPECT_TRUE(process_manager_->instance_info_.empty()); |
| 258 } | 258 } |
| 259 | 259 |
| 260 INSTANTIATE_TEST_CASE_P(ServiceWorkerProcessManagerTest, | 260 INSTANTIATE_TEST_CASE_P(ServiceWorkerProcessManagerTest, |
| 261 ServiceWorkerProcessManagerTestP, | 261 ServiceWorkerProcessManagerTestP, |
| 262 testing::Bool()); | 262 testing::Bool()); |
| 263 | 263 |
| 264 } // namespace content | 264 } // namespace content |
| OLD | NEW |