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