172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/process_singleton.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/types.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <sys/wait.h> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <signal.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <unistd.h> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/eintr_wrapper.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/test/test_timeouts.h" 183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h" 224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/chrome_switches.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/chrome_process_util.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui/ui_test.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ProcessSingletonLinuxTest : public UITest { 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void SetUp() { 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UITest::SetUp(); 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick lock_path_ = user_data_dir().Append(chrome::kSingletonLockFilename); 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick socket_path_ = user_data_dir().Append(chrome::kSingletonSocketFilename); 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cookie_path_ = user_data_dir().Append(chrome::kSingletonCookieFilename); 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void TearDown() { 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UITest::TearDown(); 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Check that the test cleaned up after itself. 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick struct stat statbuf; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool lock_exists = lstat(lock_path_.value().c_str(), &statbuf) == 0; 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(lock_exists); 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (lock_exists) { 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Unlink to prevent failing future tests if the lock still exists. 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(unlink(lock_path_.value().c_str()), 0); 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath lock_path_; 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath socket_path_; 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath cookie_path_; 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessSingleton* CreateProcessSingleton() { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath user_data_dir; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new ProcessSingleton(user_data_dir); 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCommandLine CommandLineForUrl(const std::string& url) { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Hack: mutate the current process's command line so we don't show a dialog. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that this only works if we have no loose values on the command line, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but that's fine for unit tests. In a UI test we disable error dialogs 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // when spawning Chrome, but this test hits the ProcessSingleton directly. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!cmd_line->HasSwitch(switches::kNoProcessSingletonDialog)) 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cmd_line->AppendSwitch(switches::kNoProcessSingletonDialog); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLine new_cmd_line(*cmd_line); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_cmd_line.AppendArg(url); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new_cmd_line; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A helper method to call ProcessSingleton::NotifyOtherProcess(). 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |url| will be added to CommandLine for current process, so that it can be 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sent to browser process by ProcessSingleton::NotifyOtherProcess(). 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessSingleton::NotifyResult NotifyOtherProcess(const std::string& url, 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int timeout_ms) { 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return process_singleton->NotifyOtherProcessWithTimeout( 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLineForUrl(url), timeout_ms / 1000, true); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |url| will be added to CommandLine for current process, so that it can be 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sent to browser process by ProcessSingleton::NotifyOtherProcessOrCreate(). 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& url, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int timeout_ms) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLineForUrl(url), timeout_ms / 1000); 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test if the socket file and symbol link created by ProcessSingletonLinux 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// are valid. When running this test, the ProcessSingleton object is already 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// initiated by UITest. So we just test against this existing object. 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This test is flaky as per http://crbug.com/74554. 106dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenTEST_F(ProcessSingletonLinuxTest, FLAKY_CheckSocketFile) { 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct stat statbuf; 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, lstat(lock_path_.value().c_str(), &statbuf)); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick char buf[PATH_MAX]; 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssize_t len = readlink(lock_path_.value().c_str(), buf, PATH_MAX); 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_GT(len, 0); 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, lstat(socket_path_.value().c_str(), &statbuf)); 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick len = readlink(socket_path_.value().c_str(), buf, PATH_MAX); 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_GT(len, 0); 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath socket_target_path = FilePath(std::string(buf, len)); 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, lstat(socket_target_path.value().c_str(), &statbuf)); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(S_ISSOCK(statbuf.st_mode)); 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick len = readlink(cookie_path_.value().c_str(), buf, PATH_MAX); 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_GT(len, 0); 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string cookie(buf, len); 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath remote_cookie_path = socket_target_path.DirName(). 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Append(chrome::kSingletonCookieFilename); 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_GT(len, 0); 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(cookie, std::string(buf, len)); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The following tests in linux/view does not pass without a window manager, 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// which is true in build/try bots. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See http://crbug.com/30953. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NotifyOtherProcessSuccess FAILS_NotifyOtherProcessSuccess 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NotifyOtherProcessHostChanged FAILS_NotifyOtherProcessHostChanged 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(james.su@gmail.com): port following tests to Windows. 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test success case of NotifyOtherProcess(). 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int original_tab_count = GetTabCount(); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcess(url, TestTimeouts::action_timeout_ms())); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(original_tab_count + 1, GetTabCount()); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(url, GetActiveTabURL().spec()); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test failure case of NotifyOtherProcess(). 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::ProcessId pid = browser_process_id(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_GE(pid, 1); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Block the browser process, then it'll be killed by 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ProcessSingleton::NotifyOtherProcess(). 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kill(pid, SIGSTOP); 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Wait to make sure the browser process is actually stopped. 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It's necessary when running with valgrind. 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_GE(HANDLE_EINTR(waitpid(pid, 0, WUNTRACED)), 0); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROCESS_NONE, 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcess(url, TestTimeouts::action_timeout_ms())); 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Wait for a while to make sure the browser process is actually killed. 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int exit_code = 0; 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(launcher_->WaitForBrowserProcessToQuit( 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestTimeouts::action_max_timeout_ms(), &exit_code)); 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(-1, exit_code); // Expect unclean shutdown. 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we don't kill ourselves by accident if a lockfile with the same pid 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// happens to exist. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(mattm): This doesn't really need to be a uitest. (We don't use the 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// uitest created browser process, but we do use some uitest provided stuff like 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the user_data_dir and the NotifyOtherProcess function in this file, which 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// would have to be duplicated or shared if this test was moved into a 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// unittest.) 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) { 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Replace lockfile with one containing our own pid. 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string symlink_content = StringPrintf( 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "%s%c%u", 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::GetHostName().c_str(), 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch '-', 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::GetCurrentProcId()); 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink(symlink_content.c_str(), lock_path_.value().c_str())); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove socket so that we will not be able to notify the existing browser. 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(socket_path_.value().c_str())); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROCESS_NONE, 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcess(url, TestTimeouts::action_timeout_ms())); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we've gotten to this point without killing ourself, the test succeeded. 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we can still notify a process on the same host even after the 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// hostname changed. 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int original_tab_count = GetTabCount(); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcess(url, TestTimeouts::action_timeout_ms())); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(original_tab_count + 1, GetTabCount()); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(url, GetActiveTabURL().spec()); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we fail when lock says process is on another host and we can't 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notify it over the socket. 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::ProcessId pid = browser_process_id(); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_GE(pid, 1); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Kill the browser process, so that it does not respond on the socket. 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kill(pid, SIGKILL); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Wait for a while to make sure the browser process is actually killed. 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int exit_code = 0; 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(launcher_->WaitForBrowserProcessToQuit( 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestTimeouts::action_max_timeout_ms(), &exit_code)); 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(-1, exit_code); // Expect unclean shutdown. 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcess(url, TestTimeouts::action_timeout_ms())); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, unlink(lock_path_.value().c_str())); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we fail when lock says process is on another host and we can't 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// notify it over the socket. 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_DifferingHost) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::ProcessId pid = browser_process_id(); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_GE(pid, 1); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Kill the browser process, so that it does not respond on the socket. 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kill(pid, SIGKILL); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Wait for a while to make sure the browser process is actually killed. 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int exit_code = 0; 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(launcher_->WaitForBrowserProcessToQuit( 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TestTimeouts::action_max_timeout_ms(), &exit_code)); 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(-1, exit_code); // Expect unclean shutdown. 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url("about:blank"); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout_ms())); 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, unlink(lock_path_.value().c_str())); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that Create fails when another browser is using the profile directory. 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_FALSE(process_singleton->Create()); 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that Create fails when another browser is using the profile directory 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// but with the old socket location. 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) { 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Do some surgery so as to look like the old configuration. 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick char buf[PATH_MAX]; 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ssize_t len = readlink(socket_path_.value().c_str(), buf, sizeof(buf)); 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_GT(len, 0); 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath socket_target_path = FilePath(std::string(buf, len)); 2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, unlink(socket_path_.value().c_str())); 2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, rename(socket_target_path.value().c_str(), 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick socket_path_.value().c_str())); 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(0, unlink(cookie_path_.value().c_str())); 2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_FALSE(process_singleton->Create()); 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test that we fail when lock says process is on another host and we can't 2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// notify it over the socket before of a bad cookie. 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_BadCookie) { 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Change the cookie. 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(cookie_path_.value().c_str())); 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink("INCORRECTCOOKIE", cookie_path_.value().c_str())); 3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Also change the hostname, so the remote does not retry. 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string url("about:blank"); 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout_ms())); 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 310