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
16 class FirefoxProfileLockTest : public testing::Test {
17 protected:
SetUp()18 virtual void SetUp() {
19 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
20 }
21
22 ScopedTempDir temp_dir_;
23 };
24
TEST_F(FirefoxProfileLockTest,LockTest)25 TEST_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.
TEST_F(FirefoxProfileLockTest,ProfileLock)36 TEST_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.
TEST_F(FirefoxProfileLockTest,ProfileLockOrphaned)72 TEST_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.
TEST_F(FirefoxProfileLockTest,ProfileLockContention)98 TEST_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