| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/test/base/mojo_test_connector.h" | 5 #include "chrome/test/base/mojo_test_connector.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "services/service_manager/background/tests/test_catalog_store.h" | 22 #include "services/service_manager/background/tests/test_catalog_store.h" |
| 23 #include "services/service_manager/native_runner_delegate.h" | 23 #include "services/service_manager/native_runner_delegate.h" |
| 24 #include "services/service_manager/public/cpp/connector.h" | 24 #include "services/service_manager/public/cpp/connector.h" |
| 25 #include "services/service_manager/public/cpp/service.h" | 25 #include "services/service_manager/public/cpp/service.h" |
| 26 #include "services/service_manager/public/cpp/service_context.h" | 26 #include "services/service_manager/public/cpp/service_context.h" |
| 27 #include "services/service_manager/runner/common/client_util.h" | 27 #include "services/service_manager/runner/common/client_util.h" |
| 28 #include "services/service_manager/runner/common/switches.h" | 28 #include "services/service_manager/runner/common/switches.h" |
| 29 #include "services/service_manager/service_manager.h" | 29 #include "services/service_manager/service_manager.h" |
| 30 #include "services/service_manager/switches.h" | 30 #include "services/service_manager/switches.h" |
| 31 | 31 |
| 32 using shell::mojom::Service; | 32 using service_manager::mojom::Service; |
| 33 using shell::mojom::ServicePtr; | 33 using service_manager::mojom::ServicePtr; |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 const char kTestRunnerName[] = "exe:mash_browser_tests"; | 37 const char kTestRunnerName[] = "exe:mash_browser_tests"; |
| 38 const char kTestName[] = "service:content_browser"; | 38 const char kTestName[] = "service:content_browser"; |
| 39 | 39 |
| 40 // BackgroundTestState maintains all the state necessary to bind the test to | 40 // BackgroundTestState maintains all the state necessary to bind the test to |
| 41 // mojo. This class is only used on the thread created by BackgroundShell. | 41 // mojo. This class is only used on the thread created by BackgroundShell. |
| 42 class BackgroundTestState { | 42 class BackgroundTestState { |
| 43 public: | 43 public: |
| 44 BackgroundTestState() : child_token_(mojo::edk::GenerateRandomToken()) {} | 44 BackgroundTestState() : child_token_(mojo::edk::GenerateRandomToken()) {} |
| 45 ~BackgroundTestState() {} | 45 ~BackgroundTestState() {} |
| 46 | 46 |
| 47 // Prepares the command line and other setup for connecting the test to mojo. | 47 // Prepares the command line and other setup for connecting the test to mojo. |
| 48 // Must be paired with a call to ChildProcessLaunched(). | 48 // Must be paired with a call to ChildProcessLaunched(). |
| 49 void Connect(base::CommandLine* command_line, | 49 void Connect(base::CommandLine* command_line, |
| 50 shell::ServiceManager* service_manager, | 50 service_manager::ServiceManager* service_manager, |
| 51 base::TestLauncher::LaunchOptions* test_launch_options) { | 51 base::TestLauncher::LaunchOptions* test_launch_options) { |
| 52 command_line->AppendSwitch(MojoTestConnector::kTestSwitch); | 52 command_line->AppendSwitch(MojoTestConnector::kTestSwitch); |
| 53 command_line->AppendSwitch(switches::kChildProcess); | 53 command_line->AppendSwitch(switches::kChildProcess); |
| 54 mojo_ipc_channel_.reset(new mojo::edk::PlatformChannelPair); | 54 mojo_ipc_channel_.reset(new mojo::edk::PlatformChannelPair); |
| 55 mojo_ipc_channel_->PrepareToPassClientHandleToChildProcess( | 55 mojo_ipc_channel_->PrepareToPassClientHandleToChildProcess( |
| 56 command_line, &handle_passing_info_); | 56 command_line, &handle_passing_info_); |
| 57 #if defined(OS_WIN) | 57 #if defined(OS_WIN) |
| 58 test_launch_options->inherit_handles = true; | 58 test_launch_options->inherit_handles = true; |
| 59 test_launch_options->handles_to_inherit = &handle_passing_info_; | 59 test_launch_options->handles_to_inherit = &handle_passing_info_; |
| 60 #if defined(OFFICIAL_BUILD) | 60 #if defined(OFFICIAL_BUILD) |
| 61 CHECK(false) << "Launching mojo process with inherit_handles is insecure!"; | 61 CHECK(false) << "Launching mojo process with inherit_handles is insecure!"; |
| 62 #endif | 62 #endif |
| 63 #elif defined(OS_POSIX) | 63 #elif defined(OS_POSIX) |
| 64 test_launch_options->fds_to_remap = &handle_passing_info_; | 64 test_launch_options->fds_to_remap = &handle_passing_info_; |
| 65 #else | 65 #else |
| 66 #error "Unsupported" | 66 #error "Unsupported" |
| 67 #endif | 67 #endif |
| 68 shell::mojom::ServicePtr service = | 68 service_manager::mojom::ServicePtr service = |
| 69 shell::PassServiceRequestOnCommandLine(command_line, child_token_); | 69 service_manager::PassServiceRequestOnCommandLine(command_line, |
| 70 child_token_); |
| 70 | 71 |
| 71 std::unique_ptr<shell::ConnectParams> params(new shell::ConnectParams); | 72 std::unique_ptr<service_manager::ConnectParams> params( |
| 72 params->set_source(shell::CreateServiceManagerIdentity()); | 73 new service_manager::ConnectParams); |
| 74 params->set_source(service_manager::CreateServiceManagerIdentity()); |
| 73 // Use the default instance name (which should be "browser"). Otherwise a | 75 // Use the default instance name (which should be "browser"). Otherwise a |
| 74 // service (e.g. ash) that connects to the default "service:content_browser" | 76 // service (e.g. ash) that connects to the default "service:content_browser" |
| 75 // will spawn a new instance. | 77 // will spawn a new instance. |
| 76 params->set_target(shell::Identity(kTestName, shell::mojom::kRootUserID)); | 78 params->set_target(service_manager::Identity( |
| 79 kTestName, service_manager::mojom::kRootUserID)); |
| 77 | 80 |
| 78 shell::mojom::ClientProcessConnectionPtr client_process_connection = | 81 service_manager::mojom::ClientProcessConnectionPtr |
| 79 shell::mojom::ClientProcessConnection::New(); | 82 client_process_connection = |
| 83 service_manager::mojom::ClientProcessConnection::New(); |
| 80 client_process_connection->service = | 84 client_process_connection->service = |
| 81 service.PassInterface().PassHandle(); | 85 service.PassInterface().PassHandle(); |
| 82 client_process_connection->pid_receiver_request = | 86 client_process_connection->pid_receiver_request = |
| 83 mojo::GetProxy(&pid_receiver_).PassMessagePipe(); | 87 mojo::GetProxy(&pid_receiver_).PassMessagePipe(); |
| 84 params->set_client_process_connection(std::move(client_process_connection)); | 88 params->set_client_process_connection(std::move(client_process_connection)); |
| 85 service_manager->Connect(std::move(params)); | 89 service_manager->Connect(std::move(params)); |
| 86 } | 90 } |
| 87 | 91 |
| 88 // Called after the test process has launched. Completes the registration done | 92 // Called after the test process has launched. Completes the registration done |
| 89 // in Connect(). | 93 // in Connect(). |
| 90 void ChildProcessLaunched(base::ProcessHandle handle, base::ProcessId pid) { | 94 void ChildProcessLaunched(base::ProcessHandle handle, base::ProcessId pid) { |
| 91 pid_receiver_->SetPID(pid); | 95 pid_receiver_->SetPID(pid); |
| 92 mojo_ipc_channel_->ChildProcessLaunched(); | 96 mojo_ipc_channel_->ChildProcessLaunched(); |
| 93 mojo::edk::ChildProcessLaunched( | 97 mojo::edk::ChildProcessLaunched( |
| 94 handle, mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle( | 98 handle, mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle( |
| 95 mojo_ipc_channel_->PassServerHandle().release().handle)), | 99 mojo_ipc_channel_->PassServerHandle().release().handle)), |
| 96 child_token_); | 100 child_token_); |
| 97 } | 101 } |
| 98 | 102 |
| 99 private: | 103 private: |
| 100 // Used to back the NodeChannel between the parent and child node. | 104 // Used to back the NodeChannel between the parent and child node. |
| 101 const std::string child_token_; | 105 const std::string child_token_; |
| 102 std::unique_ptr<mojo::edk::PlatformChannelPair> mojo_ipc_channel_; | 106 std::unique_ptr<mojo::edk::PlatformChannelPair> mojo_ipc_channel_; |
| 103 | 107 |
| 104 mojo::edk::HandlePassingInformation handle_passing_info_; | 108 mojo::edk::HandlePassingInformation handle_passing_info_; |
| 105 | 109 |
| 106 shell::mojom::PIDReceiverPtr pid_receiver_; | 110 service_manager::mojom::PIDReceiverPtr pid_receiver_; |
| 107 | 111 |
| 108 DISALLOW_COPY_AND_ASSIGN(BackgroundTestState); | 112 DISALLOW_COPY_AND_ASSIGN(BackgroundTestState); |
| 109 }; | 113 }; |
| 110 | 114 |
| 111 // Called used destroy BackgroundTestState on the background thread. | 115 // Called used destroy BackgroundTestState on the background thread. |
| 112 void DestroyBackgroundStateOnBackgroundThread( | 116 void DestroyBackgroundStateOnBackgroundThread( |
| 113 std::unique_ptr<BackgroundTestState> state, | 117 std::unique_ptr<BackgroundTestState> state, |
| 114 shell::ServiceManager* service_manager) {} | 118 service_manager::ServiceManager* service_manager) {} |
| 115 | 119 |
| 116 // State created per test. Manages creation of the corresponding | 120 // State created per test. Manages creation of the corresponding |
| 117 // BackgroundTestState and making sure processing runs on the right threads. | 121 // BackgroundTestState and making sure processing runs on the right threads. |
| 118 class MojoTestState : public content::TestState { | 122 class MojoTestState : public content::TestState { |
| 119 public: | 123 public: |
| 120 explicit MojoTestState(shell::BackgroundShell* background_shell) | 124 explicit MojoTestState(service_manager::BackgroundShell* background_shell) |
| 121 : background_shell_(background_shell) {} | 125 : background_shell_(background_shell) {} |
| 122 | 126 |
| 123 ~MojoTestState() override { | 127 ~MojoTestState() override { |
| 124 DCHECK(background_state_); | 128 DCHECK(background_state_); |
| 125 // BackgroundState needs to be destroyed on the background thread. We're | 129 // BackgroundState needs to be destroyed on the background thread. We're |
| 126 // guaranteed |background_shell_| has been created by the time we reach | 130 // guaranteed |background_shell_| has been created by the time we |
| 127 // here as Init() blocks until |background_shell_| has been created. | 131 // reach |
| 132 // here as Init() blocks until |background_shell_| has been |
| 133 // created. |
| 128 background_shell_->ExecuteOnServiceManagerThread( | 134 background_shell_->ExecuteOnServiceManagerThread( |
| 129 base::Bind(&DestroyBackgroundStateOnBackgroundThread, | 135 base::Bind(&DestroyBackgroundStateOnBackgroundThread, |
| 130 base::Passed(&background_state_))); | 136 base::Passed(&background_state_))); |
| 131 } | 137 } |
| 132 | 138 |
| 133 void Init(base::CommandLine* command_line, | 139 void Init(base::CommandLine* command_line, |
| 134 base::TestLauncher::LaunchOptions* test_launch_options) { | 140 base::TestLauncher::LaunchOptions* test_launch_options) { |
| 135 base::WaitableEvent signal(base::WaitableEvent::ResetPolicy::MANUAL, | 141 base::WaitableEvent signal(base::WaitableEvent::ResetPolicy::MANUAL, |
| 136 base::WaitableEvent::InitialState::NOT_SIGNALED); | 142 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 137 background_shell_->ExecuteOnServiceManagerThread(base::Bind( | 143 background_shell_->ExecuteOnServiceManagerThread(base::Bind( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 153 background_shell_->ExecuteOnServiceManagerThread( | 159 background_shell_->ExecuteOnServiceManagerThread( |
| 154 base::Bind(&MojoTestState::ChildProcessLaunchedOnBackgroundThread, | 160 base::Bind(&MojoTestState::ChildProcessLaunchedOnBackgroundThread, |
| 155 base::Unretained(this), handle, pid, &signal)); | 161 base::Unretained(this), handle, pid, &signal)); |
| 156 signal.Wait(); | 162 signal.Wait(); |
| 157 } | 163 } |
| 158 | 164 |
| 159 void ChildProcessLaunchedOnBackgroundThread( | 165 void ChildProcessLaunchedOnBackgroundThread( |
| 160 base::ProcessHandle handle, | 166 base::ProcessHandle handle, |
| 161 base::ProcessId pid, | 167 base::ProcessId pid, |
| 162 base::WaitableEvent* signal, | 168 base::WaitableEvent* signal, |
| 163 shell::ServiceManager* service_manager) { | 169 service_manager::ServiceManager* service_manager) { |
| 164 background_state_->ChildProcessLaunched(handle, pid); | 170 background_state_->ChildProcessLaunched(handle, pid); |
| 165 signal->Signal(); | 171 signal->Signal(); |
| 166 } | 172 } |
| 167 | 173 |
| 168 void BindOnBackgroundThread( | 174 void BindOnBackgroundThread( |
| 169 base::WaitableEvent* signal, | 175 base::WaitableEvent* signal, |
| 170 base::CommandLine* command_line, | 176 base::CommandLine* command_line, |
| 171 base::TestLauncher::LaunchOptions* test_launch_options, | 177 base::TestLauncher::LaunchOptions* test_launch_options, |
| 172 shell::ServiceManager* service_manager) { | 178 service_manager::ServiceManager* service_manager) { |
| 173 background_state_.reset(new BackgroundTestState); | 179 background_state_.reset(new BackgroundTestState); |
| 174 background_state_->Connect(command_line, service_manager, | 180 background_state_->Connect(command_line, service_manager, |
| 175 test_launch_options); | 181 test_launch_options); |
| 176 signal->Signal(); | 182 signal->Signal(); |
| 177 } | 183 } |
| 178 | 184 |
| 179 shell::BackgroundShell* background_shell_; | 185 service_manager::BackgroundShell* background_shell_; |
| 180 std::unique_ptr<BackgroundTestState> background_state_; | 186 std::unique_ptr<BackgroundTestState> background_state_; |
| 181 | 187 |
| 182 DISALLOW_COPY_AND_ASSIGN(MojoTestState); | 188 DISALLOW_COPY_AND_ASSIGN(MojoTestState); |
| 183 }; | 189 }; |
| 184 | 190 |
| 185 // The name in the manifest results in getting exe:mash_browser_tests used, | 191 // The name in the manifest results in getting exe:mash_browser_tests used, |
| 186 // remap that to browser_tests. | 192 // remap that to browser_tests. |
| 187 void RemoveMashFromBrowserTests(base::CommandLine* command_line) { | 193 void RemoveMashFromBrowserTests(base::CommandLine* command_line) { |
| 188 base::FilePath exe_path(command_line->GetProgram()); | 194 base::FilePath exe_path(command_line->GetProgram()); |
| 189 #if defined(OS_WIN) | 195 #if defined(OS_WIN) |
| 190 exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("browser_tests.exe")); | 196 exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("browser_tests.exe")); |
| 191 #else | 197 #else |
| 192 exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("browser_tests")); | 198 exe_path = exe_path.DirName().Append(FILE_PATH_LITERAL("browser_tests")); |
| 193 #endif | 199 #endif |
| 194 command_line->SetProgram(exe_path); | 200 command_line->SetProgram(exe_path); |
| 195 } | 201 } |
| 196 | 202 |
| 197 } // namespace | 203 } // namespace |
| 198 | 204 |
| 199 // NativeRunnerDelegate that makes exe:mash_browser_tests to exe:browser_tests, | 205 // NativeRunnerDelegate that makes exe:mash_browser_tests to exe:browser_tests, |
| 200 // and removes '--run-in-mash'. | 206 // and removes '--run-in-mash'. |
| 201 class MojoTestConnector::NativeRunnerDelegateImpl | 207 class MojoTestConnector::NativeRunnerDelegateImpl |
| 202 : public shell::NativeRunnerDelegate { | 208 : public service_manager::NativeRunnerDelegate { |
| 203 public: | 209 public: |
| 204 NativeRunnerDelegateImpl() {} | 210 NativeRunnerDelegateImpl() {} |
| 205 ~NativeRunnerDelegateImpl() override {} | 211 ~NativeRunnerDelegateImpl() override {} |
| 206 | 212 |
| 207 private: | 213 private: |
| 208 // shell::NativeRunnerDelegate: | 214 // service_manager::NativeRunnerDelegate: |
| 209 void AdjustCommandLineArgumentsForTarget( | 215 void AdjustCommandLineArgumentsForTarget( |
| 210 const shell::Identity& target, | 216 const service_manager::Identity& target, |
| 211 base::CommandLine* command_line) override { | 217 base::CommandLine* command_line) override { |
| 212 if (target.name() != kTestName) { | 218 if (target.name() != kTestName) { |
| 213 if (target.name() == kTestRunnerName) | 219 if (target.name() == kTestRunnerName) |
| 214 RemoveMashFromBrowserTests(command_line); | 220 RemoveMashFromBrowserTests(command_line); |
| 215 command_line->AppendSwitch(MojoTestConnector::kMashApp); | 221 command_line->AppendSwitch(MojoTestConnector::kMashApp); |
| 216 return; | 222 return; |
| 217 } | 223 } |
| 218 | 224 |
| 219 base::CommandLine::StringVector argv(command_line->argv()); | 225 base::CommandLine::StringVector argv(command_line->argv()); |
| 220 auto iter = | 226 auto iter = |
| 221 std::find(argv.begin(), argv.end(), FILE_PATH_LITERAL("--run-in-mash")); | 227 std::find(argv.begin(), argv.end(), FILE_PATH_LITERAL("--run-in-mash")); |
| 222 if (iter != argv.end()) | 228 if (iter != argv.end()) |
| 223 argv.erase(iter); | 229 argv.erase(iter); |
| 224 *command_line = base::CommandLine(argv); | 230 *command_line = base::CommandLine(argv); |
| 225 } | 231 } |
| 226 | 232 |
| 227 DISALLOW_COPY_AND_ASSIGN(NativeRunnerDelegateImpl); | 233 DISALLOW_COPY_AND_ASSIGN(NativeRunnerDelegateImpl); |
| 228 }; | 234 }; |
| 229 | 235 |
| 230 // static | 236 // static |
| 231 const char MojoTestConnector::kTestSwitch[] = "is_test"; | 237 const char MojoTestConnector::kTestSwitch[] = "is_test"; |
| 232 // static | 238 // static |
| 233 const char MojoTestConnector::kMashApp[] = "mash-app"; | 239 const char MojoTestConnector::kMashApp[] = "mash-app"; |
| 234 | 240 |
| 235 MojoTestConnector::MojoTestConnector() {} | 241 MojoTestConnector::MojoTestConnector() {} |
| 236 | 242 |
| 237 shell::mojom::ServiceRequest MojoTestConnector::Init() { | 243 service_manager::mojom::ServiceRequest MojoTestConnector::Init() { |
| 238 native_runner_delegate_ = base::MakeUnique<NativeRunnerDelegateImpl>(); | 244 native_runner_delegate_ = base::MakeUnique<NativeRunnerDelegateImpl>(); |
| 239 | 245 |
| 240 std::unique_ptr<shell::BackgroundShell::InitParams> init_params( | 246 std::unique_ptr<service_manager::BackgroundShell::InitParams> init_params( |
| 241 new shell::BackgroundShell::InitParams); | 247 new service_manager::BackgroundShell::InitParams); |
| 242 // When running in single_process mode chrome initializes the edk. | 248 // When running in single_process mode chrome initializes the edk. |
| 243 init_params->init_edk = !base::CommandLine::ForCurrentProcess()->HasSwitch( | 249 init_params->init_edk = !base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 244 content::kSingleProcessTestsFlag); | 250 content::kSingleProcessTestsFlag); |
| 245 init_params->native_runner_delegate = native_runner_delegate_.get(); | 251 init_params->native_runner_delegate = native_runner_delegate_.get(); |
| 246 background_shell_.Init(std::move(init_params)); | 252 background_shell_.Init(std::move(init_params)); |
| 247 return background_shell_.CreateServiceRequest(kTestRunnerName); | 253 return background_shell_.CreateServiceRequest(kTestRunnerName); |
| 248 } | 254 } |
| 249 | 255 |
| 250 MojoTestConnector::~MojoTestConnector() {} | 256 MojoTestConnector::~MojoTestConnector() {} |
| 251 | 257 |
| 252 std::unique_ptr<content::TestState> MojoTestConnector::PrepareForTest( | 258 std::unique_ptr<content::TestState> MojoTestConnector::PrepareForTest( |
| 253 base::CommandLine* command_line, | 259 base::CommandLine* command_line, |
| 254 base::TestLauncher::LaunchOptions* test_launch_options) { | 260 base::TestLauncher::LaunchOptions* test_launch_options) { |
| 255 std::unique_ptr<MojoTestState> test_state( | 261 std::unique_ptr<MojoTestState> test_state( |
| 256 new MojoTestState(&background_shell_)); | 262 new MojoTestState(&background_shell_)); |
| 257 test_state->Init(command_line, test_launch_options); | 263 test_state->Init(command_line, test_launch_options); |
| 258 return std::move(test_state); | 264 return std::move(test_state); |
| 259 } | 265 } |
| OLD | NEW |