1 | //===- unittests/LockFileManagerTest.cpp - LockFileManager tests ----------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Support/LockFileManager.h" |
10 | #include "llvm/Support/FileSystem.h" |
11 | #include "llvm/Support/Path.h" |
12 | #include "llvm/Testing/Support/SupportHelpers.h" |
13 | #include "gtest/gtest.h" |
14 | #include <memory> |
15 | |
16 | using namespace llvm; |
17 | using llvm::unittest::TempDir; |
18 | |
19 | namespace { |
20 | |
21 | TEST(LockFileManagerTest, Basic) { |
22 | TempDir TmpDir("LockFileManagerTestDir" , /*Unique*/ true); |
23 | |
24 | SmallString<64> LockedFile(TmpDir.path()); |
25 | sys::path::append(path&: LockedFile, a: "file.lock" ); |
26 | |
27 | { |
28 | // The lock file should not exist, so we should successfully acquire it. |
29 | LockFileManager Locked1(LockedFile); |
30 | EXPECT_EQ(LockFileManager::LFS_Owned, Locked1.getState()); |
31 | |
32 | // Attempting to reacquire the lock should fail. Waiting on it would cause |
33 | // deadlock, so don't try that. |
34 | LockFileManager Locked2(LockedFile); |
35 | EXPECT_NE(LockFileManager::LFS_Owned, Locked2.getState()); |
36 | } |
37 | |
38 | // Now that the lock is out of scope, the file should be gone. |
39 | EXPECT_FALSE(sys::fs::exists(LockedFile.str())); |
40 | } |
41 | |
42 | TEST(LockFileManagerTest, LinkLockExists) { |
43 | TempDir LockFileManagerTestDir("LockFileManagerTestDir" , /*Unique*/ true); |
44 | |
45 | SmallString<64> LockedFile(LockFileManagerTestDir.path()); |
46 | sys::path::append(path&: LockedFile, a: "file" ); |
47 | |
48 | SmallString<64> FileLocK(LockFileManagerTestDir.path()); |
49 | sys::path::append(path&: FileLocK, a: "file.lock" ); |
50 | |
51 | SmallString<64> TmpFileLock(LockFileManagerTestDir.path()); |
52 | sys::path::append(path&: TmpFileLock, a: "file.lock-000" ); |
53 | |
54 | int FD; |
55 | std::error_code EC = sys::fs::openFileForWrite(Name: TmpFileLock.str(), ResultFD&: FD); |
56 | ASSERT_FALSE(EC); |
57 | |
58 | int Ret = close(fd: FD); |
59 | ASSERT_EQ(Ret, 0); |
60 | |
61 | EC = sys::fs::create_link(to: TmpFileLock.str(), from: FileLocK.str()); |
62 | ASSERT_FALSE(EC); |
63 | |
64 | EC = sys::fs::remove(path: TmpFileLock.str()); |
65 | ASSERT_FALSE(EC); |
66 | |
67 | { |
68 | // The lock file doesn't point to a real file, so we should successfully |
69 | // acquire it. |
70 | LockFileManager Locked(LockedFile); |
71 | EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState()); |
72 | } |
73 | |
74 | // Now that the lock is out of scope, the file should be gone. |
75 | EXPECT_FALSE(sys::fs::exists(LockedFile.str())); |
76 | } |
77 | |
78 | |
79 | TEST(LockFileManagerTest, RelativePath) { |
80 | TempDir LockFileManagerTestDir("LockFileManagerTestDir" , /*Unique*/ true); |
81 | |
82 | char PathBuf[1024]; |
83 | const char *OrigPath = getcwd(buf: PathBuf, size: 1024); |
84 | ASSERT_FALSE(chdir(LockFileManagerTestDir.c_str())); |
85 | |
86 | TempDir inner("inner" ); |
87 | SmallString<64> LockedFile(inner.path()); |
88 | sys::path::append(path&: LockedFile, a: "file" ); |
89 | |
90 | SmallString<64> FileLock(LockedFile); |
91 | FileLock += ".lock" ; |
92 | |
93 | { |
94 | // The lock file should not exist, so we should successfully acquire it. |
95 | LockFileManager Locked(LockedFile); |
96 | EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState()); |
97 | EXPECT_TRUE(sys::fs::exists(FileLock.str())); |
98 | } |
99 | |
100 | // Now that the lock is out of scope, the file should be gone. |
101 | EXPECT_FALSE(sys::fs::exists(LockedFile.str())); |
102 | EXPECT_FALSE(sys::fs::exists(FileLock.str())); |
103 | |
104 | ASSERT_FALSE(chdir(OrigPath)); |
105 | } |
106 | |
107 | } // end anonymous namespace |
108 | |