// Copyright (c) 2019 The Chromium 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 <cinttypes>
#include <cstdlib>
#include <iostream>
#include <map>
#include <memory>
#include <string>

#include "base/at_exit.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "net/base/cache_type.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/disk_cache/backend_cleanup_tracker.h"
#include "net/disk_cache/blockfile/backend_impl.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/disk_cache_fuzzer.pb.h"
#include "net/disk_cache/disk_cache_test_util.h"
#include "net/disk_cache/memory/mem_backend_impl.h"
#include "net/disk_cache/simple/simple_backend_impl.h"
#include "net/disk_cache/simple/simple_file_tracker.h"
#include "net/disk_cache/simple/simple_index.h"
#include "testing/libfuzzer/proto/lpm_interface.h"

// To get a good idea of what a test case is doing, just run the libfuzzer
// target with LPM_DUMP_NATIVE_INPUT=1 prefixed. This will trigger all the
// prints below and will convey exactly what the test case is doing: use this
// instead of trying to print the protobuf as text.

// For code coverage:
// python ./tools/code_coverage/coverage.py disk_cache_lpm_fuzzer       -b
// out/coverage -o out/report       -c 'out/coverage/disk_cache_lpm_fuzzer
// -runs=0 -workers=24  corpus_disk_cache_simple'       -f net/disk_cache

void IOCallback(std::string io_type, int rv);

namespace {
const uint32_t kMaxSizeKB = 128;  // 128KB maximum.
const uint32_t kMaxSize = kMaxSizeKB * 1024;
const uint32_t kMaxEntrySize = kMaxSize * 2;
const uint32_t kNumStreams = 3;  // All caches seem to have 3 streams. TODO do
                                 // other specialized caches have this?
const uint64_t kFirstSavedTime =
    5;  // Totally random number chosen by dice roll. ;)
const uint32_t kMaxNumMillisToWait = 2019;
const int kMaxFdsSimpleCache = 10;

#define IOTYPES_APPLY(F) \
  F(WriteData)           \
  F(ReadData)            \
  F(WriteSparseData)     \
  F(ReadSparseData)      \
  F(DoomAllEntries)      \
  F(DoomEntriesSince)    \
  F(DoomEntriesBetween)  \
  F(GetAvailableRange)   \
  F(DoomKey)

enum class IOType {
#define ENUM_ENTRY(IO_TYPE) IO_TYPE,
  IOTYPES_APPLY(ENUM_ENTRY)
#undef ENUM_ENTRY
};

struct InitGlobals {
  InitGlobals() {
    base::CommandLine::Init(0, nullptr);

    print_comms_ = ::getenv("LPM_DUMP_NATIVE_INPUT");

    // Mark this thread as an IO_THREAD with MOCK_TIME, and ensure that every
    // other thread's time is driven from this thread's MOCK_TIME.
    scoped_task_environment_ = std::make_unique<
        base::test::ScopedTaskEnvironment>(
        base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
        base::test::ScopedTaskEnvironment::NowSource::MAIN_THREAD_MOCK_TIME);

    // Work around for a DCHECK issue: DCHECK(!TimeTicks::Now().is_null())
    // Since MOCK_TIME starts at 0 the starting time is considered null.
    // So make it non-zero.
    scoped_task_environment_->FastForwardBy(
        base::TimeDelta::FromMilliseconds(1));

    // Disable noisy logging as per "libFuzzer in Chrome" documentation:
    // testing/libfuzzer/getting_started.md#Disable-noisy-error-message-logging.
    logging::SetMinLogLevel(logging::LOG_FATAL);

    // Re-using this buffer for write operations may technically be against
    // IOBuffer rules but it shouldn't cause any actual problems.
    buffer_ =
        base::MakeRefCounted<net::IOBuffer>(static_cast<size_t>(kMaxEntrySize));
    CacheTestFillBuffer(buffer_->data(), kMaxEntrySize, false);

#define CREATE_IO_CALLBACK(IO_TYPE) \
  io_callbacks_.push_back(base::BindRepeating(&IOCallback, #IO_TYPE));
    IOTYPES_APPLY(CREATE_IO_CALLBACK)
#undef CREATE_IO_CALLBACK
  }

  // This allows us to mock time for all threads.
  std::unique_ptr<base::test::ScopedTaskEnvironment> scoped_task_environment_;

  // Used as a pre-filled buffer for all writes.
  scoped_refptr<net::IOBuffer> buffer_;

  // Should we print debugging info?
  bool print_comms_;

  // List of IO callbacks. They do nothing (except maybe print) but are used by
  // all async entry operations.
  std::vector<base::RepeatingCallback<void(int)>> io_callbacks_;
};

InitGlobals* init_globals = new InitGlobals();
}  // namespace

class DiskCacheLPMFuzzer {
 public:
  DiskCacheLPMFuzzer() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    cache_path_ = temp_dir_.GetPath();
  }

  ~DiskCacheLPMFuzzer();

  void RunCommands(const disk_cache_fuzzer::FuzzCommands& commands);

 private:
  struct EntryInfo {
    EntryInfo() = default;
    disk_cache::Entry* entry_ptr = nullptr;
    std::unique_ptr<net::TestCompletionCallback> tcb;

    DISALLOW_COPY_AND_ASSIGN(EntryInfo);
  };
  void RunTaskForTest(base::OnceClosure closure);

  // Waits for an entry to be ready. Only should be called if there is a pending
  // callback for this entry; i.e. ei->tcb != nullptr.
  // Also takes the rv that the cache entry creation functions return, and does
  // not wait if rv != net::ERR_IO_PENDING (and would never have called the
  // callback).
  int WaitOnEntry(EntryInfo* ei, int rv = net::ERR_IO_PENDING);

  // Used as a callback for entry-opening backend calls. Will record the entry
  // in the map as usable and will release any entry-specific calls waiting for
  // the entry to be ready.
  void OpenCacheEntryCallback(
      scoped_refptr<base::RefCountedData<disk_cache::EntryWithOpened>>
          entry_result,
      uint64_t entry_id,
      bool async,
      bool set_is_sparse,
      int rv);

