xref: /llvm-project/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp (revision 92cd66d905aa63fe4d77bb632812dff87e0e1c08)
1a11a4324SJan Svoboda //===- DependencyScanningFilesystemTest.cpp -------------------------------===//
2a11a4324SJan Svoboda //
3a11a4324SJan Svoboda // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a11a4324SJan Svoboda // See https://llvm.org/LICENSE.txt for license information.
5a11a4324SJan Svoboda // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a11a4324SJan Svoboda //
7a11a4324SJan Svoboda //===----------------------------------------------------------------------===//
8a11a4324SJan Svoboda 
9a11a4324SJan Svoboda #include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
10a11a4324SJan Svoboda #include "llvm/ADT/SmallString.h"
11a11a4324SJan Svoboda #include "llvm/Support/VirtualFileSystem.h"
12a11a4324SJan Svoboda #include "gtest/gtest.h"
13a11a4324SJan Svoboda 
14a11a4324SJan Svoboda using namespace clang::tooling::dependencies;
15a11a4324SJan Svoboda 
16a11a4324SJan Svoboda TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) {
17a11a4324SJan Svoboda   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
18a11a4324SJan Svoboda 
19a11a4324SJan Svoboda   auto InstrumentingFS =
2070fcdb3dSJan Svoboda       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
21a11a4324SJan Svoboda 
22a11a4324SJan Svoboda   DependencyScanningFilesystemSharedCache SharedCache;
23a11a4324SJan Svoboda   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
24a11a4324SJan Svoboda   DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS);
25a11a4324SJan Svoboda 
26a11a4324SJan Svoboda   DepFS.status("/foo.c");
27a11a4324SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u);
28a11a4324SJan Svoboda 
29a11a4324SJan Svoboda   DepFS.status("/foo.c");
30a11a4324SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u); // Cached, no increase.
31a11a4324SJan Svoboda 
32a11a4324SJan Svoboda   DepFS.status("/bar.c");
33a11a4324SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
34a11a4324SJan Svoboda 
35a11a4324SJan Svoboda   DepFS2.status("/foo.c");
36a11a4324SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u); // Shared cache.
37a11a4324SJan Svoboda }
38a11a4324SJan Svoboda 
39a11a4324SJan Svoboda TEST(DependencyScanningFilesystem, CacheGetRealPath) {
40a11a4324SJan Svoboda   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
41a11a4324SJan Svoboda   InMemoryFS->setCurrentWorkingDirectory("/");
42a11a4324SJan Svoboda   InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer(""));
43a11a4324SJan Svoboda   InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer(""));
44a11a4324SJan Svoboda 
45a11a4324SJan Svoboda   auto InstrumentingFS =
4670fcdb3dSJan Svoboda       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
47a11a4324SJan Svoboda 
48a11a4324SJan Svoboda   DependencyScanningFilesystemSharedCache SharedCache;
49a11a4324SJan Svoboda   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
50a11a4324SJan Svoboda   DependencyScanningWorkerFilesystem DepFS2(SharedCache, InstrumentingFS);
51a11a4324SJan Svoboda 
52a11a4324SJan Svoboda   {
53a11a4324SJan Svoboda     llvm::SmallString<128> Result;
54a11a4324SJan Svoboda     DepFS.getRealPath("/foo", Result);
55a11a4324SJan Svoboda     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 1u);
56a11a4324SJan Svoboda   }
57a11a4324SJan Svoboda 
58a11a4324SJan Svoboda   {
59a11a4324SJan Svoboda     llvm::SmallString<128> Result;
60a11a4324SJan Svoboda     DepFS.getRealPath("/foo", Result);
61a11a4324SJan Svoboda     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 1u); // Cached, no increase.
62a11a4324SJan Svoboda   }
63a11a4324SJan Svoboda 
64a11a4324SJan Svoboda   {
65a11a4324SJan Svoboda     llvm::SmallString<128> Result;
66a11a4324SJan Svoboda     DepFS.getRealPath("/bar", Result);
67a11a4324SJan Svoboda     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 2u);
68a11a4324SJan Svoboda   }
69a11a4324SJan Svoboda 
70a11a4324SJan Svoboda   {
71a11a4324SJan Svoboda     llvm::SmallString<128> Result;
72a11a4324SJan Svoboda     DepFS2.getRealPath("/foo", Result);
73a11a4324SJan Svoboda     EXPECT_EQ(InstrumentingFS->NumGetRealPathCalls, 2u); // Shared cache.
74a11a4324SJan Svoboda   }
75a11a4324SJan Svoboda }
76a11a4324SJan Svoboda 
77a11a4324SJan Svoboda TEST(DependencyScanningFilesystem, RealPathAndStatusInvariants) {
78a11a4324SJan Svoboda   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
79a11a4324SJan Svoboda   InMemoryFS->setCurrentWorkingDirectory("/");
80a11a4324SJan Svoboda   InMemoryFS->addFile("/foo.c", 0, llvm::MemoryBuffer::getMemBuffer(""));
81a11a4324SJan Svoboda   InMemoryFS->addFile("/bar.c", 0, llvm::MemoryBuffer::getMemBuffer(""));
82a11a4324SJan Svoboda 
83a11a4324SJan Svoboda   DependencyScanningFilesystemSharedCache SharedCache;
84a9111d4aSJan Svoboda   DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS);
85a11a4324SJan Svoboda 
86a11a4324SJan Svoboda   // Success.
87a11a4324SJan Svoboda   {
88a11a4324SJan Svoboda     DepFS.status("/foo.c");
89a11a4324SJan Svoboda 
90a11a4324SJan Svoboda     llvm::SmallString<128> Result;
91a11a4324SJan Svoboda     DepFS.getRealPath("/foo.c", Result);
92a11a4324SJan Svoboda   }
93a11a4324SJan Svoboda   {
94a11a4324SJan Svoboda     llvm::SmallString<128> Result;
95a11a4324SJan Svoboda     DepFS.getRealPath("/bar.c", Result);
96a11a4324SJan Svoboda 
97a11a4324SJan Svoboda     DepFS.status("/bar.c");
98a11a4324SJan Svoboda   }
99a11a4324SJan Svoboda 
100a11a4324SJan Svoboda   // Failure.
101a11a4324SJan Svoboda   {
102a11a4324SJan Svoboda     DepFS.status("/foo.m");
103a11a4324SJan Svoboda 
104a11a4324SJan Svoboda     llvm::SmallString<128> Result;
105a11a4324SJan Svoboda     DepFS.getRealPath("/foo.m", Result);
106a11a4324SJan Svoboda   }
107a11a4324SJan Svoboda   {
108a11a4324SJan Svoboda     llvm::SmallString<128> Result;
109a11a4324SJan Svoboda     DepFS.getRealPath("/bar.m", Result);
110a11a4324SJan Svoboda 
111a11a4324SJan Svoboda     DepFS.status("/bar.m");
112a11a4324SJan Svoboda   }
113a11a4324SJan Svoboda 
114a11a4324SJan Svoboda   // Failure without caching.
115a11a4324SJan Svoboda   {
116a11a4324SJan Svoboda     DepFS.status("/foo");
117a11a4324SJan Svoboda 
118a11a4324SJan Svoboda     llvm::SmallString<128> Result;
119a11a4324SJan Svoboda     DepFS.getRealPath("/foo", Result);
120a11a4324SJan Svoboda   }
121a11a4324SJan Svoboda   {
122a11a4324SJan Svoboda     llvm::SmallString<128> Result;
123a11a4324SJan Svoboda     DepFS.getRealPath("/bar", Result);
124a11a4324SJan Svoboda 
125a11a4324SJan Svoboda     DepFS.status("/bar");
126a11a4324SJan Svoboda   }
127a11a4324SJan Svoboda }
128779ba604SArtem Chikin 
129779ba604SArtem Chikin TEST(DependencyScanningFilesystem, CacheStatOnExists) {
130779ba604SArtem Chikin   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
131779ba604SArtem Chikin   auto InstrumentingFS =
13270fcdb3dSJan Svoboda       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
133779ba604SArtem Chikin   InMemoryFS->setCurrentWorkingDirectory("/");
134779ba604SArtem Chikin   InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer(""));
135779ba604SArtem Chikin   InMemoryFS->addFile("/bar", 0, llvm::MemoryBuffer::getMemBuffer(""));
136779ba604SArtem Chikin   DependencyScanningFilesystemSharedCache SharedCache;
137779ba604SArtem Chikin   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
138779ba604SArtem Chikin 
139779ba604SArtem Chikin   DepFS.status("/foo");
140779ba604SArtem Chikin   DepFS.status("/foo");
141779ba604SArtem Chikin   DepFS.status("/bar");
142779ba604SArtem Chikin   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
143779ba604SArtem Chikin 
144779ba604SArtem Chikin   DepFS.exists("/foo");
145779ba604SArtem Chikin   DepFS.exists("/bar");
146779ba604SArtem Chikin   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
147779ba604SArtem Chikin   EXPECT_EQ(InstrumentingFS->NumExistsCalls, 0u);
148779ba604SArtem Chikin }
14955323ca6SJan Svoboda 
15055323ca6SJan Svoboda TEST(DependencyScanningFilesystem, CacheStatFailures) {
15155323ca6SJan Svoboda   auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
15255323ca6SJan Svoboda   InMemoryFS->setCurrentWorkingDirectory("/");
15355323ca6SJan Svoboda   InMemoryFS->addFile("/dir/vector", 0, llvm::MemoryBuffer::getMemBuffer(""));
15455323ca6SJan Svoboda   InMemoryFS->addFile("/cache/a.pcm", 0, llvm::MemoryBuffer::getMemBuffer(""));
15555323ca6SJan Svoboda 
15655323ca6SJan Svoboda   auto InstrumentingFS =
157*92cd66d9SJan Svoboda       llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(InMemoryFS);
15855323ca6SJan Svoboda 
15955323ca6SJan Svoboda   DependencyScanningFilesystemSharedCache SharedCache;
16055323ca6SJan Svoboda   DependencyScanningWorkerFilesystem DepFS(SharedCache, InstrumentingFS);
16155323ca6SJan Svoboda 
16255323ca6SJan Svoboda   DepFS.status("/dir");
16355323ca6SJan Svoboda   DepFS.status("/dir");
16455323ca6SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 1u);
16555323ca6SJan Svoboda 
16655323ca6SJan Svoboda   DepFS.status("/dir/vector");
16755323ca6SJan Svoboda   DepFS.status("/dir/vector");
16855323ca6SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 2u);
16955323ca6SJan Svoboda 
17055323ca6SJan Svoboda   DepFS.setBypassedPathPrefix("/cache");
17155323ca6SJan Svoboda   DepFS.exists("/cache/a.pcm");
17255323ca6SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 3u);
17355323ca6SJan Svoboda   DepFS.exists("/cache/a.pcm");
17455323ca6SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 4u);
17555323ca6SJan Svoboda 
17655323ca6SJan Svoboda   DepFS.resetBypassedPathPrefix();
17755323ca6SJan Svoboda   DepFS.exists("/cache/a.pcm");
17855323ca6SJan Svoboda   DepFS.exists("/cache/a.pcm");
17955323ca6SJan Svoboda   EXPECT_EQ(InstrumentingFS->NumStatusCalls, 5u);
18055323ca6SJan Svoboda }
181