xref: /llvm-project/clang-tools-extra/clangd/unittests/support/FileCacheTests.cpp (revision e26dad0a661e055076002d0de4ceb713b8ca6917)
1d95db169SSam McCall //===-- FileCacheTests.cpp ------------------------------------------------===//
2d95db169SSam McCall //
3d95db169SSam McCall // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d95db169SSam McCall // See https://llvm.org/LICENSE.txt for license information.
5d95db169SSam McCall // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d95db169SSam McCall //
7d95db169SSam McCall //===----------------------------------------------------------------------===//
8d95db169SSam McCall 
9d95db169SSam McCall #include "support/FileCache.h"
10d95db169SSam McCall 
11d95db169SSam McCall #include "TestFS.h"
12d95db169SSam McCall #include "gmock/gmock.h"
13d95db169SSam McCall #include "gtest/gtest.h"
14d95db169SSam McCall #include <chrono>
1571f55735SKazu Hirata #include <optional>
16*e26dad0aSKadir Cetinkaya #include <utility>
17d95db169SSam McCall 
18d95db169SSam McCall namespace clang {
19d95db169SSam McCall namespace clangd {
20d95db169SSam McCall namespace config {
21d95db169SSam McCall namespace {
22d95db169SSam McCall 
23d95db169SSam McCall class TestCache : public FileCache {
24d95db169SSam McCall   MockFS FS;
25d95db169SSam McCall   mutable std::string Value;
26d95db169SSam McCall 
27d95db169SSam McCall public:
TestCache()28d95db169SSam McCall   TestCache() : FileCache(testPath("foo.cc")) {}
29d95db169SSam McCall 
setContents(const char * C)30d95db169SSam McCall   void setContents(const char *C) {
31d95db169SSam McCall     if (C)
32d95db169SSam McCall       FS.Files[testPath("foo.cc")] = C;
33d95db169SSam McCall     else
34d95db169SSam McCall       FS.Files.erase(testPath("foo.cc"));
35d95db169SSam McCall   }
36d95db169SSam McCall 
37*e26dad0aSKadir Cetinkaya   std::pair<std::string, /*Parsed=*/bool>
get(std::chrono::steady_clock::time_point FreshTime) const38*e26dad0aSKadir Cetinkaya   get(std::chrono::steady_clock::time_point FreshTime) const {
39d95db169SSam McCall     bool GotParse = false;
40*e26dad0aSKadir Cetinkaya     bool GotRead = false;
41d95db169SSam McCall     std::string Result;
42d95db169SSam McCall     read(
43d95db169SSam McCall         FS, FreshTime,
44f71ffd3bSKazu Hirata         [&](std::optional<llvm::StringRef> Data) {
45d95db169SSam McCall           GotParse = true;
4667854f9eSFangrui Song           Value = Data.value_or("").str();
47d95db169SSam McCall         },
48d95db169SSam McCall         [&]() {
49d95db169SSam McCall           GotRead = true;
50d95db169SSam McCall           Result = Value;
51d95db169SSam McCall         });
52d95db169SSam McCall     EXPECT_TRUE(GotRead);
53*e26dad0aSKadir Cetinkaya     return {Result, GotParse};
54d95db169SSam McCall   }
55d95db169SSam McCall };
56d95db169SSam McCall 
57*e26dad0aSKadir Cetinkaya MATCHER_P(Parsed, Value, "") { return arg.second && arg.first == Value; }
58*e26dad0aSKadir Cetinkaya MATCHER_P(Cached, Value, "") { return !arg.second && arg.first == Value; }
59*e26dad0aSKadir Cetinkaya 
TEST(FileCacheTest,Invalidation)60d95db169SSam McCall TEST(FileCacheTest, Invalidation) {
61d95db169SSam McCall   TestCache C;
62d95db169SSam McCall 
63d95db169SSam McCall   auto StaleOK = std::chrono::steady_clock::now();
64d95db169SSam McCall   auto MustBeFresh = StaleOK + std::chrono::hours(1);
65d95db169SSam McCall 
66d95db169SSam McCall   C.setContents("a");
67*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(StaleOK), Parsed("a")) << "Parsed first time";
68*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(StaleOK), Cached("a")) << "Cached (time)";
69*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Cached("a")) << "Cached (stat)";
70d95db169SSam McCall   C.setContents("bb");
71*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(StaleOK), Cached("a")) << "Cached (time)";
72*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Parsed("bb")) << "Size changed";
73*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Cached("bb")) << "Cached (stat)";
74d95db169SSam McCall   C.setContents(nullptr);
75*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(StaleOK), Cached("bb")) << "Cached (time)";
76*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Parsed("")) << "stat failed";
77*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Cached("")) << "Cached (404)";
78d95db169SSam McCall   C.setContents("bb"); // Match the previous stat values!
79*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(StaleOK), Cached("")) << "Cached (time)";
80*e26dad0aSKadir Cetinkaya   EXPECT_THAT(C.get(MustBeFresh), Parsed("bb")) << "Size changed";
81d95db169SSam McCall }
82d95db169SSam McCall 
83d95db169SSam McCall } // namespace
84d95db169SSam McCall } // namespace config
85d95db169SSam McCall } // namespace clangd
86d95db169SSam McCall } // namespace clang
87