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