1 //===- unittests/LockFileManagerTest.cpp - LockFileManager tests ----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Support/LockFileManager.h" 11 #include "llvm/Support/FileSystem.h" 12 #include "llvm/Support/Path.h" 13 #include "gtest/gtest.h" 14 #include <memory> 15 16 using namespace llvm; 17 using std::error_code; 18 19 namespace { 20 21 TEST(LockFileManagerTest, Basic) { 22 SmallString<64> TmpDir; 23 error_code EC; 24 EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir); 25 ASSERT_FALSE(EC); 26 27 SmallString<64> LockedFile(TmpDir); 28 sys::path::append(LockedFile, "file.lock"); 29 30 { 31 // The lock file should not exist, so we should successfully acquire it. 32 LockFileManager Locked1(LockedFile); 33 EXPECT_EQ(LockFileManager::LFS_Owned, Locked1.getState()); 34 35 // Attempting to reacquire the lock should fail. Waiting on it would cause 36 // deadlock, so don't try that. 37 LockFileManager Locked2(LockedFile); 38 EXPECT_NE(LockFileManager::LFS_Owned, Locked2.getState()); 39 } 40 41 // Now that the lock is out of scope, the file should be gone. 42 EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile))); 43 44 EC = sys::fs::remove(StringRef(TmpDir)); 45 ASSERT_FALSE(EC); 46 } 47 48 TEST(LockFileManagerTest, LinkLockExists) { 49 SmallString<64> TmpDir; 50 error_code EC; 51 EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir); 52 ASSERT_FALSE(EC); 53 54 SmallString<64> LockedFile(TmpDir); 55 sys::path::append(LockedFile, "file"); 56 57 SmallString<64> FileLocK(TmpDir); 58 sys::path::append(FileLocK, "file.lock"); 59 60 SmallString<64> TmpFileLock(TmpDir); 61 sys::path::append(TmpFileLock, "file.lock-000"); 62 63 int FD; 64 EC = sys::fs::openFileForWrite(StringRef(TmpFileLock), FD, sys::fs::F_None); 65 ASSERT_FALSE(EC); 66 67 int Ret = close(FD); 68 ASSERT_EQ(Ret, 0); 69 70 EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str()); 71 ASSERT_FALSE(EC); 72 73 EC = sys::fs::remove(StringRef(TmpFileLock)); 74 ASSERT_FALSE(EC); 75 76 { 77 // The lock file doesn't point to a real file, so we should successfully 78 // acquire it. 79 LockFileManager Locked(LockedFile); 80 EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState()); 81 } 82 83 // Now that the lock is out of scope, the file should be gone. 84 EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile))); 85 86 EC = sys::fs::remove(StringRef(TmpDir)); 87 ASSERT_FALSE(EC); 88 } 89 90 91 TEST(LockFileManagerTest, RelativePath) { 92 SmallString<64> TmpDir; 93 error_code EC; 94 EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir); 95 ASSERT_FALSE(EC); 96 97 char PathBuf[1024]; 98 const char *OrigPath = getcwd(PathBuf, 1024); 99 chdir(TmpDir.c_str()); 100 101 sys::fs::create_directory("inner"); 102 SmallString<64> LockedFile("inner"); 103 sys::path::append(LockedFile, "file"); 104 105 SmallString<64> FileLock(LockedFile); 106 FileLock += ".lock"; 107 108 { 109 // The lock file should not exist, so we should successfully acquire it. 110 LockFileManager Locked(LockedFile); 111 EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState()); 112 EXPECT_TRUE(sys::fs::exists(FileLock.str())); 113 } 114 115 // Now that the lock is out of scope, the file should be gone. 116 EXPECT_FALSE(sys::fs::exists(LockedFile.str())); 117 EXPECT_FALSE(sys::fs::exists(FileLock.str())); 118 119 EC = sys::fs::remove("inner"); 120 ASSERT_FALSE(EC); 121 122 chdir(OrigPath); 123 124 EC = sys::fs::remove(StringRef(TmpDir)); 125 ASSERT_FALSE(EC); 126 } 127 128 } // end anonymous namespace 129