Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / service_process / service_process_control_browsertest.cc
blobb4bd874e909f906e23fa07587614aca052cec6aa
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/location.h"
11 #include "base/path_service.h"
12 #include "base/process/kill.h"
13 #include "base/process/process.h"
14 #include "base/process/process_iterator.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/test/test_timeouts.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/chrome_constants.h"
20 #include "chrome/common/chrome_version_info.h"
21 #include "chrome/common/service_process_util.h"
22 #include "chrome/test/base/in_process_browser_test.h"
23 #include "content/public/common/content_paths.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/test/test_utils.h"
26 #include "testing/gmock/include/gmock/gmock.h"
28 class ServiceProcessControlBrowserTest
29 : public InProcessBrowserTest {
30 public:
31 ServiceProcessControlBrowserTest() {
33 virtual ~ServiceProcessControlBrowserTest() {
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 void SetUp() override {
72 InProcessBrowserTest::SetUp();
74 // This should not be needed because TearDown() ends with a closed
75 // service_process_, but HistogramsTimeout and Histograms fail without this
76 // on Mac.
77 service_process_.Close();
80 void TearDown() override {
81 if (ServiceProcessControl::GetInstance()->IsConnected())
82 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
83 #if defined(OS_MACOSX)
84 // ForceServiceProcessShutdown removes the process from launched on Mac.
85 ForceServiceProcessShutdown("", 0);
86 #endif // OS_MACOSX
87 if (service_process_.IsValid()) {
88 int exit_code;
89 EXPECT_TRUE(service_process_.WaitForExitWithTimeout(
90 TestTimeouts::action_max_timeout(), &exit_code));
91 EXPECT_EQ(0, exit_code);
92 service_process_.Close();
95 InProcessBrowserTest::TearDown();
98 void ProcessControlLaunched() {
99 base::ProcessId service_pid;
100 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
101 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
102 #if defined(OS_WIN)
103 service_process_ =
104 base::Process::OpenWithAccess(service_pid,
105 SYNCHRONIZE | PROCESS_QUERY_INFORMATION);
106 #else
107 service_process_ = base::Process::Open(service_pid);
108 #endif
109 EXPECT_TRUE(service_process_.IsValid());
110 // Quit the current message. Post a QuitTask instead of just calling Quit()
111 // because this can get invoked in the context of a Launch() call and we
112 // may not be in Run() yet.
113 base::ThreadTaskRunnerHandle::Get()->PostTask(
114 FROM_HERE, base::MessageLoop::QuitClosure());
117 void ProcessControlLaunchFailed() {
118 ADD_FAILURE();
119 // Quit the current message.
120 base::ThreadTaskRunnerHandle::Get()->PostTask(
121 FROM_HERE, base::MessageLoop::QuitClosure());
124 private:
125 base::Process service_process_;
128 class RealServiceProcessControlBrowserTest
129 : public ServiceProcessControlBrowserTest {
130 public:
131 void SetUpCommandLine(base::CommandLine* command_line) override {
132 ServiceProcessControlBrowserTest::SetUpCommandLine(command_line);
133 base::FilePath exe;
134 PathService::Get(base::DIR_EXE, &exe);
135 #if defined(OS_MACOSX)
136 exe = exe.DirName().DirName().DirName();
137 #endif
138 exe = exe.Append(chrome::kHelperProcessExecutablePath);
139 // Run chrome instead of browser_tests.exe.
140 EXPECT_TRUE(base::PathExists(exe));
141 command_line->AppendSwitchPath(switches::kBrowserSubprocessPath, exe);
145 // TODO(vitalybuka): Fix crbug.com/340563
146 IN_PROC_BROWSER_TEST_F(RealServiceProcessControlBrowserTest,
147 DISABLED_LaunchAndIPC) {
148 LaunchServiceProcessControl();
150 // Make sure we are connected to the service process.
151 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
152 ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
153 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
154 content::RunMessageLoop();
156 // And then shutdown the service process.
157 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
160 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
161 LaunchServiceProcessControl();
163 // Make sure we are connected to the service process.
164 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
165 ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
166 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
167 content::RunMessageLoop();
169 // And then shutdown the service process.
170 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
173 // This tests the case when a service process is launched when the browser
174 // starts but we try to launch it again while setting up Cloud Print.
175 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchTwice) {
176 // Launch the service process the first time.
177 LaunchServiceProcessControl();
179 // Make sure we are connected to the service process.
180 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
181 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
182 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
183 content::RunMessageLoop();
185 // Launch the service process again.
186 LaunchServiceProcessControl();
187 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
188 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
189 base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
190 content::RunMessageLoop();
193 static void DecrementUntilZero(int* count) {
194 (*count)--;
195 if (!(*count))
196 base::ThreadTaskRunnerHandle::Get()->PostTask(
197 FROM_HERE, base::MessageLoop::QuitClosure());
200 // Invoke multiple Launch calls in succession and ensure that all the tasks
201 // get invoked.
202 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
203 MultipleLaunchTasks) {
204 ServiceProcessControl* process = ServiceProcessControl::GetInstance();
205 int launch_count = 5;
206 for (int i = 0; i < launch_count; i++) {
207 // Launch the process asynchronously.
208 process->Launch(base::Bind(&DecrementUntilZero, &launch_count),
209 base::MessageLoop::QuitClosure());
211 // Then run the message loop to keep things running.
212 content::RunMessageLoop();
213 EXPECT_EQ(0, launch_count);
216 // Make sure using the same task for success and failure tasks works.
217 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, SameLaunchTask) {
218 ServiceProcessControl* process = ServiceProcessControl::GetInstance();
219 int launch_count = 5;
220 for (int i = 0; i < launch_count; i++) {
221 // Launch the process asynchronously.
222 base::Closure task = base::Bind(&DecrementUntilZero, &launch_count);
223 process->Launch(task, task);
225 // Then run the message loop to keep things running.
226 content::RunMessageLoop();
227 EXPECT_EQ(0, launch_count);
230 // Tests whether disconnecting from the service IPC causes the service process
231 // to die.
232 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, DieOnDisconnect) {
233 // Launch the service process.
234 LaunchServiceProcessControl();
235 // Make sure we are connected to the service process.
236 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
237 Disconnect();
240 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, ForceShutdown) {
241 // Launch the service process.
242 LaunchServiceProcessControl();
243 // Make sure we are connected to the service process.
244 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
245 base::ProcessId service_pid;
246 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
247 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
248 chrome::VersionInfo version_info;
249 ForceServiceProcessShutdown(version_info.Version(), service_pid);
252 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, CheckPid) {
253 base::ProcessId service_pid;
254 EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
255 // Launch the service process.
256 LaunchServiceProcessControl();
257 EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
258 EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
259 // Disconnect from service process.
260 Disconnect();
263 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsNoService) {
264 ASSERT_FALSE(ServiceProcessControl::GetInstance()->IsConnected());
265 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
266 EXPECT_FALSE(ServiceProcessControl::GetInstance()->GetHistograms(
267 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
268 base::Unretained(this)),
269 base::TimeDelta()));
272 // Histograms disabled on OSX http://crbug.com/406227
273 #if defined(OS_MACOSX)
274 #define MAYBE_HistogramsTimeout DISABLED_HistogramsTimeout
275 #define MAYBE_Histograms DISABLED_Histograms
276 #else
277 #define MAYBE_HistogramsTimeout HistogramsTimeout
278 #define MAYBE_Histograms Histograms
279 #endif
280 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
281 MAYBE_HistogramsTimeout) {
282 LaunchServiceProcessControl();
283 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
284 // Callback should not be called during GetHistograms call.
285 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
286 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
287 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
288 base::Unretained(this)),
289 base::TimeDelta::FromMilliseconds(100)));
290 EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
291 EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
292 content::RunMessageLoop();
295 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_Histograms) {
296 LaunchServiceProcessControl();
297 ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
298 // Callback should not be called during GetHistograms call.
299 EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
300 // Wait for real callback by providing large timeout value.
301 EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
302 base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
303 base::Unretained(this)),
304 base::TimeDelta::FromHours(1)));
305 EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
306 content::RunMessageLoop();