mock_http_cache.h revision 116680a4aac90f2aa7413d9095a592090648e557
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
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 "base/containers/hash_tables.h"
14#include "net/disk_cache/disk_cache.h"
15#include "net/http/http_cache.h"
16#include "net/http/http_transaction_test_util.h"
17
18//-----------------------------------------------------------------------------
19// Mock disk cache (a very basic memory cache implementation).
20
21class MockDiskEntry : public disk_cache::Entry,
22                      public base::RefCounted<MockDiskEntry> {
23 public:
24  explicit MockDiskEntry(const std::string& key);
25
26  bool is_doomed() const { return doomed_; }
27
28  virtual void Doom() OVERRIDE;
29  virtual void Close() OVERRIDE;
30  virtual std::string GetKey() const OVERRIDE;
31  virtual base::Time GetLastUsed() const OVERRIDE;
32  virtual base::Time GetLastModified() const OVERRIDE;
33  virtual int32 GetDataSize(int index) const OVERRIDE;
34  virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len,
35                       const net::CompletionCallback& callback) OVERRIDE;
36  virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len,
37                        const net::CompletionCallback& callback,
38                        bool truncate) OVERRIDE;
39  virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
40                             const net::CompletionCallback& callback) OVERRIDE;
41  virtual int WriteSparseData(
42      int64 offset, net::IOBuffer* buf, int buf_len,
43      const net::CompletionCallback& callback) OVERRIDE;
44  virtual int GetAvailableRange(
45      int64 offset, int len, int64* start,
46      const net::CompletionCallback& callback) OVERRIDE;
47  virtual bool CouldBeSparse() const OVERRIDE;
48  virtual void CancelSparseIO() OVERRIDE;
49  virtual int ReadyForSparseIO(
50      const net::CompletionCallback& completion_callback) OVERRIDE;
51
52  // Fail most subsequent requests.
53  void set_fail_requests() { fail_requests_ = true; }
54
55  void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
56
57  // If |value| is true, don't deliver any completion callbacks until called
58  // again with |value| set to false.  Caution: remember to enable callbacks
59  // again or all subsequent tests will fail.
60  static void IgnoreCallbacks(bool value);
61
62 private:
63  friend class base::RefCounted<MockDiskEntry>;
64  struct CallbackInfo;
65
66  virtual ~MockDiskEntry();
67
68  // Unlike the callbacks for MockHttpTransaction, we want this one to run even
69  // if the consumer called Close on the MockDiskEntry.  We achieve that by
70  // leveraging the fact that this class is reference counted.
71  void CallbackLater(const net::CompletionCallback& callback, int result);
72
73  void RunCallback(const net::CompletionCallback& callback, int result);
74
75  // When |store| is true, stores the callback to be delivered later; otherwise
76  // delivers any callback previously stored.
77  static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry,
78                                       const net::CompletionCallback& callback,
79                                       int result);
80
81  static const int kNumCacheEntryDataIndices = 3;
82
83  std::string key_;
84  std::vector<char> data_[kNumCacheEntryDataIndices];
85  int test_mode_;
86  bool doomed_;
87  bool sparse_;
88  bool fail_requests_;
89  bool fail_sparse_requests_;
90  bool busy_;
91  bool delayed_;
92  static bool cancel_;
93  static bool ignore_callbacks_;
94};
95
96class MockDiskCache : public disk_cache::Backend {
97 public:
98  MockDiskCache();
99  virtual ~MockDiskCache();
100
101  virtual net::CacheType GetCacheType() const OVERRIDE;
102  virtual int32 GetEntryCount() const OVERRIDE;
103  virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry,
104                        const net::CompletionCallback& callback) OVERRIDE;
105  virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
106                          const net::CompletionCallback& callback) OVERRIDE;
107  virtual int DoomEntry(const std::string& key,
108                        const net::CompletionCallback& callback) OVERRIDE;
109  virtual int DoomAllEntries(const net::CompletionCallback& callback) OVERRIDE;
110  virtual int DoomEntriesBetween(
111      base::Time initial_time,
112      base::Time end_time,
113      const net::CompletionCallback& callback) OVERRIDE;
114  virtual int DoomEntriesSince(
115      base::Time initial_time,
116      const net::CompletionCallback& callback) OVERRIDE;
117  virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry,
118                            const net::CompletionCallback& callback) OVERRIDE;
119  virtual void EndEnumeration(void** iter) OVERRIDE;
120  virtual void GetStats(
121      std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE;
122  virtual void OnExternalCacheHit(const std::string& key) OVERRIDE;
123
124  // Returns number of times a cache entry was successfully opened.
125  int open_count() const { return open_count_; }
126
127  // Returns number of times a cache entry was successfully created.
128  int create_count() const { return create_count_; }
129
130  // Fail any subsequent CreateEntry and OpenEntry.
131  void set_fail_requests() { fail_requests_ = true; }
132
133  // Return entries that fail some of their requests.
134  void set_soft_failures(bool value) { soft_failures_ = value; }
135
136  // Makes sure that CreateEntry is not called twice for a given key.
137  void set_double_create_check(bool value) { double_create_check_ = value; }
138
139  // Makes all requests for data ranges to fail as not implemented.
140  void set_fail_sparse_requests() { fail_sparse_requests_ = true; }
141
142  void ReleaseAll();
143
144 private:
145  typedef base::hash_map<std::string, MockDiskEntry*> EntryMap;
146
147  void CallbackLater(const net::CompletionCallback& callback, int result);
148
149  EntryMap entries_;
150  int open_count_;
151  int create_count_;
152  bool fail_requests_;
153  bool soft_failures_;
154  bool double_create_check_;
155  bool fail_sparse_requests_;
156};
157
158class MockBackendFactory : public net::HttpCache::BackendFactory {
159 public:
160  virtual int CreateBackend(net::NetLog* net_log,
161                            scoped_ptr<disk_cache::Backend>* backend,
162                            const net::CompletionCallback& callback) OVERRIDE;
163};
164
165class MockHttpCache {
166 public:
167  MockHttpCache();
168  explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory);
169
170  net::HttpCache* http_cache() { return &http_cache_; }
171
172  MockNetworkLayer* network_layer() {
173    return static_cast<MockNetworkLayer*>(http_cache_.network_layer());
174  }
175  MockDiskCache* disk_cache();
176
177  // Wrapper around http_cache()->CreateTransaction(net::DEFAULT_PRIORITY...)
178  int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans);
179
180  // Wrapper to bypass the cache lock for new transactions.
181  void BypassCacheLock();
182
183  // Helper function for reading response info from the disk cache.
184  static bool ReadResponseInfo(disk_cache::Entry* disk_entry,
185                               net::HttpResponseInfo* response_info,
186                               bool* response_truncated);
187
188  // Helper function for writing response info into the disk cache.
189  static bool WriteResponseInfo(disk_cache::Entry* disk_entry,
190                                const net::HttpResponseInfo* response_info,
191                                bool skip_transient_headers,
192                                bool response_truncated);
193
194  // Helper function to synchronously open a backend entry.
195  bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry);
196
197  // Helper function to synchronously create a backend entry.
198  bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry,
199                          net::NetLog* net_log);
200
201  // Returns the test mode after considering the global override.
202  static int GetTestMode(int test_mode);
203
204  // Overrides the test mode for a given operation. Remember to reset it after
205  // the test! (by setting test_mode to zero).
206  static void SetTestMode(int test_mode);
207
208 private:
209  net::HttpCache http_cache_;
210};
211
212// This version of the disk cache doesn't invoke CreateEntry callbacks.
213class MockDiskCacheNoCB : public MockDiskCache {
214  virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry,
215                          const net::CompletionCallback& callback) OVERRIDE;
216};
217
218class MockBackendNoCbFactory : public net::HttpCache::BackendFactory {
219 public:
220  virtual int CreateBackend(net::NetLog* net_log,
221                            scoped_ptr<disk_cache::Backend>* backend,
222                            const net::CompletionCallback& callback) OVERRIDE;
223};
224
225// This backend factory allows us to control the backend instantiation.
226class MockBlockingBackendFactory : public net::HttpCache::BackendFactory {
227 public:
228  MockBlockingBackendFactory();
229  virtual ~MockBlockingBackendFactory();
230
231  virtual int CreateBackend(net::NetLog* net_log,
232                            scoped_ptr<disk_cache::Backend>* backend,
233                            const net::CompletionCallback& callback) OVERRIDE;
234
235  // Completes the backend creation. Any blocked call will be notified via the
236  // provided callback.
237  void FinishCreation();
238
239  scoped_ptr<disk_cache::Backend>* backend() { return backend_; }
240  void set_fail(bool fail) { fail_ = fail; }
241
242  const net::CompletionCallback& callback() { return callback_; }
243
244 private:
245  int Result() { return fail_ ? net::ERR_FAILED : net::OK; }
246
247  scoped_ptr<disk_cache::Backend>* backend_;
248  net::CompletionCallback callback_;
249  bool block_;
250  bool fail_;
251};
252
253#endif  // NET_HTTP_MOCK_HTTP_CACHE_H_
254