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