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 21 class MockDiskEntry : public disk_cache::Entry, 22 public base::RefCounted<MockDiskEntry> { 23 public: 24 explicit MockDiskEntry(const std::string& key); 25 is_doomed()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. set_fail_requests()53 void set_fail_requests() { fail_requests_ = true; } 54 set_fail_sparse_requests()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 96 class 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 scoped_ptr<Iterator> CreateIterator() OVERRIDE; 118 virtual void GetStats( 119 std::vector<std::pair<std::string, std::string> >* stats) OVERRIDE; 120 virtual void OnExternalCacheHit(const std::string& key) OVERRIDE; 121 122 // Returns number of times a cache entry was successfully opened. open_count()123 int open_count() const { return open_count_; } 124 125 // Returns number of times a cache entry was successfully created. create_count()126 int create_count() const { return create_count_; } 127 128 // Fail any subsequent CreateEntry and OpenEntry. set_fail_requests()129 void set_fail_requests() { fail_requests_ = true; } 130 131 // Return entries that fail some of their requests. set_soft_failures(bool value)132 void set_soft_failures(bool value) { soft_failures_ = value; } 133 134 // Makes sure that CreateEntry is not called twice for a given key. set_double_create_check(bool value)135 void set_double_create_check(bool value) { double_create_check_ = value; } 136 137 // Makes all requests for data ranges to fail as not implemented. set_fail_sparse_requests()138 void set_fail_sparse_requests() { fail_sparse_requests_ = true; } 139 140 void ReleaseAll(); 141 142 private: 143 typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; 144 class NotImplementedIterator; 145 146 void CallbackLater(const net::CompletionCallback& callback, int result); 147 148 EntryMap entries_; 149 int open_count_; 150 int create_count_; 151 bool fail_requests_; 152 bool soft_failures_; 153 bool double_create_check_; 154 bool fail_sparse_requests_; 155 }; 156 157 class MockBackendFactory : public net::HttpCache::BackendFactory { 158 public: 159 virtual int CreateBackend(net::NetLog* net_log, 160 scoped_ptr<disk_cache::Backend>* backend, 161 const net::CompletionCallback& callback) OVERRIDE; 162 }; 163 164 class MockHttpCache { 165 public: 166 MockHttpCache(); 167 explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory); 168 http_cache()169 net::HttpCache* http_cache() { return &http_cache_; } 170 network_layer()171 MockNetworkLayer* network_layer() { 172 return static_cast<MockNetworkLayer*>(http_cache_.network_layer()); 173 } 174 MockDiskCache* disk_cache(); 175 176 // Wrapper around http_cache()->CreateTransaction(net::DEFAULT_PRIORITY...) 177 int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans); 178 179 // Wrapper to bypass the cache lock for new transactions. 180 void BypassCacheLock(); 181 182 // Helper function for reading response info from the disk cache. 183 static bool ReadResponseInfo(disk_cache::Entry* disk_entry, 184 net::HttpResponseInfo* response_info, 185 bool* response_truncated); 186 187 // Helper function for writing response info into the disk cache. 188 static bool WriteResponseInfo(disk_cache::Entry* disk_entry, 189 const net::HttpResponseInfo* response_info, 190 bool skip_transient_headers, 191 bool response_truncated); 192 193 // Helper function to synchronously open a backend entry. 194 bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry); 195 196 // Helper function to synchronously create a backend entry. 197 bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry, 198 net::NetLog* net_log); 199 200 // Returns the test mode after considering the global override. 201 static int GetTestMode(int test_mode); 202 203 // Overrides the test mode for a given operation. Remember to reset it after 204 // the test! (by setting test_mode to zero). 205 static void SetTestMode(int test_mode); 206 207 private: 208 net::HttpCache http_cache_; 209 }; 210 211 // This version of the disk cache doesn't invoke CreateEntry callbacks. 212 class MockDiskCacheNoCB : public MockDiskCache { 213 virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, 214 const net::CompletionCallback& callback) OVERRIDE; 215 }; 216 217 class MockBackendNoCbFactory : public net::HttpCache::BackendFactory { 218 public: 219 virtual int CreateBackend(net::NetLog* net_log, 220 scoped_ptr<disk_cache::Backend>* backend, 221 const net::CompletionCallback& callback) OVERRIDE; 222 }; 223 224 // This backend factory allows us to control the backend instantiation. 225 class MockBlockingBackendFactory : public net::HttpCache::BackendFactory { 226 public: 227 MockBlockingBackendFactory(); 228 virtual ~MockBlockingBackendFactory(); 229 230 virtual int CreateBackend(net::NetLog* net_log, 231 scoped_ptr<disk_cache::Backend>* backend, 232 const net::CompletionCallback& callback) OVERRIDE; 233 234 // Completes the backend creation. Any blocked call will be notified via the 235 // provided callback. 236 void FinishCreation(); 237 backend()238 scoped_ptr<disk_cache::Backend>* backend() { return backend_; } set_fail(bool fail)239 void set_fail(bool fail) { fail_ = fail; } 240 callback()241 const net::CompletionCallback& callback() { return callback_; } 242 243 private: Result()244 int Result() { return fail_ ? net::ERR_FAILED : net::OK; } 245 246 scoped_ptr<disk_cache::Backend>* backend_; 247 net::CompletionCallback callback_; 248 bool block_; 249 bool fail_; 250 }; 251 252 #endif // NET_HTTP_MOCK_HTTP_CACHE_H_ 253