Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1112)

Unified Diff: chrome/browser/process_singleton_linux_unittest.cc

Issue 218883008: Use process_singleton_linux on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CreateUniqueTempDir is fine. DCHECK socket path length. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/process_singleton_linux_unittest.cc
diff --git a/chrome/browser/process_singleton_linux_unittest.cc b/chrome/browser/process_singleton_linux_unittest.cc
deleted file mode 100644
index 689a2dfaf1e0c0e07d07f8c6dc564c3fa191cccf..0000000000000000000000000000000000000000
--- a/chrome/browser/process_singleton_linux_unittest.cc
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/process_singleton.h"
-
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/test_timeouts.h"
-#include "base/test/thread_test_helper.h"
-#include "base/threading/thread.h"
-#include "chrome/common/chrome_constants.h"
-#include "content/public/test/test_browser_thread.h"
-#include "net/base/net_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using content::BrowserThread;
-
-namespace {
-
-class ProcessSingletonLinuxTest : public testing::Test {
- public:
- // A ProcessSingleton exposing some protected methods for testing.
- class TestableProcessSingleton : public ProcessSingleton {
- public:
- explicit TestableProcessSingleton(const base::FilePath& user_data_dir)
- : ProcessSingleton(
- user_data_dir,
- base::Bind(&TestableProcessSingleton::NotificationCallback,
- base::Unretained(this))) {}
-
-
- std::vector<CommandLine::StringVector> callback_command_lines_;
-
- using ProcessSingleton::NotifyOtherProcessWithTimeout;
- using ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate;
- using ProcessSingleton::OverrideCurrentPidForTesting;
- using ProcessSingleton::OverrideKillCallbackForTesting;
-
- private:
- bool NotificationCallback(const CommandLine& command_line,
- const base::FilePath& current_directory) {
- callback_command_lines_.push_back(command_line.argv());
- return true;
- }
- };
-
- ProcessSingletonLinuxTest()
- : kill_callbacks_(0),
- io_thread_(BrowserThread::IO),
- wait_event_(true, false),
- signal_event_(true, false),
- process_singleton_on_thread_(NULL) {
- io_thread_.StartIOThread();
- }
-
- virtual void SetUp() {
- testing::Test::SetUp();
-
- ProcessSingleton::DisablePromptForTesting();
- // Put the lock in a temporary directory. Doesn't need to be a
- // full profile to test this code.
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- lock_path_ = temp_dir_.path().Append(chrome::kSingletonLockFilename);
- socket_path_ = temp_dir_.path().Append(chrome::kSingletonSocketFilename);
- cookie_path_ = temp_dir_.path().Append(chrome::kSingletonCookieFilename);
- }
-
- virtual void TearDown() {
- scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper(
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get()));
- ASSERT_TRUE(io_helper->Run());
-
- // Destruct the ProcessSingleton object before the IO thread so that its
- // internals are destructed properly.
- if (process_singleton_on_thread_) {
- worker_thread_->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&ProcessSingletonLinuxTest::DestructProcessSingleton,
- base::Unretained(this)));
-
- scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper(
- worker_thread_->message_loop_proxy().get()));
- ASSERT_TRUE(helper->Run());
- }
-
- io_thread_.Stop();
- testing::Test::TearDown();
- }
-
- void CreateProcessSingletonOnThread() {
- ASSERT_EQ(NULL, worker_thread_.get());
- worker_thread_.reset(new base::Thread("BlockingThread"));
- worker_thread_->Start();
-
- worker_thread_->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&ProcessSingletonLinuxTest::
- CreateProcessSingletonInternal,
- base::Unretained(this)));
-
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(worker_thread_->message_loop_proxy().get()));
- ASSERT_TRUE(helper->Run());
- }
-
- TestableProcessSingleton* CreateProcessSingleton() {
- return new TestableProcessSingleton(temp_dir_.path());
- }
-
- ProcessSingleton::NotifyResult NotifyOtherProcess(
- bool override_kill,
- base::TimeDelta timeout) {
- scoped_ptr<TestableProcessSingleton> process_singleton(
- CreateProcessSingleton());
- CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram());
- command_line.AppendArg("about:blank");
- if (override_kill) {
- process_singleton->OverrideCurrentPidForTesting(
- base::GetCurrentProcId() + 1);
- process_singleton->OverrideKillCallbackForTesting(
- base::Bind(&ProcessSingletonLinuxTest::KillCallback,
- base::Unretained(this)));
- }
-
- return process_singleton->NotifyOtherProcessWithTimeout(
- command_line, timeout.InSeconds(), true);
- }
-
- // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate().
- ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate(
- const std::string& url,
- base::TimeDelta timeout) {
- scoped_ptr<TestableProcessSingleton> process_singleton(
- CreateProcessSingleton());
- CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram());
- command_line.AppendArg(url);
- return process_singleton->NotifyOtherProcessWithTimeoutOrCreate(
- command_line, timeout.InSeconds());
- }
-
- void CheckNotified() {
- ASSERT_TRUE(process_singleton_on_thread_ != NULL);
- ASSERT_EQ(1u, process_singleton_on_thread_->callback_command_lines_.size());
- bool found = false;
- for (size_t i = 0;
- i < process_singleton_on_thread_->callback_command_lines_[0].size();
- ++i) {
- if (process_singleton_on_thread_->callback_command_lines_[0][i] ==
- "about:blank") {
- found = true;
- break;
- }
- }
- ASSERT_TRUE(found);
- ASSERT_EQ(0, kill_callbacks_);
- }
-
- void BlockWorkerThread() {
- worker_thread_->message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&ProcessSingletonLinuxTest::BlockThread,
- base::Unretained(this)));
- }
-
- void UnblockWorkerThread() {
- wait_event_.Signal(); // Unblock the worker thread for shutdown.
- signal_event_.Wait(); // Ensure thread unblocks before continuing.
- }
-
- void BlockThread() {
- wait_event_.Wait();
- signal_event_.Signal();
- }
-
- base::FilePath lock_path_;
- base::FilePath socket_path_;
- base::FilePath cookie_path_;
- int kill_callbacks_;
-
- private:
- void CreateProcessSingletonInternal() {
- ASSERT_TRUE(!process_singleton_on_thread_);
- process_singleton_on_thread_ = CreateProcessSingleton();
- ASSERT_EQ(ProcessSingleton::PROCESS_NONE,
- process_singleton_on_thread_->NotifyOtherProcessOrCreate());
- }
-
- void DestructProcessSingleton() {
- ASSERT_TRUE(process_singleton_on_thread_);
- delete process_singleton_on_thread_;
- }
-
- void KillCallback(int pid) {
- kill_callbacks_++;
- }
-
- content::TestBrowserThread io_thread_;
- base::ScopedTempDir temp_dir_;
- base::WaitableEvent wait_event_;
- base::WaitableEvent signal_event_;
-
- scoped_ptr<base::Thread> worker_thread_;
- TestableProcessSingleton* process_singleton_on_thread_;
-};
-
-} // namespace
-
-// Test if the socket file and symbol link created by ProcessSingletonLinux
-// are valid.
-// If this test flakes, use http://crbug.com/74554.
-TEST_F(ProcessSingletonLinuxTest, 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));
-}
-
-// TODO(james.su@gmail.com): port following tests to Windows.
-// Test success case of NotifyOtherProcess().
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) {
- CreateProcessSingletonOnThread();
- EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED,
- NotifyOtherProcess(true, TestTimeouts::action_timeout()));
- CheckNotified();
-}
-
-// Test failure case of NotifyOtherProcess().
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) {
- CreateProcessSingletonOnThread();
-
- BlockWorkerThread();
- EXPECT_EQ(ProcessSingleton::PROCESS_NONE,
- NotifyOtherProcess(true, TestTimeouts::action_timeout()));
-
- ASSERT_EQ(1, kill_callbacks_);
- UnblockWorkerThread();
-}
-
-// Test that we don't kill ourselves by accident if a lockfile with the same pid
-// happens to exist.
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) {
- CreateProcessSingletonOnThread();
- // Replace lockfile with one containing our own pid.
- EXPECT_EQ(0, unlink(lock_path_.value().c_str()));
- std::string symlink_content = base::StringPrintf(
- "%s%c%u",
- net::GetHostName().c_str(),
- '-',
- base::GetCurrentProcId());
- EXPECT_EQ(0, symlink(symlink_content.c_str(), lock_path_.value().c_str()));
-
- // Remove socket so that we will not be able to notify the existing browser.
- EXPECT_EQ(0, unlink(socket_path_.value().c_str()));
-
- EXPECT_EQ(ProcessSingleton::PROCESS_NONE,
- NotifyOtherProcess(false, TestTimeouts::action_timeout()));
- // If we've gotten to this point without killing ourself, the test succeeded.
-}
-
-// Test that we can still notify a process on the same host even after the
-// hostname changed.
-TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) {
- CreateProcessSingletonOnThread();
- EXPECT_EQ(0, unlink(lock_path_.value().c_str()));
- EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str()));
-
- EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED,
- NotifyOtherProcess(false, TestTimeouts::action_timeout()));
- CheckNotified();
-}
-
-// 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) {
- CreateProcessSingletonOnThread();
-
- BlockWorkerThread();
-
- EXPECT_EQ(0, unlink(lock_path_.value().c_str()));
- EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str()));
-
- EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE,
- NotifyOtherProcess(false, TestTimeouts::action_timeout()));
-
- ASSERT_EQ(0, unlink(lock_path_.value().c_str()));
-
- UnblockWorkerThread();
-}
-
-// 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) {
- CreateProcessSingletonOnThread();
-
- BlockWorkerThread();
-
- EXPECT_EQ(0, unlink(lock_path_.value().c_str()));
- EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str()));
-
- std::string url("about:blank");
- EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE,
- NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout()));
-
- ASSERT_EQ(0, unlink(lock_path_.value().c_str()));
-
- UnblockWorkerThread();
-}
-
-// Test that Create fails when another browser is using the profile directory.
-TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) {
- CreateProcessSingletonOnThread();
-
- scoped_ptr<TestableProcessSingleton> process_singleton(
- CreateProcessSingleton());
- process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1);
- EXPECT_FALSE(process_singleton->Create());
-}
-
-// Test that Create fails when another browser is using the profile directory
-// but with the old socket location.
-TEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) {
- CreateProcessSingletonOnThread();
- scoped_ptr<TestableProcessSingleton> process_singleton(
- CreateProcessSingleton());
- process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1);
-
- // Do some surgery so as to look like the old configuration.
- char buf[PATH_MAX];
- ssize_t len = readlink(socket_path_.value().c_str(), buf, sizeof(buf));
- ASSERT_GT(len, 0);
- base::FilePath socket_target_path = base::FilePath(std::string(buf, len));
- ASSERT_EQ(0, unlink(socket_path_.value().c_str()));
- ASSERT_EQ(0, rename(socket_target_path.value().c_str(),
- socket_path_.value().c_str()));
- ASSERT_EQ(0, unlink(cookie_path_.value().c_str()));
-
- EXPECT_FALSE(process_singleton->Create());
-}
-
-// 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) {
- CreateProcessSingletonOnThread();
- // Change the cookie.
- EXPECT_EQ(0, unlink(cookie_path_.value().c_str()));
- EXPECT_EQ(0, symlink("INCORRECTCOOKIE", cookie_path_.value().c_str()));
-
- // Also change the hostname, so the remote does not retry.
- EXPECT_EQ(0, unlink(lock_path_.value().c_str()));
- EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str()));
-
- std::string url("about:blank");
- EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE,
- NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout()));
-}
-

Powered by Google App Engine
This is Rietveld 408576698