1 //===- DependencyScanningFilesystemTest.cpp -------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/Support/VirtualFileSystem.h"
12 #include "gtest/gtest.h"
14 using namespace clang::tooling::dependencies
;
16 TEST(DependencyScanningWorkerFilesystem
, CacheStatusFailures
) {
17 auto InMemoryFS
= llvm::makeIntrusiveRefCnt
<llvm::vfs::InMemoryFileSystem
>();
19 auto InstrumentingFS
=
20 llvm::makeIntrusiveRefCnt
<llvm::vfs::TracingFileSystem
>(InMemoryFS
);
22 DependencyScanningFilesystemSharedCache SharedCache
;
23 DependencyScanningWorkerFilesystem
DepFS(SharedCache
, InstrumentingFS
);
24 DependencyScanningWorkerFilesystem
DepFS2(SharedCache
, InstrumentingFS
);
26 DepFS
.status("/foo.c");
27 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 1u);
29 DepFS
.status("/foo.c");
30 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 1u); // Cached, no increase.
32 DepFS
.status("/bar.c");
33 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 2u);
35 DepFS2
.status("/foo.c");
36 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 2u); // Shared cache.
39 TEST(DependencyScanningFilesystem
, CacheGetRealPath
) {
40 auto InMemoryFS
= llvm::makeIntrusiveRefCnt
<llvm::vfs::InMemoryFileSystem
>();
41 InMemoryFS
->setCurrentWorkingDirectory("/");
42 InMemoryFS
->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer(""));
43 InMemoryFS
->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer(""));
45 auto InstrumentingFS
=
46 llvm::makeIntrusiveRefCnt
<llvm::vfs::TracingFileSystem
>(InMemoryFS
);
48 DependencyScanningFilesystemSharedCache SharedCache
;
49 DependencyScanningWorkerFilesystem
DepFS(SharedCache
, InstrumentingFS
);
50 DependencyScanningWorkerFilesystem
DepFS2(SharedCache
, InstrumentingFS
);
53 llvm::SmallString
<128> Result
;
54 DepFS
.getRealPath("/foo", Result
);
55 EXPECT_EQ(InstrumentingFS
->NumGetRealPathCalls
, 1u);
59 llvm::SmallString
<128> Result
;
60 DepFS
.getRealPath("/foo", Result
);
61 EXPECT_EQ(InstrumentingFS
->NumGetRealPathCalls
, 1u); // Cached, no increase.
65 llvm::SmallString
<128> Result
;
66 DepFS
.getRealPath("/bar", Result
);
67 EXPECT_EQ(InstrumentingFS
->NumGetRealPathCalls
, 2u);
71 llvm::SmallString
<128> Result
;
72 DepFS2
.getRealPath("/foo", Result
);
73 EXPECT_EQ(InstrumentingFS
->NumGetRealPathCalls
, 2u); // Shared cache.
77 TEST(DependencyScanningFilesystem
, RealPathAndStatusInvariants
) {
78 auto InMemoryFS
= llvm::makeIntrusiveRefCnt
<llvm::vfs::InMemoryFileSystem
>();
79 InMemoryFS
->setCurrentWorkingDirectory("/");
80 InMemoryFS
->addFile("/foo.c", 0, llvm::MemoryBuffer::getMemBuffer(""));
81 InMemoryFS
->addFile("/bar.c", 0, llvm::MemoryBuffer::getMemBuffer(""));
83 DependencyScanningFilesystemSharedCache SharedCache
;
84 DependencyScanningWorkerFilesystem
DepFS(SharedCache
, InMemoryFS
);
88 DepFS
.status("/foo.c");
90 llvm::SmallString
<128> Result
;
91 DepFS
.getRealPath("/foo.c", Result
);
94 llvm::SmallString
<128> Result
;
95 DepFS
.getRealPath("/bar.c", Result
);
97 DepFS
.status("/bar.c");
102 DepFS
.status("/foo.m");
104 llvm::SmallString
<128> Result
;
105 DepFS
.getRealPath("/foo.m", Result
);
108 llvm::SmallString
<128> Result
;
109 DepFS
.getRealPath("/bar.m", Result
);
111 DepFS
.status("/bar.m");
114 // Failure without caching.
116 DepFS
.status("/foo");
118 llvm::SmallString
<128> Result
;
119 DepFS
.getRealPath("/foo", Result
);
122 llvm::SmallString
<128> Result
;
123 DepFS
.getRealPath("/bar", Result
);
125 DepFS
.status("/bar");
129 TEST(DependencyScanningFilesystem
, CacheStatOnExists
) {
130 auto InMemoryFS
= llvm::makeIntrusiveRefCnt
<llvm::vfs::InMemoryFileSystem
>();
131 auto InstrumentingFS
=
132 llvm::makeIntrusiveRefCnt
<llvm::vfs::TracingFileSystem
>(InMemoryFS
);
133 InMemoryFS
->setCurrentWorkingDirectory("/");
134 InMemoryFS
->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer(""));
135 InMemoryFS
->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer(""));
136 DependencyScanningFilesystemSharedCache SharedCache
;
137 DependencyScanningWorkerFilesystem
DepFS(SharedCache
, InstrumentingFS
);
139 DepFS
.status("/foo");
140 DepFS
.status("/foo");
141 DepFS
.status("/bar");
142 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 2u);
144 DepFS
.exists("/foo");
145 DepFS
.exists("/bar");
146 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 2u);
147 EXPECT_EQ(InstrumentingFS
->NumExistsCalls
, 0u);
150 TEST(DependencyScanningFilesystem
, CacheStatFailures
) {
151 auto InMemoryFS
= llvm::makeIntrusiveRefCnt
<llvm::vfs::InMemoryFileSystem
>();
152 InMemoryFS
->setCurrentWorkingDirectory("/");
153 InMemoryFS
->addFile("/dir/vector", 0, llvm::MemoryBuffer::getMemBuffer(""));
154 InMemoryFS
->addFile("/cache/a.pcm", 0, llvm::MemoryBuffer::getMemBuffer(""));
156 auto InstrumentingFS
=
157 llvm::makeIntrusiveRefCnt
<llvm::vfs::TracingFileSystem
>(InMemoryFS
);
159 DependencyScanningFilesystemSharedCache SharedCache
;
160 DependencyScanningWorkerFilesystem
DepFS(SharedCache
, InstrumentingFS
);
162 DepFS
.status("/dir");
163 DepFS
.status("/dir");
164 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 1u);
166 DepFS
.status("/dir/vector");
167 DepFS
.status("/dir/vector");
168 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 2u);
170 DepFS
.setBypassedPathPrefix("/cache");
171 DepFS
.exists("/cache/a.pcm");
172 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 3u);
173 DepFS
.exists("/cache/a.pcm");
174 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 4u);
176 DepFS
.resetBypassedPathPrefix();
177 DepFS
.exists("/cache/a.pcm");
178 DepFS
.exists("/cache/a.pcm");
179 EXPECT_EQ(InstrumentingFS
->NumStatusCalls
, 5u);