worker_process_launcher_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_listener.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/auto_thread_task_runner.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/host_exit_codes.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/win/launch_process_with_token.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/win/worker_process_launcher.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/worker_process_ipc_delegate.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock_mutant.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::ScopedHandle; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::CreateFunctor; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Expectation; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Invoke; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InvokeWithoutArgs; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ReturnPointee; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIpcSecurityDescriptor[] = "D:(A;;GA;;;AU)"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockProcessLauncherDelegate 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public WorkerProcessLauncher::Delegate { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockProcessLauncherDelegate() {} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockProcessLauncherDelegate() {} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual DWORD GetProcessId() const OVERRIDE { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<MockProcessLauncherDelegate*>(this)->GetProcessId(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsPermanentError(int failure_count) const OVERRIDE { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return const_cast<MockProcessLauncherDelegate*>(this)->IsPermanentError( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failure_count); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPC::Sender implementation. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(Send, bool(IPC::Message*)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WorkerProcessLauncher::Delegate implementation 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD0(GetProcessId, DWORD()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(IsPermanentError, bool(int)); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(KillProcess, void(DWORD)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD2(LaunchProcess, bool(IPC::Listener*, ScopedHandle*)); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockProcessLauncherDelegate); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockIpcDelegate 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public WorkerProcessIpcDelegate { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockIpcDelegate() {} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockIpcDelegate() {} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WorkerProcessIpcDelegate implementation 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnChannelConnected, void(int32)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD0(OnPermanentError, void()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MockIpcDelegate); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkerProcessLauncherTest 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public testing::Test, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public IPC::Listener { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerProcessLauncherTest(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~WorkerProcessLauncherTest(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPC::Listener implementation 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WorkerProcessLauncher::Delegate mocks 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void KillProcess(DWORD exit_code); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool LaunchProcess(IPC::Listener* delegate, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool LaunchProcessAndConnect(IPC::Listener* delegate, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FailLaunchAndStopWorker(IPC::Listener* delegate, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ConnectChannel(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DisconnectChannel(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts the worker. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartWorker(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stops the worker. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopWorker(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Quits |message_loop_|. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void QuitMainMessageLoop(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop message_loop_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AutoThreadTaskRunner> task_runner_; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockIpcDelegate ipc_delegate_; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MockProcessLauncherDelegate> launcher_delegate_; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The name of the IPC channel. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string channel_name_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client and server ends of the IPC channel. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IPC::ChannelProxy> channel_client_; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IPC::ChannelProxy> channel_server_; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returned as the worker process PID to the launcher. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD client_pid_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The worker process launcher. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkerProcessLauncher> launcher_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The event signalling termination of the worker process. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle process_exit_event_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if a permanent error condition should be emulated. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool permanent_error_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerProcessLauncherTest::WorkerProcessLauncherTest() 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : message_loop_(MessageLoop::TYPE_IO), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_pid_(GetCurrentProcessId()), 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permanent_error_(false) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerProcessLauncherTest::~WorkerProcessLauncherTest() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::SetUp() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_ = new AutoThreadTaskRunner( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.message_loop_proxy(), 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WorkerProcessLauncherTest::QuitMainMessageLoop, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up process launcher delegate 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_delegate_.reset(new MockProcessLauncherDelegate()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, Send(_)) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Return(false)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, GetProcessId()) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(ReturnPointee(&client_pid_)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, IsPermanentError(_)) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(ReturnPointee(&permanent_error_)); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, KillProcess(_)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::KillProcess)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up IPC delegate. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnMessageReceived(_)) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(AnyNumber()) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Return(false)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::TearDown() { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerProcessLauncherTest::OnMessageReceived(const IPC::Message& message) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::KillProcess(DWORD exit_code) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL result = SetEvent(process_exit_event_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(result); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerProcessLauncherTest::LaunchProcess( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Listener* delegate, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_exit_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!process_exit_event_.IsValid()) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle pipe; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreateIpcChannel(channel_name_, kIpcSecurityDescriptor, &pipe)) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap the pipe into an IPC channel. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_server_.reset(new IPC::ChannelProxy( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::ChannelHandle(pipe), 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Channel::MODE_SERVER, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DuplicateHandle(GetCurrentProcess(), 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_exit_event_, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetCurrentProcess(), 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_exit_event_out->Receive(), 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FALSE, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DUPLICATE_SAME_ACCESS) != FALSE; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerProcessLauncherTest::LaunchProcessAndConnect( 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Listener* delegate, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LaunchProcess(delegate, process_exit_event_out)) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_->PostTask( 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WorkerProcessLauncherTest::ConnectChannel, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WorkerProcessLauncherTest::FailLaunchAndStopWorker( 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Listener* delegate, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedHandle* process_exit_event_out) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_->PostTask( 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WorkerProcessLauncherTest::StopWorker, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::ConnectChannel() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_client_.reset(new IPC::ChannelProxy( 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::ChannelHandle(channel_name_), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Channel::MODE_CLIENT, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_)); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::DisconnectChannel() { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_client_.reset(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::StartWorker() { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_.reset(new WorkerProcessLauncher( 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_, launcher_delegate_.Pass(), &ipc_delegate_)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::StopWorker() { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_.reset(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisconnectChannel(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_name_.clear(); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_server_.reset(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_ = NULL; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WorkerProcessLauncherTest::QuitMainMessageLoop() { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, Start) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::LaunchProcess)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopWorker(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starts and connects to the worker process. Expect OnChannelConnected to be 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// called. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, StartAndConnect) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &WorkerProcessLauncherTest::StopWorker)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Kills the worker process after the 1st connect and expects it to be 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restarted. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, Restart) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(2) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke( 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expectation first_connect = 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(2) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(CreateFunctor( 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &WorkerProcessLauncherTest::StopWorker)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Drops the IPC channel to the worker process after the 1st connect and expects 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the worker process to be restarted. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, DropIpcChannel) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(2) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Expectation first_connect = 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(2) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs( 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::DisconnectChannel)) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs( 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::StopWorker)); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a permanent error exit code and expects OnPermanentError() to be 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// invoked. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, PermanentError) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillRepeatedly(Invoke( 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(CreateFunctor( 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(1) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(InvokeWithoutArgs(this, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &WorkerProcessLauncherTest::StopWorker)); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permanent_error_ = true; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns invalid client PID and expects the connection to be rejected. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerProcessLauncherTest, InvalidClientPid) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(2) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Invoke( 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(Invoke( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &WorkerProcessLauncherTest::FailLaunchAndStopWorker)); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ipc_delegate_, OnPermanentError()) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .Times(0); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_pid_ = GetCurrentProcessId() + 4; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartWorker(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_.Run(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 397