// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "blob-cache.h"

#include <zxtest/zxtest.h>

#include "cache-node.h"
#include "utils.h"

namespace blobfs {
namespace {

// A mock Node, comparable to Blob.
//
// "ShouldCache" mimics the internal Vnode state machine.
// "UsingMemory" mimics the storage of pages and mappings, which may be evicted
// from memory when references are closed.
class TestNode : public CacheNode, fbl::Recyclable<TestNode> {
 public:
  explicit TestNode(const Digest& digest, BlobCache* cache) : CacheNode(digest), cache_(cache) {}

  void fbl_recycle() final { CacheNode::fbl_recycle(); }

  BlobCache& Cache() final { return *cache_; }

  bool ShouldCache() const final { return should_cache_; }

  void ActivateLowMemory() final { using_memory_ = false; }

  bool UsingMemory() { return using_memory_; }

  void SetCache(bool should_cache) { should_cache_ = should_cache; }

  void SetHighMemory() { using_memory_ = true; }

  fs::VnodeProtocolSet GetProtocols() const final { return fs::VnodeProtocol::kFile; }

  zx_status_t GetNodeInfoForProtocol(fs::VnodeProtocol protocol, fs::Rights rights,
                                     fs::VnodeRepresentation* representation) {
    *representation = fs::VnodeRepresentation::File();
    return ZX_OK;
  }

 private:
  BlobCache* cache_;
  bool should_cache_ = true;
  bool using_memory_ = false;
};

Digest GenerateDigest(size_t seed) {
  Digest digest;
  digest.Init();
  digest.Update(&seed, sizeof(seed));
  digest.Final();
  return digest;
}

void CheckNothingOpenHelper(BlobCache* cache) {
  ASSERT_TRUE(cache);
  cache->ForAllOpenNodes([](fbl::RefPtr<CacheNode>) { ZX_ASSERT(false); });
}

TEST(BlobCacheTest, Null) {
  BlobCache cache;

  ASSERT_NO_FAILURES(CheckNothingOpenHelper(&cache));
  cache.Reset();
  ASSERT_NO_FAILURES(CheckNothingOpenHelper(&cache));

  Digest digest = GenerateDigest(0);
  fbl::RefPtr<CacheNode> missing_node;
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, &missing_node));
  fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Evict(node));
  node->SetCache(false);
}

TEST(BlobCacheTest, AddLookupEvict) {
  // Add a node to the cache.
  BlobCache cache;
  Digest digest = GenerateDigest(0);
  fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
  ASSERT_OK(cache.Add(node));
  ASSERT_EQ(ZX_ERR_ALREADY_EXISTS, cache.Add(node));

  // Observe that we can access the node inside the cache.
  fbl::RefPtr<CacheNode> found_node;
  ASSERT_OK(cache.Lookup(digest, nullptr));
  ASSERT_OK(cache.Lookup(digest, &found_node));
  ASSERT_EQ(found_node.get(), node.get());

  // Observe that evicting the node removes it from the cache.
  ASSERT_OK(cache.Evict(node));
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

// ShouldCache = false, Evicted = false.
//
// This results in the node being deleted from the cache.
TEST(BlobCacheTest, StopCaching) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);
  // The node is also deleted if we stop caching it, instead of just evicting.
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    ASSERT_OK(cache.Add(node));
    ASSERT_OK(cache.Lookup(digest, nullptr));
    node->SetCache(false);
  }
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

// ShouldCache = false, Evicted = True.
//
// This results in the node being deleted from the cache.
TEST(BlobCacheTest, EvictNoCache) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);
  // The node is also deleted if we stop caching it, instead of just evicting.
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    ASSERT_OK(cache.Add(node));
    ASSERT_OK(cache.Lookup(digest, nullptr));
    ASSERT_OK(cache.Evict(node));
  }
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

// ShouldCache = true, Evicted = true.
//
// This results in the node being deleted from the cache.
TEST(BlobCacheTest, EvictWhileCaching) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);
  // The node is automatically deleted if it wants to be cached, but has been
  // evicted.
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    ASSERT_OK(cache.Add(node));
    ASSERT_OK(cache.Lookup(digest, nullptr));
    ASSERT_OK(cache.Evict(node));
    node->SetCache(true);
  }
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

// This helper function only operates correctly when a single node is open in the cache.
void CheckExistsAloneInOpenCache(BlobCache* cache, void* node_ptr) {
  ASSERT_TRUE(cache);
  size_t node_count = 0;
  cache->ForAllOpenNodes([&node_count, &node_ptr](fbl::RefPtr<CacheNode> node) {
    node_count++;
    ZX_ASSERT(node.get() == node_ptr);
  });
  ASSERT_EQ(1, node_count);
}

