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(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(StringRef(LockedFile))); 40 } 41 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(StringRef(TmpFileLock), 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(StringRef(TmpFileLock)); 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(StringRef(LockedFile))); 76 } 77 78 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.path().data())); 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