1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/file_util.h"
6#include "base/path_service.h"
7#include "base/process_util.h"
8#include "base/string_util.h"
9#include "base/memory/scoped_temp_dir.h"
10#include "build/build_config.h"
11#include "chrome/browser/importer/firefox_profile_lock.h"
12#include "chrome/common/chrome_paths.h"
13#include "chrome/test/file_test_utils.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16class FirefoxProfileLockTest : public testing::Test {
17 protected:
18  virtual void SetUp() {
19    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
20  }
21
22  ScopedTempDir temp_dir_;
23};
24
25TEST_F(FirefoxProfileLockTest, LockTest) {
26  FirefoxProfileLock lock1(temp_dir_.path());
27  ASSERT_TRUE(lock1.HasAcquired());
28  lock1.Unlock();
29  ASSERT_FALSE(lock1.HasAcquired());
30  lock1.Lock();
31  ASSERT_TRUE(lock1.HasAcquired());
32}
33
34// Tests basic functionality and verifies that the lock file is deleted after
35// use.
36TEST_F(FirefoxProfileLockTest, ProfileLock) {
37  FilePath test_path;
38  ASSERT_TRUE(file_util::CreateNewTempDirectory(
39      FILE_PATH_LITERAL("firefox_profile"), &test_path));
40  FilePath lock_file_path = test_path;
41  FileAutoDeleter deleter(lock_file_path);
42  lock_file_path = lock_file_path.Append(FirefoxProfileLock::kLockFileName);
43
44  scoped_ptr<FirefoxProfileLock> lock;
45  EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock.get());
46  EXPECT_FALSE(file_util::PathExists(lock_file_path));
47  lock.reset(new FirefoxProfileLock(test_path));
48  EXPECT_TRUE(lock->HasAcquired());
49  EXPECT_TRUE(file_util::PathExists(lock_file_path));
50  lock->Unlock();
51  EXPECT_FALSE(lock->HasAcquired());
52
53  // In the posix code, we don't delete the file when releasing the lock.
54#if !defined(OS_POSIX)
55  EXPECT_FALSE(file_util::PathExists(lock_file_path));
56#endif  // !defined(OS_POSIX)
57  lock->Lock();
58  EXPECT_TRUE(lock->HasAcquired());
59  EXPECT_TRUE(file_util::PathExists(lock_file_path));
60  lock->Lock();
61  EXPECT_TRUE(lock->HasAcquired());
62  lock->Unlock();
63  EXPECT_FALSE(lock->HasAcquired());
64  // In the posix code, we don't delete the file when releasing the lock.
65#if !defined(OS_POSIX)
66  EXPECT_FALSE(file_util::PathExists(lock_file_path));
67#endif  // !defined(OS_POSIX)
68}
69
70// If for some reason the lock file is left behind by the previous owner, we
71// should still be able to lock it, at least in the Windows implementation.
72TEST_F(FirefoxProfileLockTest, ProfileLockOrphaned) {
73  FilePath test_path;
74  ASSERT_TRUE(file_util::CreateNewTempDirectory(
75      FILE_PATH_LITERAL("firefox_profile"), &test_path));
76  FilePath lock_file_path = test_path;
77  FileAutoDeleter deleter(lock_file_path);
78  lock_file_path = lock_file_path.Append(FirefoxProfileLock::kLockFileName);
79
80  // Create the orphaned lock file.
81  FILE* lock_file = file_util::OpenFile(lock_file_path, "w");
82  ASSERT_TRUE(lock_file);
83  file_util::CloseFile(lock_file);
84  EXPECT_TRUE(file_util::PathExists(lock_file_path));
85
86  scoped_ptr<FirefoxProfileLock> lock;
87  EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock.get());
88  lock.reset(new FirefoxProfileLock(test_path));
89  EXPECT_TRUE(lock->HasAcquired());
90  lock->Unlock();
91  EXPECT_FALSE(lock->HasAcquired());
92}
93
94// This is broken on POSIX since the same process is allowed to reacquire a
95// lock.
96#if !defined(OS_POSIX)
97// Tests two locks contending for the same lock file.
98TEST_F(FirefoxProfileLockTest, ProfileLockContention) {
99  FilePath test_path;
100  ASSERT_TRUE(file_util::CreateNewTempDirectory(
101      FILE_PATH_LITERAL("firefox_profile"), &test_path));
102  FileAutoDeleter deleter(test_path);
103
104  scoped_ptr<FirefoxProfileLock> lock1;
105  EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock1.get());
106  lock1.reset(new FirefoxProfileLock(test_path));
107  EXPECT_TRUE(lock1->HasAcquired());
108
109  scoped_ptr<FirefoxProfileLock> lock2;
110  EXPECT_EQ(static_cast<FirefoxProfileLock*>(NULL), lock2.get());
111  lock2.reset(new FirefoxProfileLock(test_path));
112  EXPECT_FALSE(lock2->HasAcquired());
113
114  lock1->Unlock();
115  EXPECT_FALSE(lock1->HasAcquired());
116
117  lock2->Lock();
118  EXPECT_TRUE(lock2->HasAcquired());
119  lock2->Unlock();
120  EXPECT_FALSE(lock2->HasAcquired());
121}
122#endif
123