blob: 05764136157cb9db3683222a18649b1e293dc600 [file] [log] [blame]
// Copyright 2014 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 "storage/browser/test/async_file_test_helper.h"
#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/file_system/file_system_backend.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_operation_runner.h"
#include "storage/browser/file_system/file_system_url.h"
#include "storage/browser/file_system/file_system_util.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/common/file_system/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
namespace storage {
using FileEntryList = FileSystemOperation::FileEntryList;
namespace {
void AssignAndQuit(base::RunLoop* run_loop,
base::File::Error* result_out,
base::File::Error result) {
*result_out = result;
run_loop->Quit();
}
base::OnceCallback<void(base::File::Error)> AssignAndQuitCallback(
base::RunLoop* run_loop,
base::File::Error* result) {
return base::BindOnce(&AssignAndQuit, run_loop, base::Unretained(result));
}
void GetMetadataCallback(base::RunLoop* run_loop,
base::File::Error* result_out,
base::File::Info* file_info_out,
base::File::Error result,
const base::File::Info& file_info) {
*result_out = result;
if (file_info_out)
*file_info_out = file_info;
run_loop->Quit();
}
void CreateSnapshotFileCallback(
base::RunLoop* run_loop,
base::File::Error* result_out,
base::FilePath* platform_path_out,
base::File::Error result,
const base::File::Info& file_info,
const base::FilePath& platform_path,
scoped_refptr<ShareableFileReference> file_ref) {
DCHECK(!file_ref.get());
*result_out = result;
if (platform_path_out)
*platform_path_out = platform_path;
run_loop->Quit();
}
void ReadDirectoryCallback(base::RunLoop* run_loop,
base::File::Error* result_out,
FileEntryList* entries_out,
base::File::Error result,
FileEntryList entries,
bool has_more) {
*result_out = result;
entries_out->insert(entries_out->end(), entries.begin(), entries.end());
if (result != base::File::FILE_OK || !has_more)
run_loop->Quit();
}
void DidGetUsageAndQuota(blink::mojom::QuotaStatusCode* status_out,
int64_t* usage_out,
int64_t* quota_out,
base::OnceClosure done_callback,
blink::mojom::QuotaStatusCode status,
int64_t usage,
int64_t quota) {
if (status_out)
*status_out = status;
if (usage_out)
*usage_out = usage;
if (quota_out)
*quota_out = quota;
if (done_callback)
std::move(done_callback).Run();
}
} // namespace
const int64_t AsyncFileTestHelper::kDontCheckSize = -1;
base::File::Error AsyncFileTestHelper::Copy(FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest) {
return CopyWithProgress(context, src, dest, CopyOrMoveProgressCallback());
}
base::File::Error AsyncFileTestHelper::CopyWithProgress(
FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest,
const CopyOrMoveProgressCallback& progress_callback) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->Copy(src, dest, FileSystemOperation::OPTION_NONE,
FileSystemOperation::ERROR_BEHAVIOR_ABORT,
progress_callback,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::CopyFileLocal(
FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->CopyFileLocal(
src, dest, FileSystemOperation::OPTION_NONE,
FileSystemOperation::CopyFileProgressCallback(),
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::Move(FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->Move(
src, dest, FileSystemOperation::OPTION_NONE,
storage::FileSystemOperation::ERROR_BEHAVIOR_ABORT,
storage::FileSystemOperation::CopyOrMoveProgressCallback(),
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::MoveWithProgress(
FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest,
const CopyOrMoveProgressCallback& progress_callback) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->Move(src, dest, FileSystemOperation::OPTION_NONE,
FileSystemOperation::ERROR_BEHAVIOR_ABORT,
progress_callback,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::MoveFileLocal(
FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->MoveFileLocal(
src, dest, FileSystemOperation::OPTION_NONE,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::Remove(FileSystemContext* context,
const FileSystemURL& url,
bool recursive) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->Remove(
url, recursive, AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::ReadDirectory(FileSystemContext* context,
const FileSystemURL& url,
FileEntryList* entries) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
DCHECK(entries);
entries->clear();
base::RunLoop run_loop;
context->operation_runner()->ReadDirectory(
url,
base::BindRepeating(&ReadDirectoryCallback, &run_loop, &result, entries));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::CreateDirectory(
FileSystemContext* context,
const FileSystemURL& url) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->CreateDirectory(
url, false /* exclusive */, false /* recursive */,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::CreateFile(FileSystemContext* context,
const FileSystemURL& url) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->CreateFile(
url, false /* exclusive */, AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::CreateFileWithData(
FileSystemContext* context,
const FileSystemURL& url,
const char* buf,
int buf_size) {
base::ScopedTempDir dir;
if (!dir.CreateUniqueTempDir())
return base::File::FILE_ERROR_FAILED;
base::FilePath local_path = dir.GetPath().AppendASCII("tmp");
if (!base::WriteFile(local_path, base::StringPiece(buf, buf_size)))
return base::File::FILE_ERROR_FAILED;
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->CopyInForeignFile(
local_path, url, AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::TruncateFile(FileSystemContext* context,
const FileSystemURL& url,
size_t size) {
base::RunLoop run_loop;
base::File::Error result = base::File::FILE_ERROR_FAILED;
context->operation_runner()->Truncate(
url, size, AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::GetMetadata(
FileSystemContext* context,
const FileSystemURL& url,
base::File::Info* file_info) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->GetMetadata(
url,
FileSystemOperation::GET_METADATA_FIELD_IS_DIRECTORY |
FileSystemOperation::GET_METADATA_FIELD_SIZE |
FileSystemOperation::GET_METADATA_FIELD_LAST_MODIFIED,
base::BindOnce(&GetMetadataCallback, &run_loop, &result, file_info));
run_loop.Run();
return result;
}
base::File::Error AsyncFileTestHelper::GetPlatformPath(
FileSystemContext* context,
const FileSystemURL& url,
base::FilePath* platform_path) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->CreateSnapshotFile(
url, base::BindOnce(&CreateSnapshotFileCallback, &run_loop, &result,
platform_path));
run_loop.Run();
return result;
}
bool AsyncFileTestHelper::FileExists(FileSystemContext* context,
const FileSystemURL& url,
int64_t expected_size) {
base::File::Info file_info;
base::File::Error result = GetMetadata(context, url, &file_info);
if (result != base::File::FILE_OK || file_info.is_directory)
return false;
return expected_size == kDontCheckSize || file_info.size == expected_size;
}
bool AsyncFileTestHelper::DirectoryExists(FileSystemContext* context,
const FileSystemURL& url) {
base::File::Info file_info;
base::File::Error result = GetMetadata(context, url, &file_info);
return (result == base::File::FILE_OK) && file_info.is_directory;
}
blink::mojom::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota(
QuotaManager* quota_manager,
const url::Origin& origin,
FileSystemType type,
int64_t* usage,
int64_t* quota) {
blink::mojom::QuotaStatusCode status =
blink::mojom::QuotaStatusCode::kUnknown;
base::RunLoop run_loop;
quota_manager->GetUsageAndQuota(
blink::StorageKey(origin), FileSystemTypeToQuotaStorageType(type),
base::BindOnce(&DidGetUsageAndQuota, &status, usage, quota,
run_loop.QuitWhenIdleClosure()));
run_loop.Run();
return status;
}
base::File::Error AsyncFileTestHelper::TouchFile(
FileSystemContext* context,
const FileSystemURL& url,
const base::Time& last_access_time,
const base::Time& last_modified_time) {
base::File::Error result = base::File::FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->TouchFile(
url, last_access_time, last_modified_time,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
}
} // namespace storage