diff options
Diffstat (limited to 'clang-tools-extra/unittests/clangd')
-rw-r--r-- | clang-tools-extra/unittests/clangd/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/ClangdTests.cpp | 65 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/FSTests.cpp | 46 | ||||
-rw-r--r-- | clang-tools-extra/unittests/clangd/TestFS.cpp | 1 |
4 files changed, 113 insertions, 0 deletions
diff --git a/clang-tools-extra/unittests/clangd/CMakeLists.txt b/clang-tools-extra/unittests/clangd/CMakeLists.txt index a870c2990a9..1c98347be55 100644 --- a/clang-tools-extra/unittests/clangd/CMakeLists.txt +++ b/clang-tools-extra/unittests/clangd/CMakeLists.txt @@ -21,6 +21,7 @@ add_extra_unittest(ClangdTests FileDistanceTests.cpp FileIndexTests.cpp FindSymbolsTests.cpp + FSTests.cpp FuzzyMatchTests.cpp GlobalCompilationDatabaseTests.cpp HeadersTests.cpp diff --git a/clang-tools-extra/unittests/clangd/ClangdTests.cpp b/clang-tools-extra/unittests/clangd/ClangdTests.cpp index ace2cef4b45..21300e906c8 100644 --- a/clang-tools-extra/unittests/clangd/ClangdTests.cpp +++ b/clang-tools-extra/unittests/clangd/ClangdTests.cpp @@ -963,6 +963,71 @@ TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) { Field(&CodeCompletion::Name, "baz"))); } +// Check that running code completion doesn't stat() a bunch of files from the +// preamble again. (They should be using the preamble's stat-cache) +TEST(ClangdTests, PreambleVFSStatCache) { + class ListenStatsFSProvider : public FileSystemProvider { + public: + ListenStatsFSProvider(llvm::StringMap<unsigned> &CountStats) + : CountStats(CountStats) {} + + IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() override { + class ListenStatVFS : public vfs::ProxyFileSystem { + public: + ListenStatVFS(IntrusiveRefCntPtr<vfs::FileSystem> FS, + llvm::StringMap<unsigned> &CountStats) + : ProxyFileSystem(std::move(FS)), CountStats(CountStats) {} + + llvm::ErrorOr<std::unique_ptr<vfs::File>> + openFileForRead(const Twine &Path) override { + ++CountStats[llvm::sys::path::filename(Path.str())]; + return ProxyFileSystem::openFileForRead(Path); + } + llvm::ErrorOr<vfs::Status> status(const Twine &Path) override { + ++CountStats[llvm::sys::path::filename(Path.str())]; + return ProxyFileSystem::status(Path); + } + + private: + llvm::StringMap<unsigned> &CountStats; + }; + + return IntrusiveRefCntPtr<ListenStatVFS>( + new ListenStatVFS(buildTestFS(Files), CountStats)); + } + + // If relative paths are used, they are resolved with testPath(). + llvm::StringMap<std::string> Files; + llvm::StringMap<unsigned> &CountStats; + }; + + llvm::StringMap<unsigned> CountStats; + ListenStatsFSProvider FS(CountStats); + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto SourcePath = testPath("foo.cpp"); + auto HeaderPath = testPath("foo.h"); + FS.Files[HeaderPath] = "struct TestSym {};"; + Annotations Code(R"cpp( + #include "foo.h" + + int main() { + TestSy^ + })cpp"); + + runAddDocument(Server, SourcePath, Code.code()); + + EXPECT_EQ(CountStats["foo.h"], 1u); + auto Completions = cantFail(runCodeComplete(Server, SourcePath, Code.point(), + clangd::CodeCompleteOptions())) + .Completions; + EXPECT_EQ(CountStats["foo.h"], 1u); + EXPECT_THAT(Completions, + ElementsAre(Field(&CodeCompletion::Name, "TestSym"))); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/unittests/clangd/FSTests.cpp b/clang-tools-extra/unittests/clangd/FSTests.cpp new file mode 100644 index 00000000000..3b028426016 --- /dev/null +++ b/clang-tools-extra/unittests/clangd/FSTests.cpp @@ -0,0 +1,46 @@ +//===-- FSTests.cpp - File system related tests -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "FS.h" +#include "TestFS.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { + +TEST(FSTests, PreambleStatusCache) { + llvm::StringMap<std::string> Files; + Files["x"] = ""; + Files["y"] = ""; + auto FS = buildTestFS(Files); + FS->setCurrentWorkingDirectory(testRoot()); + + PreambleFileStatusCache StatCache; + auto ProduceFS = StatCache.getProducingFS(FS); + EXPECT_TRUE(ProduceFS->openFileForRead("x")); + EXPECT_TRUE(ProduceFS->status("y")); + + EXPECT_TRUE(StatCache.lookup(testPath("x")).hasValue()); + EXPECT_TRUE(StatCache.lookup(testPath("y")).hasValue()); + + vfs::Status S("fake", llvm::sys::fs::UniqueID(0, 0), + std::chrono::system_clock::now(), 0, 0, 1024, + llvm::sys::fs::file_type::regular_file, llvm::sys::fs::all_all); + StatCache.update(*FS, S); + auto ConsumeFS = StatCache.getConsumingFS(FS); + auto Cached = ConsumeFS->status(testPath("fake")); + EXPECT_TRUE(Cached); + EXPECT_EQ(Cached->getName(), S.getName()); +} + +} // namespace +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/unittests/clangd/TestFS.cpp b/clang-tools-extra/unittests/clangd/TestFS.cpp index d3112b92278..bc8c5479a93 100644 --- a/clang-tools-extra/unittests/clangd/TestFS.cpp +++ b/clang-tools-extra/unittests/clangd/TestFS.cpp @@ -23,6 +23,7 @@ buildTestFS(llvm::StringMap<std::string> const &Files, llvm::StringMap<time_t> const &Timestamps) { IntrusiveRefCntPtr<vfs::InMemoryFileSystem> MemFS( new vfs::InMemoryFileSystem); + MemFS->setCurrentWorkingDirectory(testRoot()); for (auto &FileAndContents : Files) { StringRef File = FileAndContents.first(); MemFS->addFile( |