12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_test_base.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 10a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/kill.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_descriptors.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_POSIX) 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/posix/global_descriptors.h" 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string IPCTestBase::GetChannelName(const std::string& test_client_name) { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!test_client_name.empty()); 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return test_client_name + "__Channel"; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IPCTestBase::IPCTestBase() 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : client_process_(base::kNullProcessHandle) { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IPCTestBase::~IPCTestBase() { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::SetUp() { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MultiProcessTest::SetUp(); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Construct a fresh IO Message loop for the duration of each test. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!message_loop_.get()); 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_loop_.reset(new base::MessageLoopForIO()); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::TearDown() { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(message_loop_.get()); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_loop_.reset(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MultiProcessTest::TearDown(); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::Init(const std::string& test_client_name) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!test_client_name.empty()); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(test_client_name_.empty()); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_client_name_ = test_client_name; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::CreateChannel(IPC::Listener* listener) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateChannelFromChannelHandle(GetChannelName(test_client_name_), 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IPCTestBase::ConnectChannel() { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(channel_.get()); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return channel_->Connect(); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::DestroyChannel() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(channel_.get()); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_.reset(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::CreateChannelFromChannelHandle( 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IPC::ChannelHandle& channel_handle, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Listener* listener) { 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!channel_.get()); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!channel_proxy_.get()); 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) channel_ = IPC::Channel::CreateServer(channel_handle, listener); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::CreateChannelProxy( 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Listener* listener, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SingleThreadTaskRunner* ipc_task_runner) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!channel_.get()); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!channel_proxy_.get()); 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_proxy_ = IPC::ChannelProxy::Create(GetChannelName(test_client_name_), 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Channel::MODE_SERVER, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener, 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ipc_task_runner); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void IPCTestBase::DestroyChannelProxy() { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(channel_proxy_.get()); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_proxy_.reset(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IPCTestBase::StartClient() { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_process_ == base::kNullProcessHandle); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string test_main = test_client_name_ + "TestClientMain"; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) client_process_ = SpawnChild(test_main); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_POSIX) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FileHandleMappingVector fds_to_map; 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const int ipcfd = channel_.get() 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ? channel_->GetClientFileDescriptor() 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : channel_proxy_->GetClientFileDescriptor(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ipcfd > -1) 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fds_to_map.push_back(std::pair<int, int>(ipcfd, 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::LaunchOptions options; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) options.fds_to_remap = &fds_to_map; 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) client_process_ = SpawnChildWithOptions(test_main, options); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return client_process_ != base::kNullProcessHandle; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IPCTestBase::WaitForClientShutdown() { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_process_ != base::kNullProcessHandle); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rv = base::WaitForSingleProcess(client_process_, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(5)); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::CloseProcessHandle(client_process_); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_process_ = base::kNullProcessHandle; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return rv; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 123