1 // Copyright 2011 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 #include "net/disk_cache/disk_cache_test_util.h"
6
7 #include "base/check_op.h"
8 #include "base/files/file.h"
9 #include "base/files/file_path.h"
10 #include "base/run_loop.h"
11 #include "base/task/single_thread_task_runner.h"
12 #include "net/base/net_errors.h"
13 #include "net/disk_cache/blockfile/backend_impl.h"
14 #include "net/disk_cache/blockfile/file.h"
15 #include "net/disk_cache/cache_util.h"
16
17 using base::Time;
18
GenerateKey(bool same_length)19 std::string GenerateKey(bool same_length) {
20 char key[200];
21 CacheTestFillBuffer(key, sizeof(key), same_length);
22
23 key[199] = '\0';
24 return std::string(key);
25 }
26
CacheTestFillBuffer(char * buffer,size_t len,bool no_nulls)27 void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls) {
28 static bool called = false;
29 if (!called) {
30 called = true;
31 int seed = static_cast<int>(Time::Now().ToInternalValue());
32 srand(seed);
33 }
34
35 for (size_t i = 0; i < len; i++) {
36 buffer[i] = static_cast<char>(rand());
37 if (!buffer[i] && no_nulls)
38 buffer[i] = 'g';
39 }
40 if (len && !buffer[0])
41 buffer[0] = 'g';
42 }
43
CacheTestCreateAndFillBuffer(size_t len,bool no_nulls)44 scoped_refptr<net::IOBufferWithSize> CacheTestCreateAndFillBuffer(
45 size_t len,
46 bool no_nulls) {
47 auto buffer = base::MakeRefCounted<net::IOBufferWithSize>(len);
48 CacheTestFillBuffer(buffer->data(), len, no_nulls);
49 return buffer;
50 }
51
CreateCacheTestFile(const base::FilePath & name)52 bool CreateCacheTestFile(const base::FilePath& name) {
53 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
54 base::File::FLAG_WRITE;
55
56 base::File file(name, flags);
57 if (!file.IsValid())
58 return false;
59
60 file.SetLength(4 * 1024 * 1024);
61 return true;
62 }
63
DeleteCache(const base::FilePath & path)64 bool DeleteCache(const base::FilePath& path) {
65 disk_cache::DeleteCache(path, false);
66 return true;
67 }
68
CheckCacheIntegrity(const base::FilePath & path,bool new_eviction,int max_size,uint32_t mask)69 bool CheckCacheIntegrity(const base::FilePath& path,
70 bool new_eviction,
71 int max_size,
72 uint32_t mask) {
73 auto cache = std::make_unique<disk_cache::BackendImpl>(
74 path, mask, base::SingleThreadTaskRunner::GetCurrentDefault(),
75 net::DISK_CACHE, nullptr);
76 if (max_size)
77 cache->SetMaxSize(max_size);
78 if (!cache.get())
79 return false;
80 if (new_eviction)
81 cache->SetNewEviction();
82 cache->SetFlags(disk_cache::kNoRandom);
83 if (cache->SyncInit() != net::OK)
84 return false;
85 return cache->SelfCheck() >= 0;
86 }
87
88 // -----------------------------------------------------------------------
89 TestBackendResultCompletionCallback::TestBackendResultCompletionCallback() =
90 default;
91
92 TestBackendResultCompletionCallback::~TestBackendResultCompletionCallback() =
93 default;
94
95 disk_cache::BackendResultCallback
callback()96 TestBackendResultCompletionCallback::callback() {
97 return base::BindOnce(&TestBackendResultCompletionCallback::SetResult,
98 base::Unretained(this));
99 }
100
101 TestEntryResultCompletionCallback::TestEntryResultCompletionCallback() =
102 default;
103
104 TestEntryResultCompletionCallback::~TestEntryResultCompletionCallback() =
105 default;
106
107 disk_cache::Backend::EntryResultCallback
callback()108 TestEntryResultCompletionCallback::callback() {
109 return base::BindOnce(&TestEntryResultCompletionCallback::SetResult,
110 base::Unretained(this));
111 }
112
113 TestRangeResultCompletionCallback::TestRangeResultCompletionCallback() =
114 default;
115
116 TestRangeResultCompletionCallback::~TestRangeResultCompletionCallback() =
117 default;
118
callback()119 disk_cache::RangeResultCallback TestRangeResultCompletionCallback::callback() {
120 return base::BindOnce(&TestRangeResultCompletionCallback::HelpSetResult,
121 base::Unretained(this));
122 }
123
HelpSetResult(const disk_cache::RangeResult & result)124 void TestRangeResultCompletionCallback::HelpSetResult(
125 const disk_cache::RangeResult& result) {
126 SetResult(result);
127 }
128
129 // -----------------------------------------------------------------------
130
131 MessageLoopHelper::MessageLoopHelper() = default;
132
133 MessageLoopHelper::~MessageLoopHelper() = default;
134
WaitUntilCacheIoFinished(int num_callbacks)135 bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) {
136 if (num_callbacks == callbacks_called_)
137 return true;
138
139 ExpectCallbacks(num_callbacks);
140 // Create a recurrent timer of 50 ms.
141 base::RepeatingTimer timer;
142 timer.Start(FROM_HERE, base::Milliseconds(50), this,
143 &MessageLoopHelper::TimerExpired);
144 run_loop_ = std::make_unique<base::RunLoop>();
145 run_loop_->Run();
146 run_loop_.reset();
147
148 return completed_;
149 }
150
151 // Quits the message loop when all callbacks are called or we've been waiting
152 // too long for them (2 secs without a callback).
TimerExpired()153 void MessageLoopHelper::TimerExpired() {
154 CHECK_LE(callbacks_called_, num_callbacks_);
155 if (callbacks_called_ == num_callbacks_) {
156 completed_ = true;
157 run_loop_->Quit();
158 } else {
159 // Not finished yet. See if we have to abort.
160 if (last_ == callbacks_called_)
161 num_iterations_++;
162 else
163 last_ = callbacks_called_;
164 if (40 == num_iterations_)
165 run_loop_->Quit();
166 }
167 }
168
169 // -----------------------------------------------------------------------
170
CallbackTest(MessageLoopHelper * helper,bool reuse)171 CallbackTest::CallbackTest(MessageLoopHelper* helper,
172 bool reuse)
173 : helper_(helper),
174 reuse_(reuse ? 0 : 1) {
175 }
176
177 CallbackTest::~CallbackTest() = default;
178
179 // On the actual callback, increase the number of tests received and check for
180 // errors (an unexpected test received)
Run(int result)181 void CallbackTest::Run(int result) {
182 last_result_ = result;
183
184 if (reuse_) {
185 DCHECK_EQ(1, reuse_);
186 if (2 == reuse_)
187 helper_->set_callback_reused_error(true);
188 reuse_++;
189 }
190
191 helper_->CallbackWasCalled();
192 }
193
RunWithEntry(disk_cache::EntryResult result)194 void CallbackTest::RunWithEntry(disk_cache::EntryResult result) {
195 last_entry_result_ = std::move(result);
196 Run(last_entry_result_.net_error());
197 }
198