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