17de8ea3dSReid Kleckner //===- unittests/LockFileManagerTest.cpp - LockFileManager tests ----------===//
27de8ea3dSReid Kleckner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67de8ea3dSReid Kleckner //
77de8ea3dSReid Kleckner //===----------------------------------------------------------------------===//
87de8ea3dSReid Kleckner 
97de8ea3dSReid Kleckner #include "llvm/Support/LockFileManager.h"
107de8ea3dSReid Kleckner #include "llvm/Support/FileSystem.h"
117de8ea3dSReid Kleckner #include "llvm/Support/Path.h"
12fad75598SSergej Jaskiewicz #include "llvm/Testing/Support/SupportHelpers.h"
137de8ea3dSReid Kleckner #include "gtest/gtest.h"
147de8ea3dSReid Kleckner #include <memory>
157de8ea3dSReid Kleckner 
167de8ea3dSReid Kleckner using namespace llvm;
17fad75598SSergej Jaskiewicz using llvm::unittest::TempDir;
187de8ea3dSReid Kleckner 
197de8ea3dSReid Kleckner namespace {
207de8ea3dSReid Kleckner 
TEST(LockFileManagerTest,Basic)217de8ea3dSReid Kleckner TEST(LockFileManagerTest, Basic) {
22fad75598SSergej Jaskiewicz   TempDir TmpDir("LockFileManagerTestDir", /*Unique*/ true);
237de8ea3dSReid Kleckner 
24fad75598SSergej Jaskiewicz   SmallString<64> LockedFile(TmpDir.path());
257de8ea3dSReid Kleckner   sys::path::append(LockedFile, "file.lock");
267de8ea3dSReid Kleckner 
277de8ea3dSReid Kleckner   {
287de8ea3dSReid Kleckner     // The lock file should not exist, so we should successfully acquire it.
297de8ea3dSReid Kleckner     LockFileManager Locked1(LockedFile);
307de8ea3dSReid Kleckner     EXPECT_EQ(LockFileManager::LFS_Owned, Locked1.getState());
317de8ea3dSReid Kleckner 
327de8ea3dSReid Kleckner     // Attempting to reacquire the lock should fail.  Waiting on it would cause
337de8ea3dSReid Kleckner     // deadlock, so don't try that.
347de8ea3dSReid Kleckner     LockFileManager Locked2(LockedFile);
357de8ea3dSReid Kleckner     EXPECT_NE(LockFileManager::LFS_Owned, Locked2.getState());
367de8ea3dSReid Kleckner   }
377de8ea3dSReid Kleckner 
387de8ea3dSReid Kleckner   // Now that the lock is out of scope, the file should be gone.
39*1def2579SDavid Blaikie   EXPECT_FALSE(sys::fs::exists(LockedFile.str()));
407de8ea3dSReid Kleckner }
417de8ea3dSReid Kleckner 
TEST(LockFileManagerTest,LinkLockExists)4237575693SArgyrios Kyrtzidis TEST(LockFileManagerTest, LinkLockExists) {
43fad75598SSergej Jaskiewicz   TempDir LockFileManagerTestDir("LockFileManagerTestDir", /*Unique*/ true);
4437575693SArgyrios Kyrtzidis 
45fad75598SSergej Jaskiewicz   SmallString<64> LockedFile(LockFileManagerTestDir.path());
4637575693SArgyrios Kyrtzidis   sys::path::append(LockedFile, "file");
4737575693SArgyrios Kyrtzidis 
48fad75598SSergej Jaskiewicz   SmallString<64> FileLocK(LockFileManagerTestDir.path());
4937575693SArgyrios Kyrtzidis   sys::path::append(FileLocK, "file.lock");
5037575693SArgyrios Kyrtzidis 
51fad75598SSergej Jaskiewicz   SmallString<64> TmpFileLock(LockFileManagerTestDir.path());
5237575693SArgyrios Kyrtzidis   sys::path::append(TmpFileLock, "file.lock-000");
5337575693SArgyrios Kyrtzidis 
54663ac286SRafael Espindola   int FD;
55*1def2579SDavid Blaikie   std::error_code EC = sys::fs::openFileForWrite(TmpFileLock.str(), FD);
5637575693SArgyrios Kyrtzidis   ASSERT_FALSE(EC);
57663ac286SRafael Espindola 
58663ac286SRafael Espindola   int Ret = close(FD);
59663ac286SRafael Espindola   ASSERT_EQ(Ret, 0);
60663ac286SRafael Espindola 
61663ac286SRafael Espindola   EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str());
62663ac286SRafael Espindola   ASSERT_FALSE(EC);
63663ac286SRafael Espindola 
64*1def2579SDavid Blaikie   EC = sys::fs::remove(TmpFileLock.str());
65663ac286SRafael Espindola   ASSERT_FALSE(EC);
6637575693SArgyrios Kyrtzidis 
6737575693SArgyrios Kyrtzidis   {
6837575693SArgyrios Kyrtzidis     // The lock file doesn't point to a real file, so we should successfully
6937575693SArgyrios Kyrtzidis     // acquire it.
7037575693SArgyrios Kyrtzidis     LockFileManager Locked(LockedFile);
7137575693SArgyrios Kyrtzidis     EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
7237575693SArgyrios Kyrtzidis   }
7337575693SArgyrios Kyrtzidis 
7437575693SArgyrios Kyrtzidis   // Now that the lock is out of scope, the file should be gone.
75*1def2579SDavid Blaikie   EXPECT_FALSE(sys::fs::exists(LockedFile.str()));
7637575693SArgyrios Kyrtzidis }
7737575693SArgyrios Kyrtzidis 
78531a5be4SArgyrios Kyrtzidis 
TEST(LockFileManagerTest,RelativePath)79531a5be4SArgyrios Kyrtzidis TEST(LockFileManagerTest, RelativePath) {
80fad75598SSergej Jaskiewicz   TempDir LockFileManagerTestDir("LockFileManagerTestDir", /*Unique*/ true);
81531a5be4SArgyrios Kyrtzidis 
82531a5be4SArgyrios Kyrtzidis   char PathBuf[1024];
83531a5be4SArgyrios Kyrtzidis   const char *OrigPath = getcwd(PathBuf, 1024);
84e7b40c54SSergej Jaskiewicz   ASSERT_FALSE(chdir(LockFileManagerTestDir.c_str()));
85531a5be4SArgyrios Kyrtzidis 
86fad75598SSergej Jaskiewicz   TempDir inner("inner");
87fad75598SSergej Jaskiewicz   SmallString<64> LockedFile(inner.path());
88531a5be4SArgyrios Kyrtzidis   sys::path::append(LockedFile, "file");
89531a5be4SArgyrios Kyrtzidis 
90531a5be4SArgyrios Kyrtzidis   SmallString<64> FileLock(LockedFile);
91531a5be4SArgyrios Kyrtzidis   FileLock += ".lock";
92531a5be4SArgyrios Kyrtzidis 
93531a5be4SArgyrios Kyrtzidis   {
94531a5be4SArgyrios Kyrtzidis     // The lock file should not exist, so we should successfully acquire it.
95531a5be4SArgyrios Kyrtzidis     LockFileManager Locked(LockedFile);
96531a5be4SArgyrios Kyrtzidis     EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
97531a5be4SArgyrios Kyrtzidis     EXPECT_TRUE(sys::fs::exists(FileLock.str()));
98531a5be4SArgyrios Kyrtzidis   }
99531a5be4SArgyrios Kyrtzidis 
100531a5be4SArgyrios Kyrtzidis   // Now that the lock is out of scope, the file should be gone.
101531a5be4SArgyrios Kyrtzidis   EXPECT_FALSE(sys::fs::exists(LockedFile.str()));
102531a5be4SArgyrios Kyrtzidis   EXPECT_FALSE(sys::fs::exists(FileLock.str()));
103531a5be4SArgyrios Kyrtzidis 
10474c2c8f1SAaron Ballman   ASSERT_FALSE(chdir(OrigPath));
105126a6c02SNAKAMURA Takumi }
106531a5be4SArgyrios Kyrtzidis 
1077de8ea3dSReid Kleckner } // end anonymous namespace
108