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 
TEST(LockFileManagerTest,Basic)21 TEST(LockFileManagerTest, Basic) {
22   TempDir TmpDir("LockFileManagerTestDir", /*Unique*/ true);
23 
24   SmallString<64> LockedFile(TmpDir.path());
25   sys::path::append(LockedFile, "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 
TEST(LockFileManagerTest,LinkLockExists)42 TEST(LockFileManagerTest, LinkLockExists) {
43   TempDir LockFileManagerTestDir("LockFileManagerTestDir", /*Unique*/ true);
44 
45   SmallString<64> LockedFile(LockFileManagerTestDir.path());
46   sys::path::append(LockedFile, "file");
47 
48   SmallString<64> FileLocK(LockFileManagerTestDir.path());
49   sys::path::append(FileLocK, "file.lock");
50 
51   SmallString<64> TmpFileLock(LockFileManagerTestDir.path());
52   sys::path::append(TmpFileLock, "file.lock-000");
53 
54   int FD;
55   std::error_code EC = sys::fs::openFileForWrite(TmpFileLock.str(), FD);
56   ASSERT_FALSE(EC);
57 
58   int Ret = close(FD);
59   ASSERT_EQ(Ret, 0);
60 
61   EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str());
62   ASSERT_FALSE(EC);
63 
64   EC = sys::fs::remove(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 
TEST(LockFileManagerTest,RelativePath)79 TEST(LockFileManagerTest, RelativePath) {
80   TempDir LockFileManagerTestDir("LockFileManagerTestDir", /*Unique*/ true);
81 
82   char PathBuf[1024];
83   const char *OrigPath = getcwd(PathBuf, 1024);
84   ASSERT_FALSE(chdir(LockFileManagerTestDir.c_str()));
85 
86   TempDir inner("inner");
87   SmallString<64> LockedFile(inner.path());
88   sys::path::append(LockedFile, "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