1 //===-- FileCacheTests.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 "support/FileCache.h" 10 11 #include "TestFS.h" 12 #include "gmock/gmock.h" 13 #include "gtest/gtest.h" 14 #include <atomic> 15 #include <chrono> 16 17 namespace clang { 18 namespace clangd { 19 namespace config { 20 namespace { 21 22 class TestCache : public FileCache { 23 MockFS FS; 24 mutable std::string Value; 25 26 public: 27 TestCache() : FileCache(testPath("foo.cc")) {} 28 29 void setContents(const char *C) { 30 if (C) 31 FS.Files[testPath("foo.cc")] = C; 32 else 33 FS.Files.erase(testPath("foo.cc")); 34 } 35 36 std::string get(std::chrono::steady_clock::time_point FreshTime, 37 bool ExpectParse) const { 38 bool GotParse = false; 39 bool GotRead; 40 std::string Result; 41 read( 42 FS, FreshTime, 43 [&](llvm::Optional<llvm::StringRef> Data) { 44 GotParse = true; 45 Value = Data.value_or("").str(); 46 }, 47 [&]() { 48 GotRead = true; 49 Result = Value; 50 }); 51 EXPECT_EQ(GotParse, ExpectParse); 52 EXPECT_TRUE(GotRead); 53 return Result; 54 } 55 }; 56 57 TEST(FileCacheTest, Invalidation) { 58 TestCache C; 59 60 auto StaleOK = std::chrono::steady_clock::now(); 61 auto MustBeFresh = StaleOK + std::chrono::hours(1); 62 63 C.setContents("a"); 64 EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/true)) << "Parsed first time"; 65 EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; 66 EXPECT_EQ("a", C.get(MustBeFresh, /*ExpectParse=*/false)) << "Cached (stat)"; 67 C.setContents("bb"); 68 EXPECT_EQ("a", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; 69 EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Size changed"; 70 EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Cached (stat)"; 71 C.setContents(nullptr); 72 EXPECT_EQ("bb", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; 73 EXPECT_EQ("", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Stat failed"; 74 EXPECT_EQ("", C.get(MustBeFresh, /*ExpectParse=*/false)) << "Cached (404)"; 75 C.setContents("bb"); // Match the previous stat values! 76 EXPECT_EQ("", C.get(StaleOK, /*ExpectParse=*/false)) << "Cached (time)"; 77 EXPECT_EQ("bb", C.get(MustBeFresh, /*ExpectParse=*/true)) << "Size changed"; 78 } 79 80 } // namespace 81 } // namespace config 82 } // namespace clangd 83 } // namespace clang 84