Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / service_process / service_process_control_browsertest.cc
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.
4
5 #include "chrome/browser/service_process/service_process_control.h"
6
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 "content/public/common/content_paths.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/test_utils.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24
25 class ServiceProcessControlBrowserTest
26     : public InProcessBrowserTest {
27  public:
28   ServiceProcessControlBrowserTest()
29       : service_process_handle_(base::kNullProcessHandle) {
30   }
31   virtual ~ServiceProcessControlBrowserTest() {
32     base::CloseProcessHandle(service_process_handle_);
33     service_process_handle_ = base::kNullProcessHandle;
34   }
35
36   void HistogramsCallback() {
37     MockHistogramsCallback();
38     QuitMessageLoop();
39   }
40
41   MOCK_METHOD0(MockHistogramsCallback, void());
42
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));
52
53     // Then run the message loop to keep things running.
54     content::RunMessageLoop();
55   }
56
57   static void QuitMessageLoop() {
58     base::MessageLoop::current()->Quit();
59   }
60
61   static void CloudPrintInfoCallback(
62       const cloud_print::CloudPrintProxyInfo& proxy_info) {
63     QuitMessageLoop();
64   }
65
66   void Disconnect() {
67     // This will close the IPC connection.
68     ServiceProcessControl::GetInstance()->Disconnect();
69   }
70
71   virtual void SetUp() override {
72     service_process_handle_ = base::kNullProcessHandle;
73   }
74
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;
87     }
88   }
89
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());
105   }
106
107   void ProcessControlLaunchFailed() {
108     ADD_FAILURE();
109     // Quit the current message.
110     base::MessageLoop::current()->PostTask(FROM_HERE,
111                                            base::MessageLoop::QuitClosure());
112   }
113
114  private:
115   base::ProcessHandle service_process_handle_;
116 };
117
118 class RealServiceProcessControlBrowserTest
119       : public ServiceProcessControlBrowserTest {
120  public:
121   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);
132   }
133 };
134
135 // TODO(vitalybuka): Fix crbug.com/340563
136 IN_PROC_BROWSER_TEST_F(RealServiceProcessControlBrowserTest,
137                        DISABLED_LaunchAndIPC) {
138   LaunchServiceProcessControl();
139
140   // Make sure we are connected to the service process.
141   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
142   ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
143         base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
144   content::RunMessageLoop();
145
146   // And then shutdown the service process.
147   EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
148 }
149
150 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchAndIPC) {
151   LaunchServiceProcessControl();
152
153   // Make sure we are connected to the service process.
154   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
155   ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
156         base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback));
157   content::RunMessageLoop();
158
159   // And then shutdown the service process.
160   EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
161 }
162
163 // This tests the case when a service process is launched when the browser
164 // starts but we try to launch it again while setting up Cloud Print.
165 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, LaunchTwice) {
166   // Launch the service process the first time.
167   LaunchServiceProcessControl();
168
169   // Make sure we are connected to the service process.
170   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
171   EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
172         base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
173   content::RunMessageLoop();
174
175   // Launch the service process again.
176   LaunchServiceProcessControl();
177   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
178   EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetCloudPrintProxyInfo(
179         base::Bind(&ServiceProcessControlBrowserTest::CloudPrintInfoCallback)));
180   content::RunMessageLoop();
181 }
182
183 static void DecrementUntilZero(int* count) {
184   (*count)--;
185   if (!(*count))
186     base::MessageLoop::current()->PostTask(FROM_HERE,
187                                            base::MessageLoop::QuitClosure());
188 }
189
190 // Invoke multiple Launch calls in succession and ensure that all the tasks
191 // get invoked.
192 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
193                        MultipleLaunchTasks) {
194   ServiceProcessControl* process = ServiceProcessControl::GetInstance();
195   int launch_count = 5;
196   for (int i = 0; i < launch_count; i++) {
197     // Launch the process asynchronously.
198     process->Launch(base::Bind(&DecrementUntilZero, &launch_count),
199                     base::MessageLoop::QuitClosure());
200   }
201   // Then run the message loop to keep things running.
202   content::RunMessageLoop();
203   EXPECT_EQ(0, launch_count);
204 }
205
206 // Make sure using the same task for success and failure tasks works.
207 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, SameLaunchTask) {
208   ServiceProcessControl* process = ServiceProcessControl::GetInstance();
209   int launch_count = 5;
210   for (int i = 0; i < launch_count; i++) {
211     // Launch the process asynchronously.
212     base::Closure task = base::Bind(&DecrementUntilZero, &launch_count);
213     process->Launch(task, task);
214   }
215   // Then run the message loop to keep things running.
216   content::RunMessageLoop();
217   EXPECT_EQ(0, launch_count);
218 }
219
220 // Tests whether disconnecting from the service IPC causes the service process
221 // to die.
222 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, DieOnDisconnect) {
223   // Launch the service process.
224   LaunchServiceProcessControl();
225   // Make sure we are connected to the service process.
226   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
227   Disconnect();
228 }
229
230 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, ForceShutdown) {
231   // Launch the service process.
232   LaunchServiceProcessControl();
233   // Make sure we are connected to the service process.
234   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
235   base::ProcessId service_pid;
236   EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
237   EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
238   chrome::VersionInfo version_info;
239   ForceServiceProcessShutdown(version_info.Version(), service_pid);
240 }
241
242 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, CheckPid) {
243   base::ProcessId service_pid;
244   EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
245   // Launch the service process.
246   LaunchServiceProcessControl();
247   EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
248   EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
249   // Disconnect from service process.
250   Disconnect();
251 }
252
253 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsNoService) {
254   ASSERT_FALSE(ServiceProcessControl::GetInstance()->IsConnected());
255   EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
256   EXPECT_FALSE(ServiceProcessControl::GetInstance()->GetHistograms(
257       base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
258                  base::Unretained(this)),
259       base::TimeDelta()));
260 }
261
262 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, HistogramsTimeout) {
263   LaunchServiceProcessControl();
264   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
265   // Callback should not be called during GetHistograms call.
266   EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
267   EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
268       base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
269                  base::Unretained(this)),
270       base::TimeDelta::FromMilliseconds(100)));
271   EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
272   EXPECT_TRUE(ServiceProcessControl::GetInstance()->Shutdown());
273   content::RunMessageLoop();
274 }
275
276 IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, Histograms) {
277   LaunchServiceProcessControl();
278   ASSERT_TRUE(ServiceProcessControl::GetInstance()->IsConnected());
279   // Callback should not be called during GetHistograms call.
280   EXPECT_CALL(*this, MockHistogramsCallback()).Times(0);
281   // Wait for real callback by providing large timeout value.
282   EXPECT_TRUE(ServiceProcessControl::GetInstance()->GetHistograms(
283       base::Bind(&ServiceProcessControlBrowserTest::HistogramsCallback,
284                 base::Unretained(this)),
285       base::TimeDelta::FromHours(1)));
286   EXPECT_CALL(*this, MockHistogramsCallback()).Times(1);
287   content::RunMessageLoop();
288 }