190 lines
5.3 KiB
C++
190 lines
5.3 KiB
C++
// Copyright 2011 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "net/disk_cache/disk_cache_test_util.h"
|
|
|
|
#include "base/check_op.h"
|
|
#include "base/files/file.h"
|
|
#include "base/files/file_path.h"
|
|
#include "base/run_loop.h"
|
|
#include "base/task/single_thread_task_runner.h"
|
|
#include "net/base/net_errors.h"
|
|
#include "net/disk_cache/blockfile/backend_impl.h"
|
|
#include "net/disk_cache/blockfile/file.h"
|
|
#include "net/disk_cache/cache_util.h"
|
|
|
|
using base::Time;
|
|
|
|
std::string GenerateKey(bool same_length) {
|
|
char key[200];
|
|
CacheTestFillBuffer(key, sizeof(key), same_length);
|
|
|
|
key[199] = '\0';
|
|
return std::string(key);
|
|
}
|
|
|
|
void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls) {
|
|
static bool called = false;
|
|
if (!called) {
|
|
called = true;
|
|
int seed = static_cast<int>(Time::Now().ToInternalValue());
|
|
srand(seed);
|
|
}
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
buffer[i] = static_cast<char>(rand());
|
|
if (!buffer[i] && no_nulls)
|
|
buffer[i] = 'g';
|
|
}
|
|
if (len && !buffer[0])
|
|
buffer[0] = 'g';
|
|
}
|
|
|
|
bool CreateCacheTestFile(const base::FilePath& name) {
|
|
int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
|
|
base::File::FLAG_WRITE;
|
|
|
|
base::File file(name, flags);
|
|
if (!file.IsValid())
|
|
return false;
|
|
|
|
file.SetLength(4 * 1024 * 1024);
|
|
return true;
|
|
}
|
|
|
|
bool DeleteCache(const base::FilePath& path) {
|
|
disk_cache::DeleteCache(path, false);
|
|
return true;
|
|
}
|
|
|
|
bool CheckCacheIntegrity(const base::FilePath& path,
|
|
bool new_eviction,
|
|
int max_size,
|
|
uint32_t mask) {
|
|
auto cache = std::make_unique<disk_cache::BackendImpl>(
|
|
path, mask, base::SingleThreadTaskRunner::GetCurrentDefault(),
|
|
net::DISK_CACHE, nullptr);
|
|
if (max_size)
|
|
cache->SetMaxSize(max_size);
|
|
if (!cache.get())
|
|
return false;
|
|
if (new_eviction)
|
|
cache->SetNewEviction();
|
|
cache->SetFlags(disk_cache::kNoRandom);
|
|
if (cache->SyncInit() != net::OK)
|
|
return false;
|
|
return cache->SelfCheck() >= 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
TestBackendResultCompletionCallback::TestBackendResultCompletionCallback() =
|
|
default;
|
|
|
|
TestBackendResultCompletionCallback::~TestBackendResultCompletionCallback() =
|
|
default;
|
|
|
|
disk_cache::BackendResultCallback
|
|
TestBackendResultCompletionCallback::callback() {
|
|
return base::BindOnce(&TestBackendResultCompletionCallback::SetResult,
|
|
base::Unretained(this));
|
|
}
|
|
|
|
TestEntryResultCompletionCallback::TestEntryResultCompletionCallback() =
|
|
default;
|
|
|
|
TestEntryResultCompletionCallback::~TestEntryResultCompletionCallback() =
|
|
default;
|
|
|
|
disk_cache::Backend::EntryResultCallback
|
|
TestEntryResultCompletionCallback::callback() {
|
|
return base::BindOnce(&TestEntryResultCompletionCallback::SetResult,
|
|
base::Unretained(this));
|
|
}
|
|
|
|
TestRangeResultCompletionCallback::TestRangeResultCompletionCallback() =
|
|
default;
|
|
|
|
TestRangeResultCompletionCallback::~TestRangeResultCompletionCallback() =
|
|
default;
|
|
|
|
disk_cache::RangeResultCallback TestRangeResultCompletionCallback::callback() {
|
|
return base::BindOnce(&TestRangeResultCompletionCallback::HelpSetResult,
|
|
base::Unretained(this));
|
|
}
|
|
|
|
void TestRangeResultCompletionCallback::HelpSetResult(
|
|
const disk_cache::RangeResult& result) {
|
|
SetResult(result);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
MessageLoopHelper::MessageLoopHelper() = default;
|
|
|
|
MessageLoopHelper::~MessageLoopHelper() = default;
|
|
|
|
bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) {
|
|
if (num_callbacks == callbacks_called_)
|
|
return true;
|
|
|
|
ExpectCallbacks(num_callbacks);
|
|
// Create a recurrent timer of 50 ms.
|
|
base::RepeatingTimer timer;
|
|
timer.Start(FROM_HERE, base::Milliseconds(50), this,
|
|
&MessageLoopHelper::TimerExpired);
|
|
run_loop_ = std::make_unique<base::RunLoop>();
|
|
run_loop_->Run();
|
|
run_loop_.reset();
|
|
|
|
return completed_;
|
|
}
|
|
|
|
// Quits the message loop when all callbacks are called or we've been waiting
|
|
// too long for them (2 secs without a callback).
|
|
void MessageLoopHelper::TimerExpired() {
|
|
CHECK_LE(callbacks_called_, num_callbacks_);
|
|
if (callbacks_called_ == num_callbacks_) {
|
|
completed_ = true;
|
|
run_loop_->Quit();
|
|
} else {
|
|
// Not finished yet. See if we have to abort.
|
|
if (last_ == callbacks_called_)
|
|
num_iterations_++;
|
|
else
|
|
last_ = callbacks_called_;
|
|
if (40 == num_iterations_)
|
|
run_loop_->Quit();
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
CallbackTest::CallbackTest(MessageLoopHelper* helper,
|
|
bool reuse)
|
|
: helper_(helper),
|
|
reuse_(reuse ? 0 : 1) {
|
|
}
|
|
|
|
CallbackTest::~CallbackTest() = default;
|
|
|
|
// On the actual callback, increase the number of tests received and check for
|
|
// errors (an unexpected test received)
|
|
void CallbackTest::Run(int result) {
|
|
last_result_ = result;
|
|
|
|
if (reuse_) {
|
|
DCHECK_EQ(1, reuse_);
|
|
if (2 == reuse_)
|
|
helper_->set_callback_reused_error(true);
|
|
reuse_++;
|
|
}
|
|
|
|
helper_->CallbackWasCalled();
|
|
}
|
|
|
|
void CallbackTest::RunWithEntry(disk_cache::EntryResult result) {
|
|
last_entry_result_ = std::move(result);
|
|
Run(last_entry_result_.net_error());
|
|
}
|