| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // This is a mock of the http cache and related testing classes. To be fair, it |
| // is not really a mock http cache given that it uses the real implementation of |
| // the http cache, but it has fake implementations of all required components, |
| // so it is useful for unit tests at the http layer. |
| |
| #ifndef NET_HTTP_MOCK_HTTP_CACHE_H_ |
| #define NET_HTTP_MOCK_HTTP_CACHE_H_ |
| |
| #include "base/hash_tables.h" |
| #include "net/disk_cache/disk_cache.h" |
| #include "net/http/http_cache.h" |
| #include "net/http/http_transaction_unittest.h" |
| |
| //----------------------------------------------------------------------------- |
| // Mock disk cache (a very basic memory cache implementation). |
| |
| class MockDiskEntry : public disk_cache::Entry, |
| public base::RefCounted<MockDiskEntry> { |
| public: |
| MockDiskEntry(); |
| explicit MockDiskEntry(const std::string& key); |
| |
| bool is_doomed() const { return doomed_; } |
| |
| virtual void Doom() override; |
| virtual void Close() override; |
| virtual std::string GetKey() const override; |
| virtual base::Time GetLastUsed() const override; |
| virtual base::Time GetLastModified() const override; |
| virtual int32 GetDataSize(int index) const override; |
| virtual int ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, |
| const net::CompletionCallback& callback) override; |
| virtual int WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, |
| const net::CompletionCallback& callback, |
| bool truncate) override; |
| virtual int ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| const net::CompletionCallback& callback) override; |
| virtual int WriteSparseData( |
| int64 offset, net::IOBuffer* buf, int buf_len, |
| const net::CompletionCallback& callback) override; |
| virtual int GetAvailableRange( |
| int64 offset, int len, int64* start, |
| const net::CompletionCallback& callback) override; |
| virtual bool CouldBeSparse() const override; |
| virtual void CancelSparseIO() override; |
| virtual int ReadyForSparseIO( |
| const net::CompletionCallback& completion_callback) override; |
| |
| // Fail most subsequent requests. |
| void set_fail_requests() { fail_requests_ = true; } |
| |
| // If |value| is true, don't deliver any completion callbacks until called |
| // again with |value| set to false. Caution: remember to enable callbacks |
| // again or all subsequent tests will fail. |
| static void IgnoreCallbacks(bool value); |
| |
| private: |
| friend class base::RefCounted<MockDiskEntry>; |
| struct CallbackInfo; |
| |
| virtual ~MockDiskEntry(); |
| |
| // Unlike the callbacks for MockHttpTransaction, we want this one to run even |
| // if the consumer called Close on the MockDiskEntry. We achieve that by |
| // leveraging the fact that this class is reference counted. |
| void CallbackLater(const net::CompletionCallback& callback, int result); |
| |
| void RunCallback(const net::CompletionCallback& callback, int result); |
| |
| // When |store| is true, stores the callback to be delivered later; otherwise |
| // delivers any callback previously stored. |
| static void StoreAndDeliverCallbacks(bool store, MockDiskEntry* entry, |
| const net::CompletionCallback& callback, |
| int result); |
| |
| static const int kNumCacheEntryDataIndices = 3; |
| |
| std::string key_; |
| std::vector<char> data_[kNumCacheEntryDataIndices]; |
| int test_mode_; |
| bool doomed_; |
| bool sparse_; |
| bool fail_requests_; |
| bool busy_; |
| bool delayed_; |
| static bool cancel_; |
| static bool ignore_callbacks_; |
| }; |
| |
| class MockDiskCache : public disk_cache::Backend { |
| public: |
| MockDiskCache(); |
| virtual ~MockDiskCache(); |
| |
| virtual net::CacheType GetCacheType() const override; |
| virtual int32 GetEntryCount() const override; |
| virtual int OpenEntry(const std::string& key, disk_cache::Entry** entry, |
| const net::CompletionCallback& callback) override; |
| virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, |
| const net::CompletionCallback& callback) override; |
| virtual int DoomEntry(const std::string& key, |
| const net::CompletionCallback& callback) override; |
| virtual int DoomAllEntries(const net::CompletionCallback& callback) override; |
| virtual int DoomEntriesBetween( |
| const base::Time initial_time, |
| const base::Time end_time, |
| const net::CompletionCallback& callback) override; |
| virtual int DoomEntriesSince( |
| const base::Time initial_time, |
| const net::CompletionCallback& callback) override; |
| virtual int OpenNextEntry(void** iter, disk_cache::Entry** next_entry, |
| const net::CompletionCallback& callback) override; |
| virtual void EndEnumeration(void** iter) override; |
| virtual void GetStats( |
| std::vector<std::pair<std::string, std::string> >* stats) override; |
| virtual void OnExternalCacheHit(const std::string& key) override; |
| |
| // Returns number of times a cache entry was successfully opened. |
| int open_count() const { return open_count_; } |
| |
| // Returns number of times a cache entry was successfully created. |
| int create_count() const { return create_count_; } |
| |
| // Fail any subsequent CreateEntry and OpenEntry. |
| void set_fail_requests() { fail_requests_ = true; } |
| |
| // Return entries that fail some of their requests. |
| void set_soft_failures(bool value) { soft_failures_ = value; } |
| |
| // Makes sure that CreateEntry is not called twice for a given key. |
| void set_double_create_check(bool value) { double_create_check_ = value; } |
| |
| void ReleaseAll(); |
| |
| private: |
| typedef base::hash_map<std::string, MockDiskEntry*> EntryMap; |
| |
| void CallbackLater(const net::CompletionCallback& callback, int result); |
| |
| EntryMap entries_; |
| int open_count_; |
| int create_count_; |
| bool fail_requests_; |
| bool soft_failures_; |
| bool double_create_check_; |
| }; |
| |
| class MockBackendFactory : public net::HttpCache::BackendFactory { |
| public: |
| virtual int CreateBackend(net::NetLog* net_log, |
| disk_cache::Backend** backend, |
| const net::CompletionCallback& callback) override; |
| }; |
| |
| class MockHttpCache { |
| public: |
| MockHttpCache(); |
| explicit MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory); |
| |
| net::HttpCache* http_cache() { return &http_cache_; } |
| |
| MockNetworkLayer* network_layer() { |
| return static_cast<MockNetworkLayer*>(http_cache_.network_layer()); |
| } |
| MockDiskCache* disk_cache(); |
| |
| // Helper function for reading response info from the disk cache. |
| static bool ReadResponseInfo(disk_cache::Entry* disk_entry, |
| net::HttpResponseInfo* response_info, |
| bool* response_truncated); |
| |
| // Helper function for writing response info into the disk cache. |
| static bool WriteResponseInfo(disk_cache::Entry* disk_entry, |
| const net::HttpResponseInfo* response_info, |
| bool skip_transient_headers, |
| bool response_truncated); |
| |
| // Helper function to synchronously open a backend entry. |
| bool OpenBackendEntry(const std::string& key, disk_cache::Entry** entry); |
| |
| // Helper function to synchronously create a backend entry. |
| bool CreateBackendEntry(const std::string& key, disk_cache::Entry** entry, |
| net::NetLog* net_log); |
| |
| // Returns the test mode after considering the global override. |
| static int GetTestMode(int test_mode); |
| |
| // Overrides the test mode for a given operation. Remember to reset it after |
| // the test! (by setting test_mode to zero). |
| static void SetTestMode(int test_mode); |
| |
| private: |
| net::HttpCache http_cache_; |
| }; |
| |
| // This version of the disk cache doesn't invoke CreateEntry callbacks. |
| class MockDiskCacheNoCB : public MockDiskCache { |
| virtual int CreateEntry(const std::string& key, disk_cache::Entry** entry, |
| const net::CompletionCallback& callback) override; |
| }; |
| |
| class MockBackendNoCbFactory : public net::HttpCache::BackendFactory { |
| public: |
| virtual int CreateBackend(net::NetLog* net_log, |
| disk_cache::Backend** backend, |
| const net::CompletionCallback& callback) override; |
| }; |
| |
| // This backend factory allows us to control the backend instantiation. |
| class MockBlockingBackendFactory : public net::HttpCache::BackendFactory { |
| public: |
| MockBlockingBackendFactory(); |
| virtual ~MockBlockingBackendFactory(); |
| |
| virtual int CreateBackend(net::NetLog* net_log, |
| disk_cache::Backend** backend, |
| const net::CompletionCallback& callback) override; |
| |
| // Completes the backend creation. Any blocked call will be notified via the |
| // provided callback. |
| void FinishCreation(); |
| |
| disk_cache::Backend** backend() { return backend_; } |
| void set_fail(bool fail) { fail_ = fail; } |
| |
| const net::CompletionCallback& callback() { return callback_; } |
| |
| private: |
| int Result() { return fail_ ? net::ERR_FAILED : net::OK; } |
| |
| disk_cache::Backend** backend_; |
| net::CompletionCallback callback_; |
| bool block_; |
| bool fail_; |
| }; |
| |
| #endif // NET_HTTP_MOCK_HTTP_CACHE_H_ |