Home | History | Annotate | Download | only in http
      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 
     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 
     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.
    123   int open_count() const { return open_count_; }
    124 
    125   // Returns number of times a cache entry was successfully created.
    126   int create_count() const { return create_count_; }
    127 
    128   // Fail any subsequent CreateEntry and OpenEntry.
    129   void set_fail_requests() { fail_requests_ = true; }
    130 
    131   // Return entries that fail some of their requests.
    132   void set_soft_failures(bool value) { soft_failures_ = value; }
    133 
    134   // Makes sure that CreateEntry is not called twice for a given key.
    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.
    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 
    169   net::HttpCache* http_cache() { return &http_cache_; }
    170 
    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 
    238   scoped_ptr<disk_cache::Backend>* backend() { return backend_; }
    239   void set_fail(bool fail) { fail_ = fail; }
    240 
    241   const net::CompletionCallback& callback() { return callback_; }
    242 
    243  private:
    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