  // Waits for the entry to finish opening, in the async case. Then, if the
  // entry is successfully open (callback returns net::OK, or was already
  // successfully opened), check if the entry_ptr == nullptr. If so, the
  // entry has been closed.
  bool IsValidEntry(EntryInfo* ei);

  // Closes any non-nullptr entries in open_cache_entries_.
  void CloseAllRemainingEntries();

  void HandleSetMaxSize(const disk_cache_fuzzer::SetMaxSize&);
  void CreateBackend(
      disk_cache_fuzzer::FuzzCommands::CacheBackend cache_backend,
      uint32_t mask,
      net::CacheType type,
      bool simple_cache_wait_for_index);

  // Places to keep our cache files.
  base::FilePath cache_path_;
  base::ScopedTempDir temp_dir_;

  // Pointers to our backend. Only one of block_impl_, simple_cache_impl_, and
  // mem_cache_ are active at one time.
  std::unique_ptr<disk_cache::Backend> cache_;
  disk_cache::BackendImpl* block_impl_ = nullptr;
  std::unique_ptr<disk_cache::SimpleFileTracker> simple_file_tracker_;
  disk_cache::SimpleBackendImpl* simple_cache_impl_ = nullptr;
  disk_cache::MemBackendImpl* mem_cache_ = nullptr;

  // Maximum size of the cache, that we have currently set.
  uint32_t max_size_ = kMaxSize;

  // This "consistent hash table" keeys track of the keys we've added to the
  // backend so far. This should always be indexed by a "key_id" from a
  // protobuf.
  std::map<uint64_t, std::string> created_cache_entries_;
  // This "consistent hash table" keeps track of all opened entries we have from
  // the backend, and also contains some nullptr's where entries were already
  // closed. This should always be indexed by an "entry_id" from a protobuf.
  // When destructed, we close all entries that are still open in order to avoid
  // memory leaks.
  std::map<uint64_t, EntryInfo> open_cache_entries_;
  // This "consistent hash table" keeps track of all times we have saved, so
  // that we can call backend methods like DoomEntriesSince or
  // DoomEntriesBetween with sane timestamps. This should always be indexed by a
  // "time_id" from a protobuf.
  std::map<uint64_t, base::Time> saved_times_;
  // This "consistent hash table" keeps tack of all the iterators we have open
  // from the backend. This should always be indexed by a "it_id" from a
  // protobuf.
  std::map<uint64_t, std::unique_ptr<disk_cache::Backend::Iterator>>
      open_iterators_;

