Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / service_process / service_process_control_browsertest.cc
blobe718f1b7dd5a6750a7c630918fac7c2000da56a6
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/service_process/service_process_control.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/path_service.h"
11 #include "base/process/kill.h"
12 #include "base/process/process_handle.h"
13 #include "base/process/process_iterator.h"
14 #include "base/test/test_timeouts.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/common/chrome_constants.h"
17 #include "chrome/common/chrome_version_info.h"
18 #include "chrome/common/service_process_util.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "content/public/common/content_paths.h"
22 #include "content/public/common/content_switches.h"
23 #include "testing/gmock/include/gmock/gmock.h"
25 class ServiceProcessControlBrowserTest
26 : public InProcessBrowserTest {
27 public:
28 ServiceProcessControlBrowserTest()
29 : service_process_handle_(base::kNullProcessHandle) {
31 virtual ~ServiceProcessControlBrowserTest() {
32 base::CloseProcessHandle(service_process_handle_);
33 service_process_handle_ = base::kNullProcessHandle;
36 void HistogramsCallback() {
37 MockHistogramsCallback();
38 QuitMessageLoop();
41 MOCK_METHOD0(MockHistogramsCallback, void());
43 protected:
44 void LaunchServiceProcessControl() {
45 // Launch the process asynchronously.
46 ServiceProcessControl::GetInstance()->Launch(
47 base::Bind(&ServiceProcessControlBrowserTest::ProcessControlLaunched,
48 this),
49 base::Bind(
50 &ServiceProcessControlBrowserTest::ProcessControlLaunchFailed,
51 this));
53 // Then run the message loop to keep things running.
54 content::RunMessageLoop();
57 static void QuitMessageLoop() {
58 base::MessageLoop::current()->Quit();
61 static void CloudPrintInfoCallback(
62 const cloud_print::CloudPrintProxyInfo& proxy_info) {
63 QuitMessageLoop();
66 void Disconnect() {
67 // This will close the IPC connection.
68 ServiceProcessControl::GetInstance()->Disconnect();
71 virtual void SetUp() OVERRIDE {
72 service_process_handle_ = base::kNullProcessHandle;
75 virtual void TearDown() OVERRIDE {
76 if (ServiceProcessControl::GetInstance()->IsConnected())
77 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
78 #if defined(OS_MACOSX)
79 // ForceServiceProcessShutdown removes the process from launched on Mac.
80 ForceServiceProcessShutdown("", 0);
81 #endif // OS_MACOSX
82 if (service_process_handle_ != base::kNullProcessHandle) {
83 EXPECT_TRUE(base::WaitForSingleProcess(
84 service_process_handle_,
85 TestTimeouts::action_max_timeout()));
86 service_process_handle_ = base::kNullProcessHandle;
90 void ProcessControlLaunched() {
91 base::ProcessId service_pid;
92 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
93 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
94 EXPECT_TRUE(base::OpenProcessHandleWithAccess(
95 service_pid,
96 base::kProcessAccessWaitForTermination |
97 // we need query permission to get exit code
98 base::kProcessAccessQueryInformation,
99 &service_process_handle_));
100 // Quit the current message. Post a QuitTask instead of just calling Quit()
101 // because this can get invoked in the context of a Launch() call and we
102 // may not be in Run() yet.
103 base::MessageLoop::current()->PostTask(FROM_HERE,
104 base::MessageLoop::QuitClosure());
107 void ProcessControlLaunchFailed() {
108 ADD_FAILURE();
109 // Quit the current message.
110 base::MessageLoop::current()->PostTask(FROM_HERE,
111 base::MessageLoop::QuitClosure());
114 private:
115 base::ProcessHandle service_process_handle_;
118 class RealServiceProcessControlBrowserTest
119 : public ServiceProcessControlBrowserTest {
120 public:
121 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
122 ServiceProcessControlBrowserTest::SetUpCommandLine(command_line);
123 base::FilePath exe;
124 PathService::Get(base::DIR_EXE, &exe);
125 #if defined(OS_MACOSX)
126 exe = exe.DirName().DirName().DirName();
127 #endif
128 exe = exe.Append(chrome::kHelperProcessExecutablePath);
129 // Run chrome instead of browser_tests.exe.
130 EXPECT_TRUE(base::PathExists(exe));
131 command_line->AppendSwitchPath(switches::kBrowserSubprocessPath, exe);
135 #if defined(OS_MACOSX)
136 // Does not work on MACOSX.
137 #define MAYBE_LaunchAndIPC DISABLED_LaunchAndIPC
138 #else
139 #define MAYBE_LaunchAndIPC LaunchAndIPC
140 #endif
142 IN_PROC_BROWSER_TEST_F(RealServiceProcessControlBrowserTest,
143 MAYBE_LaunchAndIPC) {
144 LaunchServiceProcessControl();
146 // Make sure we are connected to the service process.
147 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
148 ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
149 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
150 content::RunMessageLoop();
152 // And then shutdown the service process.
153 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
156 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
157 LaunchServiceProcessControl();
159 // Make sure we are connected to the service process.
160 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
161 ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
162 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
163 content::RunMessageLoop();
165 // And then shutdown the service process.
166 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
169 // This tests the case when a service process is launched when the browser
170 // starts but we try to launch it again while setting up Cloud Print.
171 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchTwice) {
172 // Launch the service process the first time.
173 LaunchServiceProcessControl();
175 // Make sure we are connected to the service process.
176 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
177 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
178 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
179 content::RunMessageLoop();
181 // Launch the service process again.
182 LaunchServiceProcessControl();
183 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
184 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
185 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
186 content::RunMessageLoop();
189 static void DecrementUntilZero(int* count) {
190 (*count)--;
191 if (!(*count))
192 base::MessageLoop::current()->PostTask(FROM_HERE,
193 base::MessageLoop::QuitClosure());
196 // Invoke multiple Launch calls in succession and ensure that all the tasks
197 // get invoked.
198 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
199 MultipleLaunchTasks) {
200 ServiceProcessControl* process = ServiceProcessControl::GetInstance();
201 int launch_count = 5;
202 for (int i = 0; i < launch_count; i++) {
203 // Launch the process asynchronously.
204 process->Launch(base::Bind(&DecrementUntilZero, &launch_count),
205 base::MessageLoop::QuitClosure());
207 // Then run the message loop to keep things running.
208 content::RunMessageLoop();
209 EXPECT_EQ(0, launch_count);
212 // Make sure using the same task for success and failure tasks works.
213 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, SameLaunchTask) {
214 ServiceProcessControl* process = ServiceProcessControl::GetInstance();
215 int launch_count = 5;
216 for (int i = 0; i < launch_count; i++) {
217 // Launch the process asynchronously.
218 base::Closure task = base::Bind(&DecrementUntilZero, &launch_count);
219 process->Launch(task, task);
221 // Then run the message loop to keep things running.
222 content::RunMessageLoop();
223 EXPECT_EQ(0, launch_count);
226 // Tests whether disconnecting from the service IPC causes the service process
227 // to die.
228 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, DieOnDisconnect) {
229 // Launch the service process.
230 LaunchServiceProcessControl();
231 // Make sure we are connected to the service process.
232 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
233 Disconnect();
236 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, ForceShutdown) {
237 // Launch the service process.
238 LaunchServiceProcessControl();
239 // Make sure we are connected to the service process.
240 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
241 base::ProcessId service_pid;
242 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
243 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
244 chrome::VersionInfo version_info;
245 ForceServiceProcessShutdown(version_info.Version(), service_pid);
248 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, CheckPid) {
249 base::ProcessId service_pid;
250 EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
251 // Launch the service process.
252 LaunchServiceProcessControl();
253 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
254 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
255 // Disconnect from service process.
256 Disconnect();
259 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsNoService) {
260 ASSERT_FALSE(ServiceProcessControl::GetInstance()->IsConnected());
261 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
262 EXPECT_FALSE(ServiceProcessControl::GetInstance()->GetHistograms(
263 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
264 base::Unretained(this)),
265 base::TimeDelta()));
268 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsTimeout) {
269 LaunchServiceProcessControl();
270 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
271 // Callback should not be called during GetHistograms call.
272 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
273 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
274 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
275 base::Unretained(this)),
276 base::TimeDelta::FromMilliseconds(100)));
277 EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
278 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
279 content::RunMessageLoop();
282 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, Histograms) {
283 LaunchServiceProcessControl();
284 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
285 // Callback should not be called during GetHistograms call.
286 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
287 // Wait for real callback by providing large timeout value.
288 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
289 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
290 base::Unretained(this)),
291 base::TimeDelta::FromHours(1)));
292 EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
293 content::RunMessageLoop();