service_process_util_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be
3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file.
4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/basictypes.h"
6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if !defined(OS_MACOSX)
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(dmaclach): Figure out tests that will work with launchd on Mac OS.
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/at_exit.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/command_line.h"
12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/process_util.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/scoped_ptr.h"
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/string_util.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/test/multiprocess_test.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/test/test_timeouts.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/utf_string_conversions.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/chrome_switches.h"
20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/chrome_version_info.h"
21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/service_process_util.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "testing/multiprocess_func_list.h"
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN)
25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/win/win_util.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_LINUX)
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <glib.h>
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/auto_start_linux.h"
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace {
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool g_good_shutdown = false;
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ShutdownTask(MessageLoop* loop) {
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Quit the main message loop.
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_FALSE(g_good_shutdown);
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  g_good_shutdown = true;
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  loop->PostTask(FROM_HERE, new MessageLoop::QuitTask());
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}  // namespace
45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
46731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST(ServiceProcessUtilTest, ScopedVersionedName) {
47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string test_str = "test";
48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string scoped_name = GetServiceProcessScopedVersionedName(test_str);
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  chrome::VersionInfo version_info;
50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(version_info.is_valid());
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(EndsWith(scoped_name, test_str, true));
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_NE(std::string::npos, scoped_name.find(version_info.Version()));
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass ServiceProcessStateTest : public base::MultiProcessTest {
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ServiceProcessStateTest();
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ~ServiceProcessStateTest();
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void SetUp();
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::MessageLoopProxy* IOMessageLoopProxy() {
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return io_thread_.message_loop_proxy();
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void LaunchAndWait(const std::string& name);
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // This is used to release the ServiceProcessState singleton after each test.
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::ShadowingAtExitManager at_exit_manager_;
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Thread io_thread_;
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenServiceProcessStateTest::ServiceProcessStateTest()
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : io_thread_("ServiceProcessStateTestThread") {
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenServiceProcessStateTest::~ServiceProcessStateTest() {
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ServiceProcessStateTest::SetUp() {
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Thread::Options options(MessageLoop::TYPE_IO, 0);
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(io_thread_.StartWithOptions(options));
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ServiceProcessStateTest::LaunchAndWait(const std::string& name) {
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ProcessHandle handle = SpawnChild(name, false);
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(handle);
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int exit_code = 0;
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(base::WaitForExitCode(handle, &exit_code));
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(exit_code, 0);
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ServiceProcessStateTest, Singleton) {
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(state->Initialize());
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LaunchAndWait("ServiceProcessStateTestSingleton");
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ServiceProcessStateTest, ReadyState) {
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_FALSE(CheckServiceProcessReady());
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(state->Initialize());
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(state->SignalReady(IOMessageLoopProxy(), NULL));
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LaunchAndWait("ServiceProcessStateTestReadyTrue");
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  state->SignalStopped();
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LaunchAndWait("ServiceProcessStateTestReadyFalse");
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
107dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ServiceProcessStateTest, AutoRun) {
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(state->AddToAutoRun());
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  scoped_ptr<CommandLine> autorun_command_line;
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN)
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string value_name = GetServiceProcessScopedName("_service_run");
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  string16 value;
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(base::win::ReadCommandFromAutoRun(HKEY_CURRENT_USER,
115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                UTF8ToWide(value_name),
116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                &value));
117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  autorun_command_line.reset(new CommandLine(CommandLine::FromString(value)));
118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_LINUX)
119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(GOOGLE_CHROME_BUILD)
120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string base_desktop_name = "google-chrome-service.desktop";
121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else  // CHROMIUM_BUILD
122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string base_desktop_name = "chromium-service.desktop";
123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string exec_value;
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(AutoStart::GetAutostartFileValue(
126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      GetServiceProcessScopedName(base_desktop_name), "Exec", &exec_value));
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  GError *error = NULL;
128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gchar **argv = NULL;
129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  gint argc = NULL;
130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (g_shell_parse_argv(exec_value.c_str(), &argc, &argv, &error)) {
131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    autorun_command_line.reset(new CommandLine(argc, argv));
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    g_strfreev(argv);
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ADD_FAILURE();
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    g_error_free(error);
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(OS_WIN)
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (autorun_command_line.get()) {
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(autorun_command_line->GetSwitchValueASCII(switches::kProcessType),
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              std::string(switches::kServiceProcess));
141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(state->RemoveFromAutoRun());
143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_WIN)
144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(base::win::ReadCommandFromAutoRun(HKEY_CURRENT_USER,
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                 UTF8ToWide(value_name),
146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                                 &value));
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#elif defined(OS_LINUX)
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(AutoStart::GetAutostartFileValue(
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      GetServiceProcessScopedName(base_desktop_name), "Exec", &exec_value));
150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // defined(OS_WIN)
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ServiceProcessStateTest, SharedMem) {
15472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string version;
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ProcessId pid;
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN)
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // On Posix, named shared memory uses a file on disk. This file
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // could be lying around from previous crashes which could cause
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // GetServiceProcessPid to lie. On Windows, we use a named event so we
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // don't have this issue. Until we have a more stable shared memory
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // implementation on Posix, this check will only execute on Windows.
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_FALSE(GetServiceProcessData(&version, &pid));
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif  // defined(OS_WIN)
16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(state->Initialize());
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(GetServiceProcessData(&version, &pid));
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(base::GetCurrentProcId(), pid);
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(ServiceProcessStateTest, ForceShutdown) {
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ProcessHandle handle = SpawnChild("ServiceProcessStateTestShutdown",
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                          true);
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(handle);
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (int i = 0; !CheckServiceProcessReady() && i < 10; ++i) {
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout_ms());
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(CheckServiceProcessReady());
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string version;
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::ProcessId pid;
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ASSERT_TRUE(GetServiceProcessData(&version, &pid));
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(ForceServiceProcessShutdown(version, pid));
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int exit_code = 0;
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(base::WaitForExitCodeWithTimeout(handle,
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      &exit_code, TestTimeouts::action_timeout_ms() * 2));
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(exit_code, 0);
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMULTIPROCESS_TEST_MAIN(ServiceProcessStateTestSingleton) {
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(state->Initialize());
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return 0;
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMULTIPROCESS_TEST_MAIN(ServiceProcessStateTestReadyTrue) {
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(CheckServiceProcessReady());
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return 0;
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMULTIPROCESS_TEST_MAIN(ServiceProcessStateTestReadyFalse) {
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(CheckServiceProcessReady());
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return 0;
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMULTIPROCESS_TEST_MAIN(ServiceProcessStateTestShutdown) {
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MessageLoop message_loop;
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message_loop.set_thread_name("ServiceProcessStateTestShutdownMainThread");
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Thread io_thread_("ServiceProcessStateTestShutdownIOThread");
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::Thread::Options options(MessageLoop::TYPE_IO, 0);
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(io_thread_.StartWithOptions(options));
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ServiceProcessState* state = ServiceProcessState::GetInstance();
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_TRUE(state->Initialize());
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(state->SignalReady(io_thread_.message_loop_proxy(),
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 NewRunnableFunction(&ShutdownTask,
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                     MessageLoop::current())));
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message_loop.PostDelayedTask(FROM_HERE,
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               new MessageLoop::QuitTask(),
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               TestTimeouts::action_max_timeout_ms());
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(g_good_shutdown);
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message_loop.Run();
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(g_good_shutdown);
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return 0;
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // !OS_MACOSX
225