1 // Copyright 2012 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 #ifndef NET_DISK_CACHE_DISK_CACHE_TEST_UTIL_H_ 6 #define NET_DISK_CACHE_DISK_CACHE_TEST_UTIL_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <string> 12 13 #include "base/files/file_path.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/memory/scoped_refptr.h" 16 #include "base/run_loop.h" 17 #include "base/timer/timer.h" 18 #include "build/build_config.h" 19 #include "net/base/test_completion_callback.h" 20 #include "net/disk_cache/disk_cache.h" 21 22 namespace net { 23 class IOBufferWithSize; 24 } // namespace net 25 26 // Re-creates a given test file inside the cache test folder. 27 bool CreateCacheTestFile(const base::FilePath& name); 28 29 // Deletes all file son the cache. 30 bool DeleteCache(const base::FilePath& path); 31 32 // Fills buffer with random values (may contain nulls unless no_nulls is true). 33 void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls); 34 35 // Creates a buffer of size `len`, and fills in with random values, which 36 // may contain 0 unless `no_nulls` is true. 37 scoped_refptr<net::IOBufferWithSize> CacheTestCreateAndFillBuffer( 38 size_t len, 39 bool no_nulls); 40 41 // Generates a random key of up to 200 bytes. 42 std::string GenerateKey(bool same_length); 43 44 // Returns true if the cache is not corrupt. Assumes blockfile cache. 45 // |max_size|, if non-zero, will be set as its size. 46 bool CheckCacheIntegrity(const base::FilePath& path, 47 bool new_eviction, 48 int max_size, 49 uint32_t mask); 50 51 // ----------------------------------------------------------------------- 52 53 // Like net::TestCompletionCallback, but for BackendResultCallback. 54 struct BackendResultIsPendingHelper { operatorBackendResultIsPendingHelper55 bool operator()(const disk_cache::BackendResult& result) const { 56 return result.net_error == net::ERR_IO_PENDING; 57 } 58 }; 59 using TestBackendResultCompletionCallbackBase = 60 net::internal::TestCompletionCallbackTemplate<disk_cache::BackendResult, 61 BackendResultIsPendingHelper>; 62 63 class TestBackendResultCompletionCallback 64 : public TestBackendResultCompletionCallbackBase { 65 public: 66 TestBackendResultCompletionCallback(); 67 68 TestBackendResultCompletionCallback( 69 const TestBackendResultCompletionCallback&) = delete; 70 TestBackendResultCompletionCallback& operator=( 71 const TestBackendResultCompletionCallback&) = delete; 72 73 ~TestBackendResultCompletionCallback() override; 74 75 disk_cache::BackendResultCallback callback(); 76 }; 77 78 // Like net::TestCompletionCallback, but for EntryResultCallback. 79 80 struct EntryResultIsPendingHelper { operatorEntryResultIsPendingHelper81 bool operator()(const disk_cache::EntryResult& result) const { 82 return result.net_error() == net::ERR_IO_PENDING; 83 } 84 }; 85 using TestEntryResultCompletionCallbackBase = 86 net::internal::TestCompletionCallbackTemplate<disk_cache::EntryResult, 87 EntryResultIsPendingHelper>; 88 89 class TestEntryResultCompletionCallback 90 : public TestEntryResultCompletionCallbackBase { 91 public: 92 TestEntryResultCompletionCallback(); 93 94 TestEntryResultCompletionCallback(const TestEntryResultCompletionCallback&) = 95 delete; 96 TestEntryResultCompletionCallback& operator=( 97 const TestEntryResultCompletionCallback&) = delete; 98 99 ~TestEntryResultCompletionCallback() override; 100 101 disk_cache::Backend::EntryResultCallback callback(); 102 }; 103 104 // Like net::TestCompletionCallback, but for RangeResultCallback. 105 struct RangeResultIsPendingHelper { operatorRangeResultIsPendingHelper106 bool operator()(const disk_cache::RangeResult& result) const { 107 return result.net_error == net::ERR_IO_PENDING; 108 } 109 }; 110 111 class TestRangeResultCompletionCallback 112 : public net::internal::TestCompletionCallbackTemplate< 113 disk_cache::RangeResult, 114 RangeResultIsPendingHelper> { 115 public: 116 TestRangeResultCompletionCallback(); 117 ~TestRangeResultCompletionCallback() override; 118 119 disk_cache::RangeResultCallback callback(); 120 121 private: 122 // Reference -> Value adapter --- disk_cache wants reference for callback, 123 // base class wants a value. 124 void HelpSetResult(const disk_cache::RangeResult& result); 125 }; 126 127 // ----------------------------------------------------------------------- 128 129 // Simple helper to deal with the message loop on a test. 130 class MessageLoopHelper { 131 public: 132 MessageLoopHelper(); 133 134 MessageLoopHelper(const MessageLoopHelper&) = delete; 135 MessageLoopHelper& operator=(const MessageLoopHelper&) = delete; 136 137 ~MessageLoopHelper(); 138 139 // Run the message loop and wait for num_callbacks before returning. Returns 140 // false if we are waiting to long. Each callback that will be waited on is 141 // required to call CallbackWasCalled() to indicate when it was called. 142 bool WaitUntilCacheIoFinished(int num_callbacks); 143 144 // True if a given callback was called more times than it expected. callback_reused_error()145 bool callback_reused_error() const { return callback_reused_error_; } set_callback_reused_error(bool error)146 void set_callback_reused_error(bool error) { 147 callback_reused_error_ = error; 148 } 149 callbacks_called()150 int callbacks_called() const { return callbacks_called_; } 151 // Report that a callback was called. Each callback that will be waited on 152 // via WaitUntilCacheIoFinished() is expected to call this method to 153 // indicate when it has been executed. CallbackWasCalled()154 void CallbackWasCalled() { ++callbacks_called_; } 155 156 private: 157 // Sets the number of callbacks that can be received so far. ExpectCallbacks(int num_callbacks)158 void ExpectCallbacks(int num_callbacks) { 159 num_callbacks_ = num_callbacks; 160 num_iterations_ = last_ = 0; 161 completed_ = false; 162 } 163 164 // Called periodically to test if WaitUntilCacheIoFinished should return. 165 void TimerExpired(); 166 167 std::unique_ptr<base::RunLoop> run_loop_; 168 int num_callbacks_ = 0; 169 int num_iterations_ = 0; 170 int last_ = 0; 171 bool completed_ = false; 172 173 // True if a callback was called/reused more than expected. 174 bool callback_reused_error_ = false; 175 int callbacks_called_ = 0; 176 }; 177 178 // ----------------------------------------------------------------------- 179 180 // Simple callback to process IO completions from the cache. It allows tests 181 // with multiple simultaneous IO operations. 182 class CallbackTest { 183 public: 184 // Creates a new CallbackTest object. When the callback is called, it will 185 // update |helper|. If |reuse| is false and a callback is called more than 186 // once, or if |reuse| is true and a callback is called more than twice, an 187 // error will be reported to |helper|. 188 CallbackTest(MessageLoopHelper* helper, bool reuse); 189 190 CallbackTest(const CallbackTest&) = delete; 191 CallbackTest& operator=(const CallbackTest&) = delete; 192 193 ~CallbackTest(); 194 195 void Run(int result); 196 void RunWithEntry(disk_cache::EntryResult result); 197 last_result()198 int last_result() const { return last_result_; } ReleaseLastEntryResult()199 disk_cache::EntryResult ReleaseLastEntryResult() { 200 return std::move(last_entry_result_); 201 } 202 203 private: 204 raw_ptr<MessageLoopHelper> helper_; 205 int reuse_; 206 int last_result_; 207 disk_cache::EntryResult last_entry_result_; 208 }; 209 210 #endif // NET_DISK_CACHE_DISK_CACHE_TEST_UTIL_H_ 211