async_file_test_helper.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 The Chromium Authors. All rights reserved. 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 "base/bind.h" 6#include "base/file_util.h" 7#include "base/files/scoped_temp_dir.h" 8#include "base/run_loop.h" 9#include "content/public/test/async_file_test_helper.h" 10#include "testing/gtest/include/gtest/gtest.h" 11#include "webkit/browser/fileapi/file_system_backend.h" 12#include "webkit/browser/fileapi/file_system_context.h" 13#include "webkit/browser/fileapi/file_system_operation_runner.h" 14#include "webkit/browser/fileapi/file_system_url.h" 15#include "webkit/browser/quota/quota_manager.h" 16#include "webkit/common/fileapi/file_system_util.h" 17 18namespace content { 19 20typedef fileapi::FileSystemOperation::FileEntryList FileEntryList; 21 22namespace { 23 24void AssignAndQuit(base::RunLoop* run_loop, 25 base::File::Error* result_out, 26 base::File::Error result) { 27 *result_out = result; 28 run_loop->Quit(); 29} 30 31base::Callback<void(base::File::Error)> 32AssignAndQuitCallback(base::RunLoop* run_loop, 33 base::File::Error* result) { 34 return base::Bind(&AssignAndQuit, run_loop, base::Unretained(result)); 35} 36 37void GetMetadataCallback(base::RunLoop* run_loop, 38 base::File::Error* result_out, 39 base::File::Info* file_info_out, 40 base::File::Error result, 41 const base::File::Info& file_info) { 42 *result_out = result; 43 if (file_info_out) 44 *file_info_out = file_info; 45 run_loop->Quit(); 46} 47 48void CreateSnapshotFileCallback( 49 base::RunLoop* run_loop, 50 base::File::Error* result_out, 51 base::FilePath* platform_path_out, 52 base::File::Error result, 53 const base::File::Info& file_info, 54 const base::FilePath& platform_path, 55 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { 56 DCHECK(!file_ref.get()); 57 *result_out = result; 58 if (platform_path_out) 59 *platform_path_out = platform_path; 60 run_loop->Quit(); 61} 62 63void ReadDirectoryCallback(base::RunLoop* run_loop, 64 base::File::Error* result_out, 65 FileEntryList* entries_out, 66 base::File::Error result, 67 const FileEntryList& entries, 68 bool has_more) { 69 *result_out = result; 70 entries_out->insert(entries_out->end(), entries.begin(), entries.end()); 71 if (result != base::File::FILE_OK || !has_more) 72 run_loop->Quit(); 73} 74 75void DidGetUsageAndQuota(quota::QuotaStatusCode* status_out, 76 int64* usage_out, 77 int64* quota_out, 78 quota::QuotaStatusCode status, 79 int64 usage, 80 int64 quota) { 81 if (status_out) 82 *status_out = status; 83 if (usage_out) 84 *usage_out = usage; 85 if (quota_out) 86 *quota_out = quota; 87} 88 89} // namespace 90 91const int64 AsyncFileTestHelper::kDontCheckSize = -1; 92 93base::File::Error AsyncFileTestHelper::Copy( 94 fileapi::FileSystemContext* context, 95 const fileapi::FileSystemURL& src, 96 const fileapi::FileSystemURL& dest) { 97 return CopyWithProgress(context, src, dest, CopyProgressCallback()); 98} 99 100base::File::Error AsyncFileTestHelper::CopyWithProgress( 101 fileapi::FileSystemContext* context, 102 const fileapi::FileSystemURL& src, 103 const fileapi::FileSystemURL& dest, 104 const CopyProgressCallback& progress_callback) { 105 base::File::Error result = base::File::FILE_ERROR_FAILED; 106 base::RunLoop run_loop; 107 context->operation_runner()->Copy( 108 src, dest, fileapi::FileSystemOperation::OPTION_NONE, progress_callback, 109 AssignAndQuitCallback(&run_loop, &result)); 110 run_loop.Run(); 111 return result; 112} 113 114base::File::Error AsyncFileTestHelper::Move( 115 fileapi::FileSystemContext* context, 116 const fileapi::FileSystemURL& src, 117 const fileapi::FileSystemURL& dest) { 118 base::File::Error result = base::File::FILE_ERROR_FAILED; 119 base::RunLoop run_loop; 120 context->operation_runner()->Move( 121 src, dest, fileapi::FileSystemOperation::OPTION_NONE, 122 AssignAndQuitCallback(&run_loop, &result)); 123 run_loop.Run(); 124 return result; 125} 126 127base::File::Error AsyncFileTestHelper::Remove( 128 fileapi::FileSystemContext* context, 129 const fileapi::FileSystemURL& url, 130 bool recursive) { 131 base::File::Error result = base::File::FILE_ERROR_FAILED; 132 base::RunLoop run_loop; 133 context->operation_runner()->Remove( 134 url, recursive, AssignAndQuitCallback(&run_loop, &result)); 135 run_loop.Run(); 136 return result; 137} 138 139base::File::Error AsyncFileTestHelper::ReadDirectory( 140 fileapi::FileSystemContext* context, 141 const fileapi::FileSystemURL& url, 142 FileEntryList* entries) { 143 base::File::Error result = base::File::FILE_ERROR_FAILED; 144 DCHECK(entries); 145 entries->clear(); 146 base::RunLoop run_loop; 147 context->operation_runner()->ReadDirectory( 148 url, base::Bind(&ReadDirectoryCallback, &run_loop, &result, entries)); 149 run_loop.Run(); 150 return result; 151} 152 153base::File::Error AsyncFileTestHelper::CreateDirectory( 154 fileapi::FileSystemContext* context, 155 const fileapi::FileSystemURL& url) { 156 base::File::Error result = base::File::FILE_ERROR_FAILED; 157 base::RunLoop run_loop; 158 context->operation_runner()->CreateDirectory( 159 url, 160 false /* exclusive */, 161 false /* recursive */, 162 AssignAndQuitCallback(&run_loop, &result)); 163 run_loop.Run(); 164 return result; 165} 166 167base::File::Error AsyncFileTestHelper::CreateFile( 168 fileapi::FileSystemContext* context, 169 const fileapi::FileSystemURL& url) { 170 base::File::Error result = base::File::FILE_ERROR_FAILED; 171 base::RunLoop run_loop; 172 context->operation_runner()->CreateFile( 173 url, false /* exclusive */, 174 AssignAndQuitCallback(&run_loop, &result)); 175 run_loop.Run(); 176 return result; 177} 178 179base::File::Error AsyncFileTestHelper::CreateFileWithData( 180 fileapi::FileSystemContext* context, 181 const fileapi::FileSystemURL& url, 182 const char* buf, 183 int buf_size) { 184 base::ScopedTempDir dir; 185 if (!dir.CreateUniqueTempDir()) 186 return base::File::FILE_ERROR_FAILED; 187 base::FilePath local_path = dir.path().AppendASCII("tmp"); 188 if (buf_size != base::WriteFile(local_path, buf, buf_size)) 189 return base::File::FILE_ERROR_FAILED; 190 base::File::Error result = base::File::FILE_ERROR_FAILED; 191 base::RunLoop run_loop; 192 context->operation_runner()->CopyInForeignFile( 193 local_path, url, AssignAndQuitCallback(&run_loop, &result)); 194 run_loop.Run(); 195 return result; 196} 197 198base::File::Error AsyncFileTestHelper::TruncateFile( 199 fileapi::FileSystemContext* context, 200 const fileapi::FileSystemURL& url, 201 size_t size) { 202 base::RunLoop run_loop; 203 base::File::Error result = base::File::FILE_ERROR_FAILED; 204 context->operation_runner()->Truncate( 205 url, size, AssignAndQuitCallback(&run_loop, &result)); 206 run_loop.Run(); 207 return result; 208} 209 210base::File::Error AsyncFileTestHelper::GetMetadata( 211 fileapi::FileSystemContext* context, 212 const fileapi::FileSystemURL& url, 213 base::File::Info* file_info) { 214 base::File::Error result = base::File::FILE_ERROR_FAILED; 215 base::RunLoop run_loop; 216 context->operation_runner()->GetMetadata( 217 url, base::Bind(&GetMetadataCallback, &run_loop, &result, 218 file_info)); 219 run_loop.Run(); 220 return result; 221} 222 223base::File::Error AsyncFileTestHelper::GetPlatformPath( 224 fileapi::FileSystemContext* context, 225 const fileapi::FileSystemURL& url, 226 base::FilePath* platform_path) { 227 base::File::Error result = base::File::FILE_ERROR_FAILED; 228 base::RunLoop run_loop; 229 context->operation_runner()->CreateSnapshotFile( 230 url, base::Bind(&CreateSnapshotFileCallback, &run_loop, &result, 231 platform_path)); 232 run_loop.Run(); 233 return result; 234} 235 236bool AsyncFileTestHelper::FileExists( 237 fileapi::FileSystemContext* context, 238 const fileapi::FileSystemURL& url, 239 int64 expected_size) { 240 base::File::Info file_info; 241 base::File::Error result = GetMetadata(context, url, &file_info); 242 if (result != base::File::FILE_OK || file_info.is_directory) 243 return false; 244 return expected_size == kDontCheckSize || file_info.size == expected_size; 245} 246 247bool AsyncFileTestHelper::DirectoryExists( 248 fileapi::FileSystemContext* context, 249 const fileapi::FileSystemURL& url) { 250 base::File::Info file_info; 251 base::File::Error result = GetMetadata(context, url, &file_info); 252 return (result == base::File::FILE_OK) && file_info.is_directory; 253} 254 255quota::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota( 256 quota::QuotaManager* quota_manager, 257 const GURL& origin, 258 fileapi::FileSystemType type, 259 int64* usage, 260 int64* quota) { 261 quota::QuotaStatusCode status = quota::kQuotaStatusUnknown; 262 quota_manager->GetUsageAndQuota( 263 origin, 264 FileSystemTypeToQuotaStorageType(type), 265 base::Bind(&DidGetUsageAndQuota, &status, usage, quota)); 266 base::RunLoop().RunUntilIdle(); 267 return status; 268} 269 270} // namespace fileapi 271