  // This maps keeps track of the sparsity of each entry, using their pointers.
  // TODO(mpdenton) remove if CreateEntry("Key0"); WriteData("Key0", index = 2,
  // ...); WriteSparseData("Key0", ...); is supposed to be valid.
  // Then we can just use CouldBeSparse before the WriteData.
  std::map<disk_cache::Entry*, bool> sparse_entry_tracker_;
};

#define MAYBE_PRINT               \
  if (init_globals->print_comms_) \
  std::cout

inline base::RepeatingCallback<void(int)> GetIOCallback(IOType iot) {
  return init_globals->io_callbacks_[static_cast<int>(iot)];
}

std::string ToKey(uint64_t key_num) {
  return "Key" + std::to_string(key_num);
}

net::RequestPriority GetRequestPriority(
    disk_cache_fuzzer::RequestPriority lpm_pri) {
  CHECK(net::MINIMUM_PRIORITY <= static_cast<int>(lpm_pri) &&
        static_cast<int>(lpm_pri) <= net::MAXIMUM_PRIORITY);
  return static_cast<net::RequestPriority>(lpm_pri);
}

net::CacheType GetCacheTypeAndPrint(
    disk_cache_fuzzer::FuzzCommands::CacheType type,
    disk_cache_fuzzer::FuzzCommands::CacheBackend backend) {
  switch (type) {
    case disk_cache_fuzzer::FuzzCommands::APP_CACHE:
      MAYBE_PRINT << "Cache type = APP_CACHE." << std::endl;
      return net::CacheType::APP_CACHE;
      break;
    case disk_cache_fuzzer::FuzzCommands::MEDIA_CACHE:
      MAYBE_PRINT << "Cache type = MEDIA_CACHE." << std::endl;
      return net::CacheType::MEDIA_CACHE;
      break;
    case disk_cache_fuzzer::FuzzCommands::SHADER_CACHE:
      MAYBE_PRINT << "Cache type = SHADER_CACHE." << std::endl;
      return net::CacheType::SHADER_CACHE;
      break;
    case disk_cache_fuzzer::FuzzCommands::PNACL_CACHE:
      // Simple cache won't handle PNACL_CACHE.
      if (backend == disk_cache_fuzzer::FuzzCommands::SIMPLE) {
        MAYBE_PRINT << "Cache type = DISK_CACHE." << std::endl;
        return net::CacheType::DISK_CACHE;
      }
      MAYBE_PRINT << "Cache type = PNACL_CACHE." << std::endl;
      return net::CacheType::PNACL_CACHE;
      break;
    case disk_cache_fuzzer::FuzzCommands::GENERATED_CODE_CACHE:
      MAYBE_PRINT << "Cache type = GENERATED_CODE_CACHE." << std::endl;
      return net::CacheType::GENERATED_CODE_CACHE;
      break;
    case disk_cache_fuzzer::FuzzCommands::DISK_CACHE:
      MAYBE_PRINT << "Cache type = DISK_CACHE." << std::endl;
      return net::CacheType::DISK_CACHE;
      break;
  }
}

void IOCallback(std::string io_type, int rv) {
  MAYBE_PRINT << " [Async IO (" << io_type << ") = " << rv << "]" << std::endl;
}

/*
 * Consistent hashing inspired map for fuzzer state.
 * If we stored open cache entries in a hash table mapping cache_entry_id ->
 * disk_cache::Entry*, then it would be highly unlikely that any subsequent
 * "CloseEntry" or "WriteData" etc. command would come up with an ID that would
 * correspond to a valid entry in the hash table. The optimal solution is for
 * libfuzzer to generate CloseEntry commands with an ID that matches the ID of a
 * previous OpenEntry command. But libfuzzer is stateless and should stay that
 * way.
 *
 * On the other hand, if we stored entries in a vector, and on a CloseEntry
 * command we took the entry at CloseEntry.id % (size of entries vector), we
 * would always generate correct CloseEntries. This is good, but all
 * dumb/general minimization techniques stop working, because deleting a single
 * OpenEntry command changes the indexes of every entry in the vector from then
 * on.
 *
 * So, we use something that's more stable for minimization: consistent hashing.
 * Basically, when we see a CloseEntry.id, we take the entry in the table that
 * has the next highest id (wrapping when there is no higher entry).
 *
 * This makes us resilient to deleting irrelevant OpenEntry commands. But, if we
 * delete from the table on CloseEntry commands, we still screw up all the
 * indexes during minimization. We'll get around this by not deleting entries
 * after CloseEntry commands, but that will result in a slightly less efficient
 * fuzzer, as if there are many closed entries in the table, many of the *Entry
 * commands will be useless. It seems like a decent balance between generating
 * useful fuzz commands and effective minimization.
 */
template <typename T>
typename std::map<uint64_t, T>::iterator GetNextValue(
    typename std::map<uint64_t, T>* entries,
    uint64_t val) {
  auto iter = entries->lower_bound(val);
  if (iter != entries->end())
    return iter;
  // Wrap to 0
  iter = entries->lower_bound(0);
  if (iter != entries->end())
    return iter;

  return entries->end();
}

void DiskCacheLPMFuzzer::RunTaskForTest(base::OnceClosure closure) {
  if (!block_impl_) {
    std::move(closure).Run();
    return;
  }

  net::TestCompletionCallback cb;
  int rv = block_impl_->RunTaskForTest(std::move(closure), cb.callback());
  CHECK_EQ(cb.GetResult(rv), net::OK);
}

// Resets the cb in the map so that WriteData and other calls that work on an
// entry don't wait for its result.
void DiskCacheLPMFuzzer::OpenCacheEntryCallback(
    scoped_refptr<base::RefCountedData<disk_cache::EntryWithOpened>>
        entry_result,
    uint64_t entry_id,
    bool async,
    bool set_is_sparse,
    int rv) {
  // TODO(mpdenton) if this fails should we delete the entry entirely?
  // Would need to mark it for deletion and delete it later, as
  // IsValidEntry might be waiting for it.
  EntryInfo* ei = &open_cache_entries_[entry_id];

  // It's important to write the pointer here and not let it be set directly
  // by OpenEntry & co., since the callback is when the item is transferred to
  // the client, so there may be a window in between the write and callback
  // where the backend is destroyed, invalidating the transfer.
  // Writes can also happen on a different thread, so unless the read is
  // sequenced with it, it would be a race, and ei->entry_ptr is read quite a
  // bit.
  ei->entry_ptr = entry_result->data.entry;
  ei->tcb->callback().Run(rv);
  // If this entry was just created, set it as sparse if applicable.
  if (set_is_sparse && ei->entry_ptr) {
    sparse_entry_tracker_[ei->entry_ptr] = true;
  }
  if (async && ei->entry_ptr) {
    MAYBE_PRINT << " [Async opening of cache entry for \""
                << ei->entry_ptr->GetKey() << "\" callback (rv = " << rv << ")]"
                << std::endl;
  }
}

int DiskCacheLPMFuzzer::WaitOnEntry(EntryInfo* ei, int rv) {
  CHECK(ei->tcb);
  rv = ei->tcb->GetResult(rv);
  // Reset the callback so nobody accidentally waits on a callback that never
  // comes.
  ei->tcb.reset();
  return rv;
}

bool DiskCacheLPMFuzzer::IsValidEntry(EntryInfo* ei) {
  if (ei->tcb) {
    // If we have a callback, we are the first to access this async-created
    // entry. Wait for it, and then delete it so nobody waits on it again.
    return WaitOnEntry(ei) == net::OK;
  }
  // entry_ptr will be nullptr if the entry has been closed.
  return ei->entry_ptr != nullptr;
}

/*
 * Async implementation:
 1. RunUntilIdle at the top of the loop to handle any callbacks we've been
 posted from the backend thread.
 2. Only the entry creation functions have important callbacks. The good thing
 is backend destruction will cancel these operations. The entry creation
 functions simply need to keep the entry_ptr* alive until the callback is
 posted, and then need to make sure the entry_ptr is added to the map in order
 to Close it in the destructor.
    As for iterators, it's unclear whether closing an iterator will cancel
 callbacks.

 Problem: WriteData (and similar) calls will fail on the entry_id until the
 callback happens. So, I should probably delay these calls or otherwise will
 have very unreliable test cases. These are the options:
 1. Queue up WriteData (etc.) calls in some map, such that when the OpenEntry
 callback runs, the WriteData calls will all run.
 2. Just sit there and wait for the entry to be ready.

 #2 is probably best as it doesn't prevent any interesting cases and is much
 simpler.
 */

void DiskCacheLPMFuzzer::RunCommands(
    const disk_cache_fuzzer::FuzzCommands& commands) {
  uint32_t mask =
      commands.has_set_mask() ? (commands.set_mask() ? 0x1 : 0xf) : 0;
  net::CacheType type =
      GetCacheTypeAndPrint(commands.cache_type(), commands.cache_backend());
  CreateBackend(commands.cache_backend(), mask, type,
                commands.simple_cache_wait_for_index());
  MAYBE_PRINT << "CreateBackend()" << std::endl;

  if (commands.has_set_max_size()) {
    HandleSetMaxSize(commands.set_max_size());
  }

  {
    base::Time curr_time = base::Time::Now();
    saved_times_[kFirstSavedTime] = curr_time;
    // MAYBE_PRINT << "Saved initial time " << curr_time << std::endl;
  }

  for (const disk_cache_fuzzer::FuzzCommand& command :
       commands.fuzz_commands()) {
    // Handle any callbacks that other threads may have posted to us in the
    // meantime, so any successful async OpenEntry's (etc.) add their
    // entry_ptr's to the map.
    init_globals->scoped_task_environment_->RunUntilIdle();

    switch (command.fuzz_command_oneof_case()) {
      case disk_cache_fuzzer::FuzzCommand::kSetMaxSize: {
        HandleSetMaxSize(command.set_max_size());
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kCreateEntry: {
        if (!cache_)
          continue;

        const disk_cache_fuzzer::CreateEntry& ce = command.create_entry();
        uint64_t key_id = ce.key_id();
        uint64_t entry_id = ce.entry_id();
        net::RequestPriority pri = GetRequestPriority(ce.pri());
        bool async = ce.async();
        bool is_sparse = ce.is_sparse();

        if (open_cache_entries_.find(entry_id) != open_cache_entries_.end())
          continue;  // Don't overwrite a currently open cache entry.

        std::string key_str = ToKey(key_id);
        created_cache_entries_[key_id] = key_str;

        auto entry_result = base::MakeRefCounted<
            base::RefCountedData<disk_cache::EntryWithOpened>>();
        disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data;
        EntryInfo* entry_info = &open_cache_entries_[entry_id];

        entry_info->tcb = std::make_unique<net::TestCompletionCallback>();
        net::CompletionOnceCallback cb = base::BindOnce(
            &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this),
            entry_result, entry_id, async, is_sparse);

        MAYBE_PRINT << "CreateEntry(\"" << key_str
                    << "\", set_is_sparse = " << is_sparse
                    << ") = " << std::flush;
        int rv = cache_->CreateEntry(key_str, pri, &entry_result_ptr->entry,
                                     std::move(cb));
        if (!async || rv != net::ERR_IO_PENDING) {
          rv = WaitOnEntry(entry_info, rv);
          // Ensure we mark sparsity, even if the callback never ran.
          if (rv == net::OK) {
            entry_info->entry_ptr = entry_result_ptr->entry;
            sparse_entry_tracker_[entry_info->entry_ptr] = is_sparse;
          }
          MAYBE_PRINT << rv << std::endl;
        } else if (rv == net::ERR_IO_PENDING) {
          MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl;
        }
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kOpenEntry: {
        if (!cache_)
          continue;

        const disk_cache_fuzzer::OpenEntry& oe = command.open_entry();
        uint64_t key_id = oe.key_id();
        uint64_t entry_id = oe.entry_id();
        net::RequestPriority pri = GetRequestPriority(oe.pri());
        bool async = oe.async();

        if (created_cache_entries_.empty())
          continue;

        if (open_cache_entries_.find(entry_id) != open_cache_entries_.end())
          continue;  // Don't overwrite a currently open cache entry.

        auto entry_result = base::MakeRefCounted<
            base::RefCountedData<disk_cache::EntryWithOpened>>();
        disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data;
        EntryInfo* entry_info = &open_cache_entries_[entry_id];

        entry_info->tcb = std::make_unique<net::TestCompletionCallback>();
        net::CompletionOnceCallback cb = base::BindOnce(
            &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this),
            entry_result, entry_id, async, false);

        auto key_it = GetNextValue(&created_cache_entries_, key_id);
        MAYBE_PRINT << "OpenEntry(\"" << key_it->second
                    << "\") = " << std::flush;
        int rv = cache_->OpenEntry(key_it->second, pri,
                                   &entry_result_ptr->entry, std::move(cb));
        if (!async || rv != net::ERR_IO_PENDING) {
          rv = WaitOnEntry(entry_info, rv);
          if (rv == net::OK)
            entry_info->entry_ptr = entry_result_ptr->entry;
          MAYBE_PRINT << rv << std::endl;
        } else {
          MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl;
        }
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kOpenOrCreateEntry: {
        if (!cache_)
          continue;

        const disk_cache_fuzzer::OpenOrCreateEntry& ooce =
            command.open_or_create_entry();
        uint64_t key_id = ooce.key_id();
        uint64_t entry_id = ooce.entry_id();
        net::RequestPriority pri = GetRequestPriority(ooce.pri());
        bool async = ooce.async();
        bool is_sparse = ooce.is_sparse();

        if (open_cache_entries_.find(entry_id) != open_cache_entries_.end())
          continue;  // Don't overwrite a currently open cache entry.

        std::string key_str;
        // If our proto tells us to create a new entry, create a new entry, just
        // with OpenOrCreateEntry.
        if (ooce.create_new()) {
          // Use a possibly new key.
          key_str = ToKey(key_id);
          created_cache_entries_[key_id] = key_str;
        } else {
          if (created_cache_entries_.empty())
            continue;
          auto key_it = GetNextValue(&created_cache_entries_, key_id);
          key_str = key_it->second;
        }

        // Setup for callbacks.
        auto entry_result = base::MakeRefCounted<
            base::RefCountedData<disk_cache::EntryWithOpened>>();
        disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data;

        EntryInfo* entry_info = &open_cache_entries_[entry_id];

        entry_info->tcb = std::make_unique<net::TestCompletionCallback>();
        net::CompletionOnceCallback cb = base::BindOnce(
            &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this),
            entry_result, entry_id, async, is_sparse);

        // Will only be set as sparse if it is created and not opened.
        MAYBE_PRINT << "OpenOrCreateEntry(\"" << key_str
                    << "\", set_is_sparse = " << is_sparse
                    << ") = " << std::flush;
        int rv = cache_->OpenOrCreateEntry(key_str, pri, entry_result_ptr,
                                           std::move(cb));
        if (!async || rv != net::ERR_IO_PENDING) {
          rv = WaitOnEntry(entry_info, rv);
          // We still hold a reference to |entry_result| so we can use it.
          entry_info->entry_ptr = entry_result_ptr->entry;
          // Ensure we mark sparsity, even if the callback never ran.
          if (rv == net::OK && !entry_result_ptr->opened)
            sparse_entry_tracker_[entry_info->entry_ptr] = is_sparse;
          MAYBE_PRINT << rv << ", opened = " << entry_result_ptr->opened
                      << std::endl;
        } else {
          MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl;
        }
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kCloseEntry: {
        if (open_cache_entries_.empty())
          continue;

        auto entry_it = GetNextValue(&open_cache_entries_,
                                     command.close_entry().entry_id());
        if (!IsValidEntry(&entry_it->second))
          continue;

        MAYBE_PRINT << "CloseEntry(\"" << entry_it->second.entry_ptr->GetKey()
                    << "\")" << std::endl;
        entry_it->second.entry_ptr->Close();

        // Set the entry_ptr to nullptr to ensure no one uses it anymore.
        entry_it->second.entry_ptr = nullptr;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDoomEntry: {
        if (open_cache_entries_.empty())
          continue;

        auto entry_it =
            GetNextValue(&open_cache_entries_, command.doom_entry().entry_id());
        if (!IsValidEntry(&entry_it->second))
          continue;

        MAYBE_PRINT << "DoomEntry(\"" << entry_it->second.entry_ptr->GetKey()
                    << "\")" << std::endl;
        entry_it->second.entry_ptr->Doom();
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kWriteData: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::WriteData& wd = command.write_data();
        auto entry_it = GetNextValue(&open_cache_entries_, wd.entry_id());
        if (!IsValidEntry(&entry_it->second))
          continue;

        int index = 0;  // if it's sparse, these non-sparse aware streams must
                        // read from stream 0 according to the spec.
                        // Implementations might have weaker constraints.
        if (!sparse_entry_tracker_[entry_it->second.entry_ptr])
          index = wd.index() % kNumStreams;
        uint32_t offset = wd.offset() % kMaxEntrySize;
        size_t size = wd.size() % kMaxEntrySize;
        bool async = wd.async();

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::WriteData);

        MAYBE_PRINT << "WriteData(\"" << entry_it->second.entry_ptr->GetKey()
                    << "\", index = " << index << ", offset = " << offset
                    << ", size = " << size << ", truncate = " << wd.truncate()
                    << ")" << std::flush;
        int rv = entry_it->second.entry_ptr->WriteData(
            index, offset, init_globals->buffer_.get(), size, std::move(cb),
            wd.truncate());
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kReadData: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::ReadData& wd = command.read_data();
        auto entry_it = GetNextValue(&open_cache_entries_, wd.entry_id());
        if (!IsValidEntry(&entry_it->second))
          continue;

        int index = 0;  // if it's sparse, these non-sparse aware streams must
                        // read from stream 0 according to the spec.
                        // Implementations might weaker constraints?
        if (!sparse_entry_tracker_[entry_it->second.entry_ptr])
          index = wd.index() % kNumStreams;
        uint32_t offset = wd.offset() % kMaxEntrySize;
        size_t size = wd.size() % kMaxEntrySize;
        bool async = wd.async();
        scoped_refptr<net::IOBuffer> buffer =
            base::MakeRefCounted<net::IOBuffer>(size);

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::ReadData);

        MAYBE_PRINT << "ReadData(\"" << entry_it->second.entry_ptr->GetKey()
                    << "\", index = " << index << ", offset = " << offset
                    << ", size = " << size << ")" << std::flush;
        int rv = entry_it->second.entry_ptr->ReadData(
            index, offset, buffer.get(), size, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kWriteSparseData: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::WriteSparseData& wsd =
            command.write_sparse_data();
        auto entry_it = GetNextValue(&open_cache_entries_, wsd.entry_id());
        if (!IsValidEntry(&entry_it->second) ||
            !sparse_entry_tracker_[entry_it->second.entry_ptr])
          continue;

        uint64_t offset = wsd.offset();
        if (wsd.cap_offset())
          offset %= kMaxEntrySize;
        size_t size = wsd.size() % kMaxEntrySize;
        bool async = wsd.async();

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::WriteSparseData);
        MAYBE_PRINT << "WriteSparseData(\""
                    << entry_it->second.entry_ptr->GetKey()
                    << "\", offset = " << offset << ", size = " << size << ")"
                    << std::flush;
        int rv = entry_it->second.entry_ptr->WriteSparseData(
            offset, init_globals->buffer_.get(), size, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kReadSparseData: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::ReadSparseData& rsd =
            command.read_sparse_data();
        auto entry_it = GetNextValue(&open_cache_entries_, rsd.entry_id());
        if (!IsValidEntry(&entry_it->second) ||
            !sparse_entry_tracker_[entry_it->second.entry_ptr])
          continue;

        uint64_t offset = rsd.offset();
        if (rsd.cap_offset())
          offset %= kMaxEntrySize;
        size_t size = rsd.size() % kMaxEntrySize;
        bool async = rsd.async();
        scoped_refptr<net::IOBuffer> buffer =
            base::MakeRefCounted<net::IOBuffer>(size);

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::ReadSparseData);

        MAYBE_PRINT << "ReadSparseData(\""
                    << entry_it->second.entry_ptr->GetKey()
                    << "\", offset = " << offset << ", size = " << size << ")"
                    << std::flush;
        int rv = entry_it->second.entry_ptr->ReadSparseData(
            offset, buffer.get(), size, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDoomAllEntries: {
        if (!cache_)
          continue;
        bool async = command.doom_all_entries().async();

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::DoomAllEntries);
        MAYBE_PRINT << "DoomAllEntries()" << std::flush;
        int rv = cache_->DoomAllEntries(std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kFlushQueueForTest: {
        // Blockfile-cache specific method.
        if (!block_impl_)
          return;

        net::TestCompletionCallback cb;
        MAYBE_PRINT << "FlushQueueForTest()" << std::endl;
        int rv = block_impl_->FlushQueueForTest(cb.callback());
        CHECK_EQ(cb.GetResult(rv), net::OK);
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kCreateIterator: {
        if (!cache_)
          continue;
        uint64_t it_id = command.create_iterator().it_id();
        MAYBE_PRINT << "CreateIterator(), id = " << it_id << std::endl;
        open_iterators_[it_id] = cache_->CreateIterator();
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kIteratorOpenNextEntry: {
        const disk_cache_fuzzer::IteratorOpenNextEntry& ione =
            command.iterator_open_next_entry();

        uint64_t it_id = ione.it_id();
        uint64_t entry_id = ione.entry_id();
        bool async = ione.async();

        if (open_iterators_.empty())
          continue;

        if (open_cache_entries_.find(entry_id) != open_cache_entries_.end())
          continue;  // Don't overwrite a currently
                     // open cache entry.

        auto iterator_it = GetNextValue(&open_iterators_, it_id);

        auto entry_result = base::MakeRefCounted<
            base::RefCountedData<disk_cache::EntryWithOpened>>();
        disk_cache::EntryWithOpened* entry_result_ptr = &entry_result->data;
        EntryInfo* entry_info = &open_cache_entries_[entry_id];

        entry_info->tcb = std::make_unique<net::TestCompletionCallback>();
        net::CompletionOnceCallback cb = base::BindOnce(
            &DiskCacheLPMFuzzer::OpenCacheEntryCallback, base::Unretained(this),
            entry_result, entry_id, async, false);

        MAYBE_PRINT << "Iterator(" << ione.it_id()
                    << ").OpenNextEntry() = " << std::flush;
        int rv = iterator_it->second->OpenNextEntry(&entry_result_ptr->entry,
                                                    std::move(cb));
        if (!async || rv != net::ERR_IO_PENDING) {
          rv = WaitOnEntry(entry_info, rv);
          entry_info->entry_ptr = entry_result_ptr->entry;
          // Print return value, and key if applicable.
          if (!entry_info->entry_ptr) {
            MAYBE_PRINT << rv << std::endl;
          } else {
            MAYBE_PRINT << rv << ", key = " << entry_info->entry_ptr->GetKey()
                        << std::endl;
          }
        } else {
          MAYBE_PRINT << "net::ERR_IO_PENDING (async)" << std::endl;
        }
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kFastForwardBy: {
        base::TimeDelta to_wait = base::TimeDelta::FromMilliseconds(
            command.fast_forward_by().capped_num_millis() %
            kMaxNumMillisToWait);
        MAYBE_PRINT << "FastForwardBy(" << to_wait << ")" << std::endl;
        init_globals->scoped_task_environment_->FastForwardBy(to_wait);

        base::Time curr_time = base::Time::Now();
        saved_times_[command.fast_forward_by().time_id()] = curr_time;
        // MAYBE_PRINT << "Saved time " << curr_time << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDoomEntriesSince: {
        if (!cache_)
          continue;
        // App cache does not keep track of LRU timestamps so this method cannot
        // be used.
        if (type == net::APP_CACHE)
          continue;
        if (saved_times_.empty())
          continue;

        const disk_cache_fuzzer::DoomEntriesSince& des =
            command.doom_entries_since();
        auto time_it = GetNextValue(&saved_times_, des.time_id());
        bool async = des.async();

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::DoomEntriesSince);

        MAYBE_PRINT << "DoomEntriesSince(" << time_it->second << ")"
                    << std::flush;
        int rv = cache_->DoomEntriesSince(time_it->second, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDoomEntriesBetween: {
        if (!cache_)
          continue;
        // App cache does not keep track of LRU timestamps so this method cannot
        // be used.
        if (type == net::APP_CACHE)
          continue;
        if (saved_times_.empty())
          continue;

        const disk_cache_fuzzer::DoomEntriesBetween& deb =
            command.doom_entries_between();
        auto time_it1 = GetNextValue(&saved_times_, deb.time_id1());
        auto time_it2 = GetNextValue(&saved_times_, deb.time_id2());
        base::Time time1 = time_it1->second;
        base::Time time2 = time_it2->second;
        if (time1 > time2)
          std::swap(time1, time2);
        bool async = deb.async();

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::DoomEntriesBetween);

        MAYBE_PRINT << "DoomEntriesBetween(" << time1 << ", " << time2 << ")"
                    << std::flush;
        int rv = cache_->DoomEntriesBetween(time1, time2, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kOnExternalCacheHit: {
        if (!cache_)
          continue;
        if (created_cache_entries_.empty())
          continue;

        uint64_t key_id = command.on_external_cache_hit().key_id();

        auto key_it = GetNextValue(&created_cache_entries_, key_id);
        MAYBE_PRINT << "OnExternalCacheHit(\"" << key_it->second << "\")"
                    << std::endl;
        cache_->OnExternalCacheHit(key_it->second);
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kTrimForTest: {
        // Blockfile-cache specific method.
        if (!block_impl_ || type != net::DISK_CACHE)
          return;

        MAYBE_PRINT << "TrimForTest()" << std::endl;

        RunTaskForTest(base::BindOnce(&disk_cache::BackendImpl::TrimForTest,
                                      base::Unretained(block_impl_),
                                      command.trim_for_test().empty()));
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kTrimDeletedListForTest: {
        // Blockfile-cache specific method.
        if (!block_impl_ || type != net::DISK_CACHE)
          return;

        MAYBE_PRINT << "TrimDeletedListForTest()" << std::endl;

        RunTaskForTest(
            base::BindOnce(&disk_cache::BackendImpl::TrimDeletedListForTest,
                           base::Unretained(block_impl_),
                           command.trim_deleted_list_for_test().empty()));
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kGetAvailableRange: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::GetAvailableRange& gar =
            command.get_available_range();
        auto entry_it = GetNextValue(&open_cache_entries_, gar.entry_id());
        if (!IsValidEntry(&entry_it->second) ||
            !sparse_entry_tracker_[entry_it->second.entry_ptr])
          continue;

        disk_cache::Entry* entry = entry_it->second.entry_ptr;
        uint32_t offset = gar.offset() % kMaxEntrySize;
        uint32_t len = gar.len() % kMaxEntrySize;
        bool async = gar.async();
        auto start = base::MakeRefCounted<base::RefCountedData<int64_t>>();
        // Raw pointer will stay alive until the end of this command for sure,
        // as we hold a reference to the object.
        int64_t* start_tmp = &start->data;

        auto result_checker = base::BindRepeating(
            [](net::CompletionOnceCallback callback,
               scoped_refptr<base::RefCountedData<int64_t>> start,
               uint32_t offset, uint32_t len, int rv) {
              std::move(callback).Run(rv);

              if (rv < 0)
                return;

              int64_t* start_tmp = &start->data;
              CHECK_LE(offset, *start_tmp);
              CHECK_LE(*start_tmp, offset + len);
              CHECK_LE(*start_tmp + rv, offset + len);
              // Offsets are capped by kMaxEntrySize
              CHECK_LE(*start_tmp, kMaxEntrySize);
              // And size are also capped by kMaxEntrySize
              CHECK_LE(*start_tmp + rv, kMaxEntrySize * 2);
            },
            GetIOCallback(IOType::GetAvailableRange), start, offset, len);

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : result_checker;

        MAYBE_PRINT << "GetAvailableRange(\"" << entry->GetKey() << "\", "
                    << offset << ", " << len << ")" << std::flush;
        int rv =
            entry->GetAvailableRange(offset, len, start_tmp, std::move(cb));

        if (rv != net::ERR_IO_PENDING) {
          // Run the checker callback ourselves.
          result_checker.Run(rv);
        } else if (!async) {
          // In this case the callback will be run by the backend, so we don't
          // need to do it manually.
          rv = tcb.GetResult(rv);
        }

        // Finally, take care of printing.
        if (async && rv == net::ERR_IO_PENDING) {
          MAYBE_PRINT << " = net::ERR_IO_PENDING (async)" << std::endl;
        } else {
          MAYBE_PRINT << " = " << rv << ", *start = " << *start_tmp;
          if (rv < 0) {
            MAYBE_PRINT << ", error to string: " << net::ErrorToShortString(rv)
                        << std::endl;
          } else {
            MAYBE_PRINT << std::endl;
          }
        }
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kCancelSparseIo: {
        if (open_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::CancelSparseIO& csio =
            command.cancel_sparse_io();
        auto entry_it = GetNextValue(&open_cache_entries_, csio.entry_id());
        if (!IsValidEntry(&entry_it->second))
          continue;

        MAYBE_PRINT << "CancelSparseIO(\""
                    << entry_it->second.entry_ptr->GetKey() << "\")"
                    << std::endl;
        entry_it->second.entry_ptr->CancelSparseIO();
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDoomKey: {
        if (!cache_)
          continue;
        if (created_cache_entries_.empty())
          continue;

        const disk_cache_fuzzer::DoomKey& dk = command.doom_key();
        uint64_t key_id = dk.key_id();
        net::RequestPriority pri = GetRequestPriority(dk.pri());
        bool async = dk.async();

        auto key_it = GetNextValue(&created_cache_entries_, key_id);

        net::TestCompletionCallback tcb;
        net::CompletionOnceCallback cb =
            !async ? tcb.callback() : GetIOCallback(IOType::DoomKey);

        MAYBE_PRINT << "DoomKey(\"" << key_it->second << "\")" << std::flush;
        int rv = cache_->DoomEntry(key_it->second, pri, std::move(cb));
        if (!async)
          rv = tcb.GetResult(rv);
        MAYBE_PRINT << " = " << rv << std::endl;

        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kDestructBackend: {
        // Block_impl_ will leak if we destruct the backend without closing
        // previous entries.
        // TODO(mpdenton) consider creating a separate fuzz target that allows
        // closing the |block_impl_| and ignore leaks.
        if (block_impl_ || !cache_)
          continue;

        const disk_cache_fuzzer::DestructBackend& db =
            command.destruct_backend();
        // Only sometimes actually destruct the backend.
        if (!db.actually_destruct1() || !db.actually_destruct2())
          continue;

        MAYBE_PRINT << "~Backend(). Backend destruction." << std::endl;
        cache_.reset();
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::kAddRealDelay: {
        if (!command.add_real_delay().actually_delay())
          continue;

        MAYBE_PRINT << "AddRealDelay(1ms)" << std::endl;
        base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
        break;
      }
      case disk_cache_fuzzer::FuzzCommand::FUZZ_COMMAND_ONEOF_NOT_SET: {
        continue;
        break;
      }
    }
  }
}

void DiskCacheLPMFuzzer::HandleSetMaxSize(
    const disk_cache_fuzzer::SetMaxSize& sms) {
  if (!cache_)
    return;

  max_size_ = sms.size();
  max_size_ %= kMaxSizeKB;
  max_size_ *= 1024;
  MAYBE_PRINT << "SetMaxSize(" << max_size_ << ")" << std::endl;
  if (simple_cache_impl_)
    CHECK_EQ(true, simple_cache_impl_->SetMaxSize(max_size_));

  if (block_impl_)
    CHECK_EQ(true, block_impl_->SetMaxSize(max_size_));

  if (mem_cache_)
    CHECK_EQ(true, mem_cache_->SetMaxSize(max_size_));
}

void DiskCacheLPMFuzzer::CreateBackend(
    disk_cache_fuzzer::FuzzCommands::CacheBackend cache_backend,
    uint32_t mask,
    net::CacheType type,
    bool simple_cache_wait_for_index) {
  if (cache_backend == disk_cache_fuzzer::FuzzCommands::IN_MEMORY) {
    MAYBE_PRINT << "Using in-memory cache." << std::endl;
    mem_cache_ = new disk_cache::MemBackendImpl(nullptr);
    cache_.reset(mem_cache_);
    CHECK(cache_);
  } else if (cache_backend == disk_cache_fuzzer::FuzzCommands::SIMPLE) {
    MAYBE_PRINT << "Using simple cache." << std::endl;
    net::TestCompletionCallback cb;
    // We limit ourselves to 64 fds since OS X by default gives us 256.
    // (Chrome raises the number on startup, but the fuzzer doesn't).
    if (!simple_file_tracker_)
      simple_file_tracker_ =
          std::make_unique<disk_cache::SimpleFileTracker>(kMaxFdsSimpleCache);
    std::unique_ptr<disk_cache::SimpleBackendImpl> simple_backend =
        std::make_unique<disk_cache::SimpleBackendImpl>(
            cache_path_, /* cleanup_tracker = */ nullptr,
            simple_file_tracker_.get(), max_size_, type,
            /*net_log = */ nullptr);
    int rv = simple_backend->Init(cb.callback());
    CHECK_EQ(cb.GetResult(rv), net::OK);
    simple_cache_impl_ = simple_backend.get();
    cache_ = std::move(simple_backend);

    if (simple_cache_wait_for_index) {
      MAYBE_PRINT << "Waiting for simple cache index to be ready..."
                  << std::endl;
      net::TestCompletionCallback wait_for_index_cb;
      rv = simple_cache_impl_->index()->ExecuteWhenReady(
          wait_for_index_cb.callback());
      CHECK_EQ(wait_for_index_cb.GetResult(rv), net::OK);
    }
  } else {
    MAYBE_PRINT << "Using blockfile cache";

    if (mask) {
      MAYBE_PRINT << ", mask = " << mask << std::endl;
      block_impl_ = new disk_cache::BackendImpl(cache_path_, mask,
                                                /* runner = */ nullptr, type,
                                                /* net_log = */ nullptr);
    } else {
      MAYBE_PRINT << "." << std::endl;
      block_impl_ = new disk_cache::BackendImpl(cache_path_,
                                                /* cleanup_tracker = */ nullptr,
                                                /* runner = */ nullptr, type,
                                                /* net_log = */ nullptr);
    }
    cache_.reset(block_impl_);
    CHECK(cache_);
    // TODO(mpdenton) kNoRandom or not? It does a lot of waiting for IO. May be
    // good for avoiding leaks but tests a less realistic cache.
    // block_impl_->SetFlags(disk_cache::kNoRandom);

    // TODO(mpdenton) should I always wait here?
    net::TestCompletionCallback cb;
    int rv = block_impl_->Init(cb.callback());
    CHECK_EQ(cb.GetResult(rv), net::OK);
  }
}

void DiskCacheLPMFuzzer::CloseAllRemainingEntries() {
  for (auto& entry_info : open_cache_entries_) {
    disk_cache::Entry** entry_ptr = &entry_info.second.entry_ptr;
    if (!*entry_ptr)
      continue;
    MAYBE_PRINT << "Destructor CloseEntry(\"" << (*entry_ptr)->GetKey() << "\")"
                << std::endl;
    (*entry_ptr)->Close();
    *entry_ptr = nullptr;
  }
}

DiskCacheLPMFuzzer::~DiskCacheLPMFuzzer() {
  // |block_impl_| leaks a lot more if we don't close entries before destructing
  // the backend.
  if (block_impl_) {
    // TODO(mpdenton) Consider creating a fuzz target that does not wait for
    // blockfile, and also does not detect leaks.

    // Because the blockfile backend will leak any entries closed after its
    // destruction, we need to wait for any remaining backend callbacks to
    // finish. Otherwise, there will always be a race between handling callbacks
    // with RunUntilIdle() and actually closing all of the remaining entries.
    // And, closing entries after destructing the backend will not work and
    // cause leaks.
    for (auto& entry_it : open_cache_entries_) {
      if (entry_it.second.tcb) {
        WaitOnEntry(&entry_it.second);
      }
    }

    // Destroy any open iterators before destructing the backend so we don't
    // cause leaks. TODO(mpdenton) should maybe be documented?
    // Also *must* happen after waiting for all OpenNextEntry callbacks to
    // finish, because destructing the iterators may cause those callbacks to be
    // cancelled, which will cause WaitOnEntry() to spin forever waiting.
    // TODO(mpdenton) should also be documented?
    open_iterators_.clear();
    // Just in case, finish any callbacks.
    init_globals->scoped_task_environment_->RunUntilIdle();
    // Close all entries that haven't been closed yet.
    CloseAllRemainingEntries();
    // Destroy the backend.
    cache_.reset();
  } else {
    // Here we won't bother with waiting for our OpenEntry* callbacks.
    cache_.reset();
    // Finish any callbacks that came in before backend destruction.
    init_globals->scoped_task_environment_->RunUntilIdle();
    // Close all entries that haven't been closed yet.
    CloseAllRemainingEntries();
  }

  // Make sure any tasks triggered by the CloseEntry's have run.
  init_globals->scoped_task_environment_->RunUntilIdle();
  if (simple_cache_impl_)
    CHECK(simple_file_tracker_->IsEmptyForTesting());
  base::RunLoop().RunUntilIdle();

  DeleteCache(cache_path_);
}

DEFINE_BINARY_PROTO_FUZZER(const disk_cache_fuzzer::FuzzCommands& commands) {
  {
    DiskCacheLPMFuzzer disk_cache_fuzzer_instance;
    disk_cache_fuzzer_instance.RunCommands(commands);
  }
  MAYBE_PRINT << "-----------------------" << std::endl;
}
//
