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