15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 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/browser/process_singleton.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <fcntl.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <signal.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <sys/un.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/wait.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 229ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/posix/eintr_wrapper.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/thread_test_helper.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass ProcessSingletonPosixTest : public testing::Test { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A ProcessSingleton exposing some protected methods for testing. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class TestableProcessSingleton : public ProcessSingleton { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit TestableProcessSingleton(const base::FilePath& user_data_dir) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : ProcessSingleton( 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_data_dir, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&TestableProcessSingleton::NotificationCallback, 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Unretained(this))) {} 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<CommandLine::StringVector> callback_command_lines_; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using ProcessSingleton::NotifyOtherProcessWithTimeout; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using ProcessSingleton::OverrideCurrentPidForTesting; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) using ProcessSingleton::OverrideKillCallbackForTesting; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool NotificationCallback(const CommandLine& command_line, 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& current_directory) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback_command_lines_.push_back(command_line.argv()); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ProcessSingletonPosixTest() 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : kill_callbacks_(0), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_(BrowserThread::IO), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event_(true, false), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_event_(true, false), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_singleton_on_thread_(NULL) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.StartIOThread(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Test::SetUp(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessSingleton::DisablePromptForTesting(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Put the lock in a temporary directory. Doesn't need to be a 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // full profile to test this code. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Use a long directory name to ensure that the socket isn't opened through 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the symlink. 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) user_data_path_ = temp_dir_.path().Append( 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string(sizeof(sockaddr_un::sun_path), 'a')); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ASSERT_TRUE(CreateDirectory(user_data_path_)); 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) lock_path_ = user_data_path_.Append(chrome::kSingletonLockFilename); 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) socket_path_ = user_data_path_.Append(chrome::kSingletonSocketFilename); 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) cookie_path_ = user_data_path_.Append(chrome::kSingletonCookieFilename); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::ThreadTestHelper> io_helper(new base::ThreadTestHelper( 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get())); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(io_helper->Run()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destruct the ProcessSingleton object before the IO thread so that its 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // internals are destructed properly. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (process_singleton_on_thread_) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_->message_loop()->PostTask( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ProcessSingletonPosixTest::DestructProcessSingleton, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<base::ThreadTestHelper> helper(new base::ThreadTestHelper( 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) worker_thread_->message_loop_proxy().get())); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(helper->Run()); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.Stop(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Test::TearDown(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateProcessSingletonOnThread() { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(NULL, worker_thread_.get()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_.reset(new base::Thread("BlockingThread")); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_->Start(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_->message_loop()->PostTask( 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ProcessSingletonPosixTest:: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonInternal, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::ThreadTestHelper> helper( 1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new base::ThreadTestHelper(worker_thread_->message_loop_proxy().get())); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(helper->Run()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestableProcessSingleton* CreateProcessSingleton() { 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return new TestableProcessSingleton(user_data_path_); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void VerifyFiles() { 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu struct stat statbuf; 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_EQ(0, lstat(lock_path_.value().c_str(), &statbuf)); 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu char buf[PATH_MAX]; 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ssize_t len = readlink(lock_path_.value().c_str(), buf, PATH_MAX); 1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_GT(len, 0); 1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_EQ(0, lstat(socket_path_.value().c_str(), &statbuf)); 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(S_ISLNK(statbuf.st_mode)); 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu len = readlink(socket_path_.value().c_str(), buf, PATH_MAX); 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_GT(len, 0); 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::FilePath socket_target_path = base::FilePath(std::string(buf, len)); 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_EQ(0, lstat(socket_target_path.value().c_str(), &statbuf)); 1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(S_ISSOCK(statbuf.st_mode)); 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu len = readlink(cookie_path_.value().c_str(), buf, PATH_MAX); 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_GT(len, 0); 1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::string cookie(buf, len); 1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::FilePath remote_cookie_path = socket_target_path.DirName(). 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Append(chrome::kSingletonCookieFilename); 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_GT(len, 0); 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(cookie, std::string(buf, len)); 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProcessSingleton::NotifyResult NotifyOtherProcess(bool override_kill) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TestableProcessSingleton> process_singleton( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateProcessSingleton()); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.AppendArg("about:blank"); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (override_kill) { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) process_singleton->OverrideCurrentPidForTesting( 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::GetCurrentProcId() + 1); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_singleton->OverrideKillCallbackForTesting( 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ProcessSingletonPosixTest::KillCallback, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process_singleton->NotifyOtherProcessWithTimeout( 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci command_line, kRetryAttempts, timeout(), true); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& url) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TestableProcessSingleton> process_singleton( 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateProcessSingleton()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.AppendArg(url); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci command_line, kRetryAttempts, timeout()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckNotified() { 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(process_singleton_on_thread_ != NULL); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(1u, process_singleton_on_thread_->callback_command_lines_.size()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i < process_singleton_on_thread_->callback_command_lines_[0].size(); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++i) { 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (process_singleton_on_thread_->callback_command_lines_[0][i] == 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "about:blank") { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found = true; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(found); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, kill_callbacks_); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BlockWorkerThread() { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_->message_loop()->PostTask( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Bind(&ProcessSingletonPosixTest::BlockThread, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnblockWorkerThread() { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event_.Signal(); // Unblock the worker thread for shutdown. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_event_.Wait(); // Ensure thread unblocks before continuing. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BlockThread() { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event_.Wait(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_event_.Signal(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::FilePath user_data_path_; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath lock_path_; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath socket_path_; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath cookie_path_; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kill_callbacks_; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static const int kRetryAttempts = 2; 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta timeout() const { 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return TestTimeouts::tiny_timeout() * kRetryAttempts; 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CreateProcessSingletonInternal() { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(!process_singleton_on_thread_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_singleton_on_thread_ = CreateProcessSingleton(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(ProcessSingleton::PROCESS_NONE, 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) process_singleton_on_thread_->NotifyOtherProcessOrCreate()); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DestructProcessSingleton() { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(process_singleton_on_thread_); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete process_singleton_on_thread_; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void KillCallback(int pid) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kill_callbacks_++; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir temp_dir_; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent wait_event_; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent signal_event_; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Thread> worker_thread_; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestableProcessSingleton* process_singleton_on_thread_; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test if the socket file and symbol link created by ProcessSingletonPosix 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are valid. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If this test flakes, use http://crbug.com/74554. 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, CheckSocketFile) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 2705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VerifyFiles(); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(james.su@gmail.com): port following tests to Windows. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test success case of NotifyOtherProcess(). 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessSuccess) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, NotifyOtherProcess(true)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckNotified(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test failure case of NotifyOtherProcess(). 2825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessFailure) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockWorkerThread(); 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROCESS_NONE, NotifyOtherProcess(true)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, kill_callbacks_); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnblockWorkerThread(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't kill ourselves by accident if a lockfile with the same pid 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// happens to exist. 2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessNoSuicide) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Replace lockfile with one containing our own pid. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string symlink_content = base::StringPrintf( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%s%c%u", 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::GetHostName().c_str(), 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) '-', 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::GetCurrentProcId()); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink(symlink_content.c_str(), lock_path_.value().c_str())); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove socket so that we will not be able to notify the existing browser. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(socket_path_.value().c_str())); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROCESS_NONE, NotifyOtherProcess(false)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've gotten to this point without killing ourself, the test succeeded. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we can still notify a process on the same host even after the 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hostname changed. 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessHostChanged) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, NotifyOtherProcess(false)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckNotified(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we fail when lock says process is on another host and we can't 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notify it over the socket. 3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessDifferingHost) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockWorkerThread(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, NotifyOtherProcess(false)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, unlink(lock_path_.value().c_str())); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnblockWorkerThread(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we fail when lock says process is on another host and we can't 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notify it over the socket. 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessOrCreate_DifferingHost) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockWorkerThread(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url("about:blank"); 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, NotifyOtherProcessOrCreate(url)); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, unlink(lock_path_.value().c_str())); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnblockWorkerThread(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Create fails when another browser is using the profile directory. 3585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, CreateFailsWithExistingBrowser) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TestableProcessSingleton> process_singleton( 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateProcessSingleton()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(process_singleton->Create()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that Create fails when another browser is using the profile directory 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but with the old socket location. 3695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, CreateChecksCompatibilitySocket) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<TestableProcessSingleton> process_singleton( 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateProcessSingleton()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do some surgery so as to look like the old configuration. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[PATH_MAX]; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t len = readlink(socket_path_.value().c_str(), buf, sizeof(buf)); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(len, 0); 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath socket_target_path = base::FilePath(std::string(buf, len)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, unlink(socket_path_.value().c_str())); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, rename(socket_target_path.value().c_str(), 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_path_.value().c_str())); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, unlink(cookie_path_.value().c_str())); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(process_singleton->Create()); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we fail when lock says process is on another host and we can't 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notify it over the socket before of a bad cookie. 3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, NotifyOtherProcessOrCreate_BadCookie) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateProcessSingletonOnThread(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the cookie. 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(cookie_path_.value().c_str())); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink("INCORRECTCOOKIE", cookie_path_.value().c_str())); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Also change the hostname, so the remote does not retry. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, unlink(lock_path_.value().c_str())); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url("about:blank"); 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, NotifyOtherProcessOrCreate(url)); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#if defined(OS_MACOSX) 4055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that if there is an existing lock file, and we could not flock() 4065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// it, then exit. 4075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, CreateRespectsOldMacLock) { 4085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<TestableProcessSingleton> process_singleton( 4095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateProcessSingleton()); 4105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::ScopedFD lock_fd(HANDLE_EINTR( 4115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu open(lock_path_.value().c_str(), O_RDWR | O_CREAT | O_EXLOCK, 0644))); 4125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(lock_fd.is_valid()); 4135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_FALSE(process_singleton->Create()); 4145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::File::Info info; 4155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(base::GetFileInfo(lock_path_, &info)); 4165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_FALSE(info.is_directory); 4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_FALSE(info.is_symbolic_link); 4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Test that if there is an existing lock file, and it's not locked, we replace 4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// it. 4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(ProcessSingletonPosixTest, CreateReplacesOldMacLock) { 4235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<TestableProcessSingleton> process_singleton( 4245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CreateProcessSingleton()); 4255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_EQ(0, base::WriteFile(lock_path_, "", 0)); 4265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(process_singleton->Create()); 4275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VerifyFiles(); 4285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif // defined(OS_MACOSX) 430