// Copyright (c) 2011 The Chromium Authors. All rights reserved. // 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/threading/thread_task_runner_handle.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(Time::Now().ToInternalValue()); srand(seed); } for (size_t i = 0; i < len; i++) { buffer[i] = static_cast(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( path, mask, base::ThreadTaskRunnerHandle::Get(), 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(); 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()); }