mock_http_cache.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. // This is a mock of the http cache and related testing classes. To be fair, it
  5. // is not really a mock http cache given that it uses the real implementation of
  6. // the http cache, but it has fake implementations of all required components,
  7. // so it is useful for unit tests at the http layer.
  8. #ifndef NET_HTTP_MOCK_HTTP_CACHE_H_
  9. #define NET_HTTP_MOCK_HTTP_CACHE_H_
  10. #include <stdint.h>
  11. #include <map>
  12. #include <memory>
  13. #include <string>
  14. #include <utility>
  15. #include <vector>
  16. #include "base/memory/raw_ptr.h"
  17. #include "base/strings/string_split.h"
  18. #include "net/base/completion_once_callback.h"
  19. #include "net/base/request_priority.h"
  20. #include "net/disk_cache/disk_cache.h"
  21. #include "net/http/http_cache.h"
  22. #include "net/http/http_transaction_test_util.h"
  23. namespace net {
  24. //-----------------------------------------------------------------------------
  25. // Mock disk cache (a very basic memory cache implementation).
  26. class MockDiskEntry : public disk_cache::Entry,
  27. public base::RefCounted<MockDiskEntry> {
  28. public:
  29. enum DeferOp {
  30. DEFER_NONE,
  31. DEFER_CREATE,
  32. DEFER_READ,
  33. DEFER_WRITE,
  34. };
  35. // Bit mask used for set_fail_requests().
  36. enum FailOp {
  37. FAIL_READ = 0x01,
  38. FAIL_WRITE = 0x02,
  39. FAIL_READ_SPARSE = 0x04,
  40. FAIL_WRITE_SPARSE = 0x08,
  41. FAIL_GET_AVAILABLE_RANGE = 0x10,
  42. FAIL_ALL = 0xFF
  43. };
  44. explicit MockDiskEntry(const std::string& key);
  45. bool is_doomed() const { return doomed_; }
  46. void Doom() override;
  47. void Close() override;
  48. std::string GetKey() const override;
  49. base::Time GetLastUsed() const override;
  50. base::Time GetLastModified() const override;
  51. int32_t GetDataSize(int index) const override;
  52. int ReadData(int index,
  53. int offset,
  54. IOBuffer* buf,
  55. int buf_len,
  56. CompletionOnceCallback callback) override;
  57. int WriteData(int index,
  58. int offset,
  59. IOBuffer* buf,
  60. int buf_len,
  61. CompletionOnceCallback callback,
  62. bool truncate) override;
  63. int ReadSparseData(int64_t offset,
  64. IOBuffer* buf,
  65. int buf_len,
  66. CompletionOnceCallback callback) override;
  67. int WriteSparseData(int64_t offset,
  68. IOBuffer* buf,
  69. int buf_len,
  70. CompletionOnceCallback callback) override;
  71. RangeResult GetAvailableRange(int64_t offset,
  72. int len,
  73. RangeResultCallback callback) override;
  74. bool CouldBeSparse() const override;
  75. void CancelSparseIO() override;
  76. net::Error ReadyForSparseIO(
  77. CompletionOnceCallback completion_callback) override;
  78. void SetLastUsedTimeForTest(base::Time time) override;
  79. uint8_t in_memory_data() const { return in_memory_data_; }
  80. void set_in_memory_data(uint8_t val) { in_memory_data_ = val; }
  81. // Fail subsequent requests, specified via FailOp bits.
  82. void set_fail_requests(int mask) { fail_requests_ = mask; }
  83. void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
  84. // If |value| is true, don't deliver any completion callbacks until called
  85. // again with |value| set to false. Caution: remember to enable callbacks
  86. // again or all subsequent tests will fail.
  87. static void IgnoreCallbacks(bool value);
  88. // Defers invoking the callback for the given operation. Calling code should
  89. // invoke ResumeDiskEntryOperation to resume.
  90. void SetDefer(DeferOp defer_op) { defer_op_ = defer_op; }
  91. // Resumes deferred cache operation by posting |resume_callback_| with
  92. // |resume_return_code_|.
  93. void ResumeDiskEntryOperation();
  94. // Sets the maximum length of a stream. This is only applied to stream 1.
  95. void set_max_file_size(int val) { max_file_size_ = val; }
  96. private:
  97. friend class base::RefCounted<MockDiskEntry>;
  98. struct CallbackInfo;
  99. ~MockDiskEntry() override;
  100. // Unlike the callbacks for MockHttpTransaction, we want this one to run even
  101. // if the consumer called Close on the MockDiskEntry. We achieve that by
  102. // leveraging the fact that this class is reference counted.
  103. void CallbackLater(CompletionOnceCallback callback, int result);
  104. void CallbackLater(base::OnceClosure callback);
  105. void RunCallback(base::OnceClosure callback);
  106. // When |store| is true, stores the callback to be delivered later; otherwise
  107. // delivers any callback previously stored.
  108. static void StoreAndDeliverCallbacks(bool store,
  109. MockDiskEntry* entry,
  110. base::OnceClosure callback);
  111. static const int kNumCacheEntryDataIndices = 3;
  112. std::string key_;
  113. std::vector<char> data_[kNumCacheEntryDataIndices];
  114. uint8_t in_memory_data_ = 0;
  115. int test_mode_;
  116. int max_file_size_;
  117. bool doomed_ = false;
  118. bool sparse_ = false;
  119. int fail_requests_ = 0;
  120. bool fail_sparse_requests_ = false;
  121. bool busy_ = false;
  122. bool delayed_ = false;
  123. bool cancel_ = false;
  124. // Used for pause and restart.
  125. DeferOp defer_op_ = DEFER_NONE;
  126. CompletionOnceCallback resume_callback_;
  127. int resume_return_code_ = 0;
  128. static bool ignore_callbacks_;
  129. };
  130. class MockDiskCache : public disk_cache::Backend {
  131. public:
  132. MockDiskCache();
  133. ~MockDiskCache() override;
  134. int32_t GetEntryCount() const override;
  135. EntryResult OpenOrCreateEntry(const std::string& key,
  136. net::RequestPriority request_priority,
  137. EntryResultCallback callback) override;
  138. EntryResult OpenEntry(const std::string& key,
  139. net::RequestPriority request_priority,
  140. EntryResultCallback callback) override;
  141. EntryResult CreateEntry(const std::string& key,
  142. net::RequestPriority request_priority,
  143. EntryResultCallback callback) override;
  144. net::Error DoomEntry(const std::string& key,
  145. net::RequestPriority request_priority,
  146. CompletionOnceCallback callback) override;
  147. net::Error DoomAllEntries(CompletionOnceCallback callback) override;
  148. net::Error DoomEntriesBetween(base::Time initial_time,
  149. base::Time end_time,
  150. CompletionOnceCallback callback) override;
  151. net::Error DoomEntriesSince(base::Time initial_time,
  152. CompletionOnceCallback callback) override;
  153. int64_t CalculateSizeOfAllEntries(
  154. Int64CompletionOnceCallback callback) override;
  155. std::unique_ptr<Iterator> CreateIterator() override;
  156. void GetStats(base::StringPairs* stats) override;
  157. void OnExternalCacheHit(const std::string& key) override;
  158. uint8_t GetEntryInMemoryData(const std::string& key) override;
  159. void SetEntryInMemoryData(const std::string& key, uint8_t data) override;
  160. int64_t MaxFileSize() const override;
  161. // Returns number of times a cache entry was successfully opened.
  162. int open_count() const { return open_count_; }
  163. // Returns number of times a cache entry was successfully created.
  164. int create_count() const { return create_count_; }
  165. // Returns number of doomed entries.
  166. int doomed_count() const { return doomed_count_; }
  167. // Fail any subsequent CreateEntry, OpenEntry, and DoomEntry
  168. void set_fail_requests(bool value) { fail_requests_ = value; }
  169. // Return entries that fail some of their requests.
  170. // The value is formed as a bitmask of MockDiskEntry::FailOp.
  171. void set_soft_failures_mask(int value) { soft_failures_ = value; }
  172. // Returns entries that fail some of their requests, but only until
  173. // the entry is re-created. The value is formed as a bitmask of
  174. // MockDiskEntry::FailOp.
  175. void set_soft_failures_one_instance(int value) {
  176. soft_failures_one_instance_ = value;
  177. }
  178. // Makes sure that CreateEntry is not called twice for a given key.
  179. void set_double_create_check(bool value) { double_create_check_ = value; }
  180. // Determines whether to provide the GetEntryInMemoryData/SetEntryInMemoryData
  181. // interface. Default is true.
  182. void set_support_in_memory_entry_data(bool value) {
  183. support_in_memory_entry_data_ = value;
  184. }
  185. // OpenEntry, CreateEntry, and DoomEntry immediately return with
  186. // ERR_IO_PENDING and will callback some time later with an error.
  187. void set_force_fail_callback_later(bool value) {
  188. force_fail_callback_later_ = value;
  189. }
  190. // Makes all requests for data ranges to fail as not implemented.
  191. void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
  192. // Sets the limit on how big entry streams can get. Only stream 1 enforces
  193. // this, but MaxFileSize() will still report it.
  194. void set_max_file_size(int new_size) { max_file_size_ = new_size; }
  195. void ReleaseAll();
  196. // Returns true if a doomed entry exists with this key.
  197. bool IsDiskEntryDoomed(const std::string& key);
  198. // Defers invoking the callback for the given operation. Calling code should
  199. // invoke ResumeCacheOperation to resume.
  200. void SetDefer(MockDiskEntry::DeferOp defer_op) { defer_op_ = defer_op; }
  201. // Resume deferred cache operation by posting |resume_callback_| with
  202. // |resume_return_code_|.
  203. void ResumeCacheOperation();
  204. // Returns a reference to the disk entry with the given |key|.
  205. scoped_refptr<MockDiskEntry> GetDiskEntryRef(const std::string& key);
  206. // Returns a reference to the vector storing all keys for external cache hits.
  207. const std::vector<std::string>& GetExternalCacheHits() const;
  208. private:
  209. using EntryMap = std::map<std::string, MockDiskEntry*>;
  210. class NotImplementedIterator;
  211. void CallbackLater(base::OnceClosure callback);
  212. EntryMap entries_;
  213. std::vector<std::string> external_cache_hits_;
  214. int open_count_ = 0;
  215. int create_count_ = 0;
  216. int doomed_count_ = 0;
  217. int max_file_size_;
  218. bool fail_requests_ = false;
  219. int soft_failures_ = 0;
  220. int soft_failures_one_instance_ = 0;
  221. bool double_create_check_ = true;
  222. bool fail_sparse_requests_ = false;
  223. bool support_in_memory_entry_data_ = true;
  224. bool force_fail_callback_later_ = false;
  225. // Used for pause and restart.
  226. MockDiskEntry::DeferOp defer_op_ = MockDiskEntry::DEFER_NONE;
  227. base::OnceClosure resume_callback_;
  228. };
  229. class MockBackendFactory : public HttpCache::BackendFactory {
  230. public:
  231. disk_cache::BackendResult CreateBackend(
  232. NetLog* net_log,
  233. disk_cache::BackendResultCallback callback) override;
  234. };
  235. class MockHttpCache {
  236. public:
  237. MockHttpCache();
  238. explicit MockHttpCache(
  239. std::unique_ptr<HttpCache::BackendFactory> disk_cache_factory);
  240. HttpCache* http_cache() { return &http_cache_; }
  241. MockNetworkLayer* network_layer() {
  242. return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
  243. }
  244. disk_cache::Backend* backend();
  245. MockDiskCache* disk_cache();
  246. // Wrapper around http_cache()->CreateTransaction(DEFAULT_PRIORITY...)
  247. int CreateTransaction(std::unique_ptr<HttpTransaction>* trans);
  248. // Wrapper to simulate cache lock timeout for new transactions.
  249. void SimulateCacheLockTimeout();
  250. // Wrapper to simulate cache lock timeout for new transactions.
  251. void SimulateCacheLockTimeoutAfterHeaders();
  252. // Wrapper to fail request conditionalization for new transactions.
  253. void FailConditionalizations();
  254. // Helper function for reading response info from the disk cache.
  255. static bool ReadResponseInfo(disk_cache::Entry* disk_entry,
  256. HttpResponseInfo* response_info,
  257. bool* response_truncated);
  258. // Helper function for writing response info into the disk cache.
  259. static bool WriteResponseInfo(disk_cache::Entry* disk_entry,
  260. const HttpResponseInfo* response_info,
  261. bool skip_transient_headers,
  262. bool response_truncated);
  263. // Helper function to synchronously open a backend entry.
  264. bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry);
  265. // Helper function to synchronously create a backend entry.
  266. bool CreateBackendEntry(const std::string& key,
  267. disk_cache::Entry** entry,
  268. NetLog* net_log);
  269. // Returns the test mode after considering the global override.
  270. static int GetTestMode(int test_mode);
  271. // Overrides the test mode for a given operation. Remember to reset it after
  272. // the test! (by setting test_mode to zero).
  273. static void SetTestMode(int test_mode);
  274. // Functions to test the state of ActiveEntry.
  275. bool IsWriterPresent(const std::string& key);
  276. bool IsHeadersTransactionPresent(const std::string& key);
  277. int GetCountReaders(const std::string& key);
  278. int GetCountAddToEntryQueue(const std::string& key);
  279. int GetCountDoneHeadersQueue(const std::string& key);
  280. int GetCountWriterTransactions(const std::string& key);
  281. private:
  282. HttpCache http_cache_;
  283. };
  284. // This version of the disk cache doesn't invoke CreateEntry callbacks.
  285. class MockDiskCacheNoCB : public MockDiskCache {
  286. EntryResult CreateEntry(const std::string& key,
  287. net::RequestPriority request_priority,
  288. EntryResultCallback callback) override;
  289. };
  290. class MockBackendNoCbFactory : public HttpCache::BackendFactory {
  291. public:
  292. disk_cache::BackendResult CreateBackend(
  293. NetLog* net_log,
  294. disk_cache::BackendResultCallback callback) override;
  295. };
  296. // This backend factory allows us to control the backend instantiation.
  297. class MockBlockingBackendFactory : public HttpCache::BackendFactory {
  298. public:
  299. MockBlockingBackendFactory();
  300. ~MockBlockingBackendFactory() override;
  301. disk_cache::BackendResult CreateBackend(
  302. NetLog* net_log,
  303. disk_cache::BackendResultCallback callback) override;
  304. // Completes the backend creation. Any blocked call will be notified via the
  305. // provided callback.
  306. void FinishCreation();
  307. void set_fail(bool fail) { fail_ = fail; }
  308. disk_cache::BackendResultCallback ReleaseCallback() {
  309. return std::move(callback_);
  310. }
  311. private:
  312. disk_cache::BackendResult MakeResult();
  313. disk_cache::BackendResultCallback callback_;
  314. bool block_ = true;
  315. bool fail_ = false;
  316. };
  317. } // namespace net
  318. #endif // NET_HTTP_MOCK_HTTP_CACHE_H_