#ifndef NET_HTTP_MOCK_HTTP_CACHE_H_
#define NET_HTTP_MOCK_HTTP_CACHE_H_
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/strings/string_split.h"
#include "net/base/completion_once_callback.h"
#include "net/base/request_priority.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_transaction_test_util.h"
namespace net {
class MockDiskEntry : public disk_cache::Entry,
public base::RefCounted<MockDiskEntry> {
public:
enum DeferOp {
DEFER_NONE,
DEFER_CREATE,
DEFER_READ,
DEFER_WRITE,
};
enum FailOp {
FAIL_READ = 0x01,
FAIL_WRITE = 0x02,
FAIL_READ_SPARSE = 0x04,
FAIL_WRITE_SPARSE = 0x08,
FAIL_GET_AVAILABLE_RANGE = 0x10,
FAIL_ALL = 0xFF
};
explicit MockDiskEntry(const std::string& key);
bool is_doomed() const { return doomed_; }
void Doom() override;
void Close() override;
std::string GetKey() const override;
base::Time GetLastUsed() const override;
base::Time GetLastModified() const override;
int32_t GetDataSize(int index) const override;
int ReadData(int index,
int offset,
IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int WriteData(int index,
int offset,
IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback,
bool truncate) override;
int ReadSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
int WriteSparseData(int64_t offset,
IOBuffer* buf,
int buf_len,
CompletionOnceCallback callback) override;
RangeResult GetAvailableRange(int64_t offset,
int len,
RangeResultCallback callback) override;
bool CouldBeSparse() const override;
void CancelSparseIO() override;
net::Error ReadyForSparseIO(
CompletionOnceCallback completion_callback) override;
void SetLastUsedTimeForTest(base::Time time) override;
uint8_t in_memory_data() const { return in_memory_data_; }
void set_in_memory_data(uint8_t val) { in_memory_data_ = val; }
void set_fail_requests(int mask) { fail_requests_ = mask; }
void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
static void IgnoreCallbacks(bool value);
void SetDefer(DeferOp defer_op) { defer_op_ = defer_op; }
void ResumeDiskEntryOperation();
void set_max_file_size(int val) { max_file_size_ = val; }
private:
friend class base::RefCounted<MockDiskEntry>;
struct CallbackInfo;
~MockDiskEntry() override;
void CallbackLater(CompletionOnceCallback callback, int result);
void CallbackLater(base::OnceClosure callback);
void RunCallback(base::OnceClosure callback);
static void StoreAndDeliverCallbacks(bool store,
MockDiskEntry* entry,
base::OnceClosure callback);
static const int kNumCacheEntryDataIndices = 3;
std::string key_;
std::vector<char> data_[kNumCacheEntryDataIndices];
uint8_t in_memory_data_ = 0;
int test_mode_;
int max_file_size_;
bool doomed_ = false;
bool sparse_ = false;
int fail_requests_ = 0;
bool fail_sparse_requests_ = false;
bool busy_ = false;
bool delayed_ = false;
bool cancel_ = false;
DeferOp defer_op_ = DEFER_NONE;
CompletionOnceCallback resume_callback_;
int resume_return_code_ = 0;
static bool ignore_callbacks_;
};
class MockDiskCache : public disk_cache::Backend {
public:
MockDiskCache();
~MockDiskCache() override;
int32_t GetEntryCount() const override;
EntryResult OpenOrCreateEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) override;
EntryResult OpenEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) override;
EntryResult CreateEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) override;
net::Error DoomEntry(const std::string& key,
net::RequestPriority request_priority,
CompletionOnceCallback callback) override;
net::Error DoomAllEntries(CompletionOnceCallback callback) override;
net::Error DoomEntriesBetween(base::Time initial_time,
base::Time end_time,
CompletionOnceCallback callback) override;
net::Error DoomEntriesSince(base::Time initial_time,
CompletionOnceCallback callback) override;
int64_t CalculateSizeOfAllEntries(
Int64CompletionOnceCallback callback) override;
std::unique_ptr<Iterator> CreateIterator() override;
void GetStats(base::StringPairs* stats) override;
void OnExternalCacheHit(const std::string& key) override;
uint8_t GetEntryInMemoryData(const std::string& key) override;
void SetEntryInMemoryData(const std::string& key, uint8_t data) override;
int64_t MaxFileSize() const override;
int open_count() const { return open_count_; }
int create_count() const { return create_count_; }
int doomed_count() const { return doomed_count_; }
void set_fail_requests(bool value) { fail_requests_ = value; }
void set_soft_failures_mask(int value) { soft_failures_ = value; }
void set_soft_failures_one_instance(int value) {
soft_failures_one_instance_ = value;
}
void set_double_create_check(bool value) { double_create_check_ = value; }
void set_support_in_memory_entry_data(bool value) {
support_in_memory_entry_data_ = value;
}
void set_force_fail_callback_later(bool value) {
force_fail_callback_later_ = value;
}
void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
void set_max_file_size(int new_size) { max_file_size_ = new_size; }
void ReleaseAll();
bool IsDiskEntryDoomed(const std::string& key);
void SetDefer(MockDiskEntry::DeferOp defer_op) { defer_op_ = defer_op; }
void ResumeCacheOperation();
scoped_refptr<MockDiskEntry> GetDiskEntryRef(const std::string& key);
const std::vector<std::string>& GetExternalCacheHits() const;
private:
using EntryMap = std::map<std::string, MockDiskEntry*>;
class NotImplementedIterator;
void CallbackLater(base::OnceClosure callback);
EntryMap entries_;
std::vector<std::string> external_cache_hits_;
int open_count_ = 0;
int create_count_ = 0;
int doomed_count_ = 0;
int max_file_size_;
bool fail_requests_ = false;
int soft_failures_ = 0;
int soft_failures_one_instance_ = 0;
bool double_create_check_ = true;
bool fail_sparse_requests_ = false;
bool support_in_memory_entry_data_ = true;
bool force_fail_callback_later_ = false;
MockDiskEntry::DeferOp defer_op_ = MockDiskEntry::DEFER_NONE;
base::OnceClosure resume_callback_;
};
class MockBackendFactory : public HttpCache::BackendFactory {
public:
disk_cache::BackendResult CreateBackend(
NetLog* net_log,
disk_cache::BackendResultCallback callback) override;
};
class MockHttpCache {
public:
MockHttpCache();
explicit MockHttpCache(
std::unique_ptr<HttpCache::BackendFactory> disk_cache_factory);
HttpCache* http_cache() { return &http_cache_; }
MockNetworkLayer* network_layer() {
return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
}
disk_cache::Backend* backend();
MockDiskCache* disk_cache();
int CreateTransaction(std::unique_ptr<HttpTransaction>* trans);
void SimulateCacheLockTimeout();
void SimulateCacheLockTimeoutAfterHeaders();
void FailConditionalizations();
static bool ReadResponseInfo(disk_cache::Entry* disk_entry,
HttpResponseInfo* response_info,
bool* response_truncated);
static bool WriteResponseInfo(disk_cache::Entry* disk_entry,
const HttpResponseInfo* response_info,
bool skip_transient_headers,
bool response_truncated);
bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry);
bool CreateBackendEntry(const std::string& key,
disk_cache::Entry** entry,
NetLog* net_log);
static int GetTestMode(int test_mode);
static void SetTestMode(int test_mode);
bool IsWriterPresent(const std::string& key);
bool IsHeadersTransactionPresent(const std::string& key);
int GetCountReaders(const std::string& key);
int GetCountAddToEntryQueue(const std::string& key);
int GetCountDoneHeadersQueue(const std::string& key);
int GetCountWriterTransactions(const std::string& key);
private:
HttpCache http_cache_;
};
class MockDiskCacheNoCB : public MockDiskCache {
EntryResult CreateEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) override;
};
class MockBackendNoCbFactory : public HttpCache::BackendFactory {
public:
disk_cache::BackendResult CreateBackend(
NetLog* net_log,
disk_cache::BackendResultCallback callback) override;
};
class MockBlockingBackendFactory : public HttpCache::BackendFactory {
public:
MockBlockingBackendFactory();
~MockBlockingBackendFactory() override;
disk_cache::BackendResult CreateBackend(
NetLog* net_log,
disk_cache::BackendResultCallback callback) override;
void FinishCreation();
void set_fail(bool fail) { fail_ = fail; }
disk_cache::BackendResultCallback ReleaseCallback() {
return std::move(callback_);
}
private:
disk_cache::BackendResult MakeResult();
disk_cache::BackendResultCallback callback_;
bool block_ = true;
bool fail_ = false;
};
}
#endif