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