TEST(BlobCacheTest, CacheAfterRecycle) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);
  void* node_ptr = nullptr;

  // Add a node to the cache.
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    node_ptr = node.get();
    ASSERT_OK(cache.Add(node));
    ASSERT_OK(cache.Lookup(digest, nullptr));

    // Observe the node is in the set of open nodes.
    ASSERT_NO_FAILURES(CheckExistsAloneInOpenCache(&cache, node_ptr));
  }

  // Observe the node is in no longer in the set of open nodes, now that it has
  // run out of strong references.
  ASSERT_NO_FAILURES(CheckNothingOpenHelper(&cache));

  // Observe that although the node in in the "closed set", it still exists in the cache,
  // and can be re-acquired.
  ASSERT_OK(cache.Lookup(digest, nullptr));

  // Letting the node go out of scope puts it back in the cache.
  {
    fbl::RefPtr<CacheNode> node;
    ASSERT_OK(cache.Lookup(digest, &node));
    ASSERT_EQ(node_ptr, node.get());
    ASSERT_NO_FAILURES(CheckExistsAloneInOpenCache(&cache, node_ptr));
  }
  ASSERT_OK(cache.Lookup(digest, nullptr));

  // However, if we stop caching the node, it will be deleted when all references
  // go out of scope.
  {
    fbl::RefPtr<CacheNode> cache_node;
    ASSERT_OK(cache.Lookup(digest, &cache_node));
    auto vnode = fbl::RefPtr<TestNode>::Downcast(std::move(cache_node));
    ASSERT_OK(cache.Evict(vnode));
  }
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

TEST(BlobCacheTest, ResetClosed) {
  BlobCache cache;
  // Create a node which exists in the closed cache.
  Digest digest = GenerateDigest(0);
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    ASSERT_OK(cache.Add(node));
  }
  ASSERT_OK(cache.Lookup(digest, nullptr));

  // After resetting, the node should no longer exist.
  cache.Reset();
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

TEST(BlobCacheTest, ResetOpen) {
  BlobCache cache;
  // Create a node which exists in the open cache.
  Digest digest = GenerateDigest(0);
  fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
  ASSERT_OK(cache.Add(node));

  // After resetting, the node should no longer exist.
  cache.Reset();
  ASSERT_EQ(ZX_ERR_NOT_FOUND, cache.Lookup(digest, nullptr));
}

TEST(BlobCacheTest, Destructor) {
  fbl::RefPtr<TestNode> open_node;

  {
    BlobCache cache;
    Digest open_digest = GenerateDigest(0);
    open_node = fbl::AdoptRef(new TestNode(open_digest, &cache));
    open_node->SetHighMemory();

    Digest closed_digest = GenerateDigest(1);
    auto closed_node = fbl::AdoptRef(new TestNode(closed_digest, &cache));
    ASSERT_OK(cache.Add(open_node));
    ASSERT_OK(cache.Add(closed_node));
  }
  ASSERT_TRUE(open_node->UsingMemory());
}

TEST(BlobCacheTest, ForAllOpenNodes) {
  BlobCache cache;

  // Add a bunch of open nodes to the cache.
  fbl::RefPtr<TestNode> open_nodes[10];
  for (size_t i = 0; i < fbl::count_of(open_nodes); i++) {
    open_nodes[i] = fbl::AdoptRef(new TestNode(GenerateDigest(i), &cache));
    ASSERT_OK(cache.Add(open_nodes[i]));
  }

  // For fun, add some nodes to the cache which will become non-open:
  // One which runs out of strong references, and another which is evicted.
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(GenerateDigest(0xDEAD), &cache));
    ASSERT_OK(cache.Add(node));
  }
  fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(GenerateDigest(0xBEEF), &cache));
  ASSERT_OK(cache.Add(node));
  ASSERT_OK(cache.Evict(node));

  // Double check that the nodes which should be open are open, and that the nodes
  // which aren't open aren't visible.
  size_t node_index = 0;
  cache.ForAllOpenNodes([&open_nodes, &node_index](fbl::RefPtr<CacheNode> node) {
    ZX_ASSERT(node_index < fbl::count_of(open_nodes));
    for (size_t i = 0; i < fbl::count_of(open_nodes); i++) {
      // We should be able to find this node in the set of open nodes -- but only once.
      if (open_nodes[i] && open_nodes[i].get() == node.get()) {
        open_nodes[i] = nullptr;
        node_index++;
        return;
      }
    }
    ZX_ASSERT_MSG(false, "Found open node not contained in expected open set");
  });
  ASSERT_EQ(fbl::count_of(open_nodes), node_index);
}

TEST(BlobCacheTest, CachePolicyEvictImmediately) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);

  cache.SetCachePolicy(CachePolicy::EvictImmediately);
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    node->SetHighMemory();
    ASSERT_OK(cache.Add(node));
    ASSERT_TRUE(node->UsingMemory());
  }

  fbl::RefPtr<CacheNode> cache_node;
  ASSERT_OK(cache.Lookup(digest, &cache_node));
  auto node = fbl::RefPtr<TestNode>::Downcast(std::move(cache_node));
  ASSERT_FALSE(node->UsingMemory());
}

TEST(BlobCacheTest, CachePolicyNeverEvict) {
  BlobCache cache;
  Digest digest = GenerateDigest(0);

  cache.SetCachePolicy(CachePolicy::NeverEvict);
  {
    fbl::RefPtr<TestNode> node = fbl::AdoptRef(new TestNode(digest, &cache));
    node->SetHighMemory();
    ASSERT_OK(cache.Add(node));
    ASSERT_TRUE(node->UsingMemory());
  }

  fbl::RefPtr<CacheNode> cache_node;
  ASSERT_OK(cache.Lookup(digest, &cache_node));
  auto node = fbl::RefPtr<TestNode>::Downcast(std::move(cache_node));
  ASSERT_TRUE(node->UsingMemory());
}

}  // namespace
}  // namespace blobfs
