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