1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/basictypes.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h" 7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/stl_util.h" 8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_instance.h" 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_registry.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_test_helper.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "content/browser/service_worker/service_worker_context_wrapper.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/service_worker/embedded_worker_messages.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content { 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const int kRenderProcessId = 11; 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class EmbeddedWorkerInstanceTest : public testing::Test { 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected: 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EmbeddedWorkerInstanceTest() 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void SetUp() OVERRIDE { 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu helper_.reset(new EmbeddedWorkerTestHelper(kRenderProcessId)); 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual void TearDown() OVERRIDE { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helper_.reset(); 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerContextCore* context() { return helper_->context(); } 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EmbeddedWorkerRegistry* embedded_worker_registry() { 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DCHECK(context()); 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return context()->embedded_worker_registry(); 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestBrowserThreadBundle thread_bundle_; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<EmbeddedWorkerTestHelper> helper_; 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest); 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic void SaveStatusAndCall(ServiceWorkerStatusCode* out, 525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::Closure& callback, 535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerStatusCode status) { 545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = status; 555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu callback.Run(); 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) { 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<EmbeddedWorkerInstance> worker = 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) embedded_worker_registry()->CreateWorker(); 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const int64 service_worker_version_id = 55L; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL pattern("http://example.com/"); 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const GURL url("http://example.com/worker.js"); 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Simulate adding one process to the pattern. 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId); 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Start should succeed. 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerStatusCode status; 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::RunLoop run_loop; 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu worker->Start( 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_worker_version_id, 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url, 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch false, 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu run_loop.Run(); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(SERVICE_WORKER_OK, status); 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status()); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Worker started message should be notified (by EmbeddedWorkerTestHelper). 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status()); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(kRenderProcessId, worker->process_id()); 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Stop the worker. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop()); 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, worker->status()); 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Worker stopped message should be notified (by EmbeddedWorkerTestHelper). 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Verify that we've sent two messages to start and terminate the worker. 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EmbeddedWorkerMsg_StartWorker::ID)); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching( 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EmbeddedWorkerMsg_StopWorker::ID)); 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(EmbeddedWorkerInstanceTest, InstanceDestroyedBeforeStartFinishes) { 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<EmbeddedWorkerInstance> worker = 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu embedded_worker_registry()->CreateWorker(); 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const int64 service_worker_version_id = 55L; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL pattern("http://example.com/"); 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const GURL url("http://example.com/worker.js"); 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ServiceWorkerStatusCode status; 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::RunLoop run_loop; 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Begin starting the worker. 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context()->process_manager()->AddProcessReferenceToPattern( 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, kRenderProcessId); 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu worker->Start( 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu service_worker_version_id, 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern, 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu url, 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch false, 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // But destroy it before it gets a chance to complete. 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu worker.reset(); 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu run_loop.Run(); 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status); 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Verify that we didn't send the message to start the worker. 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_FALSE( 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ipc_sink()->GetUniqueMessageMatching(EmbeddedWorkerMsg_StartWorker::ID)); 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace content 134