xref: /llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp (revision 92cd66d905aa63fe4d77bb632812dff87e0e1c08)
1 //===- DependencyScanningFilesystemTest.cpp -------------------------------===//
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 "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/Support/VirtualFileSystem.h"
12 #include "gtest/gtest.h"
13 
14 using namespace clang::tooling::dependencies;
15 
16 TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) {
17   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
18 
19   auto InstrumentingFS =
20       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
21 
22   DependencyScanningFilesystemSharedCache SharedCache;
23   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
24   DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS);
25 
26   DepFS.status("/foo.c");
27   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u);
28 
29   DepFS.status("/foo.c");
30   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u); // Cached, no increase.
31 
32   DepFS.status("/bar.c");
33   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
34 
35   DepFS2.status("/foo.c");
36   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u); // Shared cache.
37 }
38 
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(""));
44 
45   auto InstrumentingFS =
46       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
47 
48   DependencyScanningFilesystemSharedCache SharedCache;
49   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
50   DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS);
51 
52   {
53     llvm::SmallString<128> Result;
54     DepFS.getRealPath("/foo", Result);
55     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 1u);
56   }
57 
58   {
59     llvm::SmallString<128> Result;
60     DepFS.getRealPath("/foo", Result);
61     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 1u); // Cached, no increase.
62   }
63 
64   {
65     llvm::SmallString<128> Result;
66     DepFS.getRealPath("/bar", Result);
67     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 2u);
68   }
69 
70   {
71     llvm::SmallString<128> Result;
72     DepFS2.getRealPath("/foo", Result);
73     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 2u); // Shared cache.
74   }
75 }
76 
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(""));
82 
83   DependencyScanningFilesystemSharedCache SharedCache;
84   DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS);
85 
86   // Success.
87   {
88     DepFS.status("/foo.c");
89 
90     llvm::SmallString<128> Result;
91     DepFS.getRealPath("/foo.c", Result);
92   }
93   {
94     llvm::SmallString<128> Result;
95     DepFS.getRealPath("/bar.c", Result);
96 
97     DepFS.status("/bar.c");
98   }
99 
100   // Failure.
101   {
102     DepFS.status("/foo.m");
103 
104     llvm::SmallString<128> Result;
105     DepFS.getRealPath("/foo.m", Result);
106   }
107   {
108     llvm::SmallString<128> Result;
109     DepFS.getRealPath("/bar.m", Result);
110 
111     DepFS.status("/bar.m");
112   }
113 
114   // Failure without caching.
115   {
116     DepFS.status("/foo");
117 
118     llvm::SmallString<128> Result;
119     DepFS.getRealPath("/foo", Result);
120   }
121   {
122     llvm::SmallString<128> Result;
123     DepFS.getRealPath("/bar", Result);
124 
125     DepFS.status("/bar");
126   }
127 }
128 
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);
138 
139   DepFS.status("/foo");
140   DepFS.status("/foo");
141   DepFS.status("/bar");
142   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
143 
144   DepFS.exists("/foo");
145   DepFS.exists("/bar");
146   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
147   EXPECT_EQ(InstrumentingFS->NumExistsCalls, 0u);
148 }
149 
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(""));
155 
156   auto InstrumentingFS =
157       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
158 
159   DependencyScanningFilesystemSharedCache SharedCache;
160   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
161 
162   DepFS.status("/dir");
163   DepFS.status("/dir");
164   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u);
165 
166   DepFS.status("/dir/vector");
167   DepFS.status("/dir/vector");
168   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
169 
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);
175 
176   DepFS.resetBypassedPathPrefix();
177   DepFS.exists("/cache/a.pcm");
178   DepFS.exists("/cache/a.pcm");
179   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 5u);
180 }
181