15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/service_process_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/kill.h"
12a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/launch.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_split.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/multiprocess_test.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/multiprocess_func_list.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/auto_start_linux.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test fails http://crbug.com/84854, and is very flaky on CrOS and
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// somewhat flaky on other Linux.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ForceShutdown DISABLED_ForceShutdown
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_WIN)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ForceShutdown DISABLED_ForceShutdown
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ForceShutdown ForceShutdown
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_good_shutdown = false;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void ShutdownTask(base::MessageLoop* loop) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Quit the main message loop.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(g_good_shutdown);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_good_shutdown = true;
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ServiceProcessUtilTest, ScopedVersionedName) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string test_str = "test";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scoped_name = GetServiceProcessScopedVersionedName(test_str);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::VersionInfo version_info;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(version_info.is_valid());
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(EndsWith(scoped_name, test_str, true));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(std::string::npos, scoped_name.find(version_info.Version()));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServiceProcessStateTest : public base::MultiProcessTest {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessStateTest();
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ServiceProcessStateTest();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::MessageLoopProxy* IOMessageLoopProxy() {
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return io_thread_.message_loop_proxy().get();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LaunchAndWait(const std::string& name);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is used to release the ServiceProcessState singleton after each test.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ShadowingAtExitManager at_exit_manager_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread io_thread_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceProcessStateTest::ServiceProcessStateTest()
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : io_thread_("ServiceProcessStateTestThread") {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceProcessStateTest::~ServiceProcessStateTest() {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceProcessStateTest::SetUp() {
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(io_thread_.StartWithOptions(options));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceProcessStateTest::LaunchAndWait(const std::string& name) {
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ProcessHandle handle = SpawnChild(name);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int exit_code = 0;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(base::WaitForExitCode(handle, &exit_code));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(exit_code, 0);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateTest, Singleton) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.Initialize());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LaunchAndWait("ServiceProcessStateTestSingleton");
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// http://crbug.com/396390
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ServiceProcessStateTest, DISABLED_ReadyState) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CheckServiceProcessReady());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.Initialize());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.SignalReady(IOMessageLoopProxy(), base::Closure()));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LaunchAndWait("ServiceProcessStateTestReadyTrue");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state.SignalStopped();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LaunchAndWait("ServiceProcessStateTestReadyFalse");
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateTest, AutoRun) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.AddToAutoRun());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CommandLine> autorun_command_line;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string value_name = GetServiceProcessScopedName("_service_run");
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 value;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(base::win::ReadCommandFromAutoRun(HKEY_CURRENT_USER,
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                base::UTF8ToWide(value_name),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                &value));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  autorun_command_line.reset(new CommandLine(CommandLine::FromString(value)));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_MACOSX)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string base_desktop_name = "google-chrome-service.desktop";
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // CHROMIUM_BUILD
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string base_desktop_name = "chromium-service.desktop";
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string exec_value;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(AutoStart::GetAutostartFileValue(
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetServiceProcessScopedName(base_desktop_name), "Exec", &exec_value));
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Make sure |exec_value| doesn't contain strings a shell would
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // treat specially.
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(std::string::npos, exec_value.find('#'));
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(std::string::npos, exec_value.find('\n'));
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(std::string::npos, exec_value.find('"'));
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(std::string::npos, exec_value.find('\''));
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CommandLine::StringVector argv;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::SplitString(exec_value, ' ', &argv);
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_GE(argv.size(), 2U)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      << "Expected at least one command-line option in: " << exec_value;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  autorun_command_line.reset(new CommandLine(argv));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (autorun_command_line.get()) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(autorun_command_line->GetSwitchValueASCII(switches::kProcessType),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              std::string(switches::kServiceProcess));
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.RemoveFromAutoRun());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(base::win::ReadCommandFromAutoRun(HKEY_CURRENT_USER,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 base::UTF8ToWide(value_name),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 &value));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_MACOSX)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(AutoStart::GetAutostartFileValue(
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetServiceProcessScopedName(base_desktop_name), "Exec", &exec_value));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// http://crbug.com/396390
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ServiceProcessStateTest, DISABLED_SharedMem) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string version;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessId pid;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // On Posix, named shared memory uses a file on disk. This file
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // could be lying around from previous crashes which could cause
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetServiceProcessPid to lie. On Windows, we use a named event so we
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // don't have this issue. Until we have a more stable shared memory
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implementation on Posix, this check will only execute on Windows.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(GetServiceProcessData(&version, &pid));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_WIN)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(state.Initialize());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(GetServiceProcessData(&version, &pid));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(base::GetCurrentProcId(), pid);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateTest, MAYBE_ForceShutdown) {
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ProcessHandle handle = SpawnChild("ServiceProcessStateTestShutdown");
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(handle);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; !CheckServiceProcessReady() && i < 10; ++i) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(CheckServiceProcessReady());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string version;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessId pid;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(GetServiceProcessData(&version, &pid));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ForceServiceProcessShutdown(version, pid));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int exit_code = 0;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(base::WaitForExitCodeWithTimeout(handle,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &exit_code, TestTimeouts::action_max_timeout()));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::CloseProcessHandle(handle);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(exit_code, 0);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MULTIPROCESS_TEST_MAIN(ServiceProcessStateTestSingleton) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(state.Initialize());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MULTIPROCESS_TEST_MAIN(ServiceProcessStateTestReadyTrue) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckServiceProcessReady());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MULTIPROCESS_TEST_MAIN(ServiceProcessStateTestReadyFalse) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckServiceProcessReady());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MULTIPROCESS_TEST_MAIN(ServiceProcessStateTestShutdown) {
224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop message_loop;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop.set_thread_name("ServiceProcessStateTestShutdownMainThread");
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread io_thread_("ServiceProcessStateTestShutdownIOThread");
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(io_thread_.StartWithOptions(options));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState state;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(state.Initialize());
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(state.SignalReady(
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      io_thread_.message_loop_proxy().get(),
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::Bind(&ShutdownTask, base::MessageLoop::current())));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop.PostDelayedTask(FROM_HERE,
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                               base::MessageLoop::QuitClosure(),
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               TestTimeouts::action_max_timeout());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(g_good_shutdown);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop.Run();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(g_good_shutdown);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // !OS_MACOSX
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreFoundation/CoreFoundation.h>
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h"
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/mac/launchd.h"
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/mac/mock_launchd.h"
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServiceProcessStateFileManipulationTest : public ::testing::Test {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessStateFileManipulationTest()
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : io_thread_("ServiceProcessStateFileManipulationTest_IO") {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ServiceProcessStateFileManipulationTest() { }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Thread::Options options;
266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    options.message_loop_type = base::MessageLoop::TYPE_IO;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(io_thread_.StartWithOptions(options));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(MockLaunchd::MakeABundle(GetTempDirPath(),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Test",
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &bundle_path_,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &executable_path_));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_launchd_.reset(new MockLaunchd(executable_path_, &loop_,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        false, false));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_launchd_instance_.reset(
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new Launchd::ScopedInstance(mock_launchd_.get()));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(service_process_state_.Initialize());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(service_process_state_.SignalReady(
2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        io_thread_.message_loop_proxy().get(), base::Closure()));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    loop_.PostDelayedTask(FROM_HERE,
281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                          base::MessageLoop::QuitClosure(),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          TestTimeouts::action_max_timeout());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockLaunchd* mock_launchd() const { return mock_launchd_.get(); }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath& executable_path() const { return executable_path_; }
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath& bundle_path() const { return bundle_path_; }
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath& GetTempDirPath() const { return temp_dir_.path(); }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::MessageLoopProxy* GetIOMessageLoopProxy() {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return io_thread_.message_loop_proxy().get();
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Run() { loop_.Run(); }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
297a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoopForUI loop_;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Thread io_thread_;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath executable_path_, bundle_path_;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockLaunchd> mock_launchd_;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Launchd::ScopedInstance> scoped_launchd_instance_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceProcessState service_process_state_;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DeleteFunc(const base::FilePath& file) {
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(base::DeleteFile(file, true));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MoveFunc(const base::FilePath& from, const base::FilePath& to) {
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(base::Move(from, to));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChangeAttr(const base::FilePath& from, int mode) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(chmod(from.value().c_str(), mode), 0);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedAttributesRestorer {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedAttributesRestorer(const base::FilePath& path, int mode)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : path_(path), mode_(mode) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedAttributesRestorer() {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChangeAttr(path_, mode_);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path_;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mode_;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TrashFunc(const base::FilePath& src) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FSRef path_ref;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FSRef new_path_ref;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(base::mac::FSRefFromPath(src.value(), &path_ref));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OSStatus status = FSMoveObjectToTrashSync(&path_ref,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            &new_path_ref,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            kFSFileOperationDefaultOptions);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(status, noErr) << "FSMoveObjectToTrashSync " << status;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, VerifyLaunchD) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There have been problems where launchd has gotten into a bad state, usually
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because something had deleted all the files in /tmp. launchd depends on
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a Unix Domain Socket that it creates at /tmp/launchd*/sock.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The symptom of this problem is that the service process connect fails
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on Mac and "launch_msg(): Socket is not connected" appears.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test is designed to make sure that launchd is working.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://crbug/75518
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note: This particular problem no longer affects launchd in 10.10+, since
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // there is no user owned launchd process and sockets are no longer made at
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // /tmp/launchd*/sock. This test is still useful as a sanity check to make
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // sure that launchd appears to be working.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cl(base::FilePath("/bin/launchctl"));
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cl.AppendArg("limit");
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string output;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int exit_code = -1;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(base::GetAppOutputWithExitCode(cl, &output, &exit_code)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              && exit_code == 0)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " exit_code:" << exit_code << " " << output;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, DeleteFile) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeleteFunc, executable_path()));
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->remove_called());
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->delete_called());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, DeleteBundle) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&DeleteFunc, bundle_path()));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->remove_called());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->delete_called());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, MoveBundle) {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_loc = GetTempDirPath().AppendASCII("MoveBundle");
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MoveFunc, bundle_path(), new_loc));
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->restart_called());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->write_called());
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, MoveFile) {
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath new_loc = GetTempDirPath().AppendASCII("MoveFile");
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MoveFunc, executable_path(), new_loc));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->remove_called());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->delete_called());
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, TrashBundle) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FSRef bundle_ref;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(base::mac::FSRefFromPath(bundle_path().value(), &bundle_ref));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TrashFunc, bundle_path()));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->remove_called());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->delete_called());
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string path(base::mac::PathFromFSRef(bundle_ref));
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath file_path(path);
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DeleteFile(file_path, true));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ServiceProcessStateFileManipulationTest, ChangeAttr) {
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedAttributesRestorer restorer(bundle_path(), 0777);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIOMessageLoopProxy()->PostTask(
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&ChangeAttr, bundle_path(), 0222));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Run();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->remove_called());
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(mock_launchd()->delete_called());
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !OS_MACOSX
426