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