Index: chrome/browser/process_singleton_posix_unittest.cc |
diff --git a/chrome/browser/process_singleton_linux_unittest.cc b/chrome/browser/process_singleton_posix_unittest.cc |
similarity index 79% |
rename from chrome/browser/process_singleton_linux_unittest.cc |
rename to chrome/browser/process_singleton_posix_unittest.cc |
index 689a2dfaf1e0c0e07d07f8c6dc564c3fa191cccf..fd24ff386128ae128fb88e854b92cb2f673a18b6 100644 |
--- a/chrome/browser/process_singleton_linux_unittest.cc |
+++ b/chrome/browser/process_singleton_posix_unittest.cc |
@@ -4,6 +4,7 @@ |
#include "chrome/browser/process_singleton.h" |
+#include <fcntl.h> |
#include <signal.h> |
#include <sys/types.h> |
#include <sys/wait.h> |
@@ -14,9 +15,11 @@ |
#include "base/bind.h" |
#include "base/command_line.h" |
+#include "base/file_util.h" |
#include "base/files/file_path.h" |
#include "base/files/scoped_temp_dir.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/posix/eintr_wrapper.h" |
#include "base/strings/stringprintf.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/test/test_timeouts.h" |
@@ -31,7 +34,7 @@ using content::BrowserThread; |
namespace { |
-class ProcessSingletonLinuxTest : public testing::Test { |
+class ProcessSingletonPosixTest : public testing::Test { |
public: |
// A ProcessSingleton exposing some protected methods for testing. |
class TestableProcessSingleton : public ProcessSingleton { |
@@ -58,7 +61,7 @@ class ProcessSingletonLinuxTest : public testing::Test { |
} |
}; |
- ProcessSingletonLinuxTest() |
+ ProcessSingletonPosixTest() |
: kill_callbacks_(0), |
io_thread_(BrowserThread::IO), |
wait_event_(true, false), |
@@ -89,7 +92,7 @@ class ProcessSingletonLinuxTest : public testing::Test { |
if (process_singleton_on_thread_) { |
worker_thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&ProcessSingletonLinuxTest::DestructProcessSingleton, |
+ base::Bind(&ProcessSingletonPosixTest::DestructProcessSingleton, |
base::Unretained(this))); |
scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( |
@@ -108,7 +111,7 @@ class ProcessSingletonLinuxTest : public testing::Test { |
worker_thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&ProcessSingletonLinuxTest:: |
+ base::Bind(&ProcessSingletonPosixTest:: |
CreateProcessSingletonInternal, |
base::Unretained(this))); |
@@ -121,6 +124,35 @@ class ProcessSingletonLinuxTest : public testing::Test { |
return new TestableProcessSingleton(temp_dir_.path()); |
} |
+ void VerifyFiles() { |
+ struct stat statbuf; |
+ ASSERT_EQ(0, lstat(lock_path_.value().c_str(), &statbuf)); |
+ ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); |
+ char buf[PATH_MAX]; |
+ ssize_t len = readlink(lock_path_.value().c_str(), buf, PATH_MAX); |
+ ASSERT_GT(len, 0); |
+ |
+ ASSERT_EQ(0, lstat(socket_path_.value().c_str(), &statbuf)); |
+ ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); |
+ |
+ len = readlink(socket_path_.value().c_str(), buf, PATH_MAX); |
+ ASSERT_GT(len, 0); |
+ base::FilePath socket_target_path = base::FilePath(std::string(buf, len)); |
+ |
+ ASSERT_EQ(0, lstat(socket_target_path.value().c_str(), &statbuf)); |
+ ASSERT_TRUE(S_ISSOCK(statbuf.st_mode)); |
+ |
+ len = readlink(cookie_path_.value().c_str(), buf, PATH_MAX); |
+ ASSERT_GT(len, 0); |
+ std::string cookie(buf, len); |
+ |
+ base::FilePath remote_cookie_path = socket_target_path.DirName(). |
+ Append(chrome::kSingletonCookieFilename); |
+ len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); |
+ ASSERT_GT(len, 0); |
+ EXPECT_EQ(cookie, std::string(buf, len)); |
+ } |
+ |
ProcessSingleton::NotifyResult NotifyOtherProcess( |
bool override_kill, |
base::TimeDelta timeout) { |
@@ -132,7 +164,7 @@ class ProcessSingletonLinuxTest : public testing::Test { |
process_singleton->OverrideCurrentPidForTesting( |
base::GetCurrentProcId() + 1); |
process_singleton->OverrideKillCallbackForTesting( |
- base::Bind(&ProcessSingletonLinuxTest::KillCallback, |
+ base::Bind(&ProcessSingletonPosixTest::KillCallback, |
base::Unretained(this))); |
} |
@@ -172,7 +204,7 @@ class ProcessSingletonLinuxTest : public testing::Test { |
void BlockWorkerThread() { |
worker_thread_->message_loop()->PostTask( |
FROM_HERE, |
- base::Bind(&ProcessSingletonLinuxTest::BlockThread, |
+ base::Bind(&ProcessSingletonPosixTest::BlockThread, |
base::Unretained(this))); |
} |
@@ -219,42 +251,17 @@ class ProcessSingletonLinuxTest : public testing::Test { |
} // namespace |
-// Test if the socket file and symbol link created by ProcessSingletonLinux |
+// Test if the socket file and symbol link created by ProcessSingletonPosix |
// are valid. |
// If this test flakes, use http://crbug.com/74554. |
-TEST_F(ProcessSingletonLinuxTest, CheckSocketFile) { |
+TEST_F(ProcessSingletonPosixTest, CheckSocketFile) { |
CreateProcessSingletonOnThread(); |
- struct stat statbuf; |
- ASSERT_EQ(0, lstat(lock_path_.value().c_str(), &statbuf)); |
- ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); |
- char buf[PATH_MAX]; |
- ssize_t len = readlink(lock_path_.value().c_str(), buf, PATH_MAX); |
- ASSERT_GT(len, 0); |
- |
- ASSERT_EQ(0, lstat(socket_path_.value().c_str(), &statbuf)); |
- ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); |
- |
- len = readlink(socket_path_.value().c_str(), buf, PATH_MAX); |
- ASSERT_GT(len, 0); |
- base::FilePath socket_target_path = base::FilePath(std::string(buf, len)); |
- |
- ASSERT_EQ(0, lstat(socket_target_path.value().c_str(), &statbuf)); |
- ASSERT_TRUE(S_ISSOCK(statbuf.st_mode)); |
- |
- len = readlink(cookie_path_.value().c_str(), buf, PATH_MAX); |
- ASSERT_GT(len, 0); |
- std::string cookie(buf, len); |
- |
- base::FilePath remote_cookie_path = socket_target_path.DirName(). |
- Append(chrome::kSingletonCookieFilename); |
- len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); |
- ASSERT_GT(len, 0); |
- EXPECT_EQ(cookie, std::string(buf, len)); |
+ VerifyFiles(); |
} |
// TODO(james.su@gmail.com): port following tests to Windows. |
// Test success case of NotifyOtherProcess(). |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessSuccess) { |
CreateProcessSingletonOnThread(); |
EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, |
NotifyOtherProcess(true, TestTimeouts::action_timeout())); |
@@ -262,7 +269,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { |
} |
// Test failure case of NotifyOtherProcess(). |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessFailure) { |
CreateProcessSingletonOnThread(); |
BlockWorkerThread(); |
@@ -275,7 +282,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { |
// Test that we don't kill ourselves by accident if a lockfile with the same pid |
// happens to exist. |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessNoSuicide) { |
CreateProcessSingletonOnThread(); |
// Replace lockfile with one containing our own pid. |
EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
@@ -296,7 +303,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) { |
// Test that we can still notify a process on the same host even after the |
// hostname changed. |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessHostChanged) { |
CreateProcessSingletonOnThread(); |
EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
@@ -308,7 +315,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { |
// Test that we fail when lock says process is on another host and we can't |
// notify it over the socket. |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessDifferingHost) { |
CreateProcessSingletonOnThread(); |
BlockWorkerThread(); |
@@ -326,7 +333,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { |
// Test that we fail when lock says process is on another host and we can't |
// notify it over the socket. |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_DifferingHost) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessOrCreate_DifferingHost) { |
CreateProcessSingletonOnThread(); |
BlockWorkerThread(); |
@@ -344,7 +351,7 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_DifferingHost) { |
} |
// Test that Create fails when another browser is using the profile directory. |
-TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { |
+TEST_F(ProcessSingletonPosixTest, CreateFailsWithExistingBrowser) { |
CreateProcessSingletonOnThread(); |
scoped_ptr<TestableProcessSingleton> process_singleton( |
@@ -355,7 +362,7 @@ TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { |
// Test that Create fails when another browser is using the profile directory |
// but with the old socket location. |
-TEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) { |
+TEST_F(ProcessSingletonPosixTest, CreateChecksCompatibilitySocket) { |
CreateProcessSingletonOnThread(); |
scoped_ptr<TestableProcessSingleton> process_singleton( |
CreateProcessSingleton()); |
@@ -376,7 +383,7 @@ TEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) { |
// Test that we fail when lock says process is on another host and we can't |
// notify it over the socket before of a bad cookie. |
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_BadCookie) { |
+TEST_F(ProcessSingletonPosixTest, NotifyOtherProcessOrCreate_BadCookie) { |
CreateProcessSingletonOnThread(); |
// Change the cookie. |
EXPECT_EQ(0, unlink(cookie_path_.value().c_str())); |
@@ -391,3 +398,29 @@ TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_BadCookie) { |
NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout())); |
} |
+#if defined(OS_MACOSX) |
+// Test that if there is an existing lock file, and we could not flock() |
+// it, then exit. |
+TEST_F(ProcessSingletonPosixTest, CreateRespectsOldMacLock) { |
+ scoped_ptr<TestableProcessSingleton> process_singleton( |
+ CreateProcessSingleton()); |
+ base::ScopedFD lock_fd(HANDLE_EINTR( |
+ open(lock_path_.value().c_str(), O_RDWR | O_CREAT | O_EXLOCK, 0644))); |
+ ASSERT_TRUE(lock_fd.is_valid()); |
+ EXPECT_FALSE(process_singleton->Create()); |
+ base::File::Info info; |
+ EXPECT_TRUE(base::GetFileInfo(lock_path_, &info)); |
+ EXPECT_FALSE(info.is_directory); |
+ EXPECT_FALSE(info.is_symbolic_link); |
+} |
+ |
+// Test that if there is an existing lock file, and it's not locked, we replace |
+// it. |
+TEST_F(ProcessSingletonPosixTest, CreateReplacesOldMacLock) { |
+ scoped_ptr<TestableProcessSingleton> process_singleton( |
+ CreateProcessSingleton()); |
+ EXPECT_EQ(0, base::WriteFile(lock_path_, "", 0)); |
+ EXPECT_TRUE(process_singleton->Create()); |
+ VerifyFiles(); |
+} |
+#endif // defined(OS_MACOSX) |