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