Home | History | Annotate | Download | only in test
      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 
     18 namespace content {
     19 
     20 typedef fileapi::FileSystemOperation::FileEntryList FileEntryList;
     21 
     22 namespace {
     23 
     24 void 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 
     31 base::Callback<void(base::File::Error)>
     32 AssignAndQuitCallback(base::RunLoop* run_loop,
     33                       base::File::Error* result) {
     34   return base::Bind(&AssignAndQuit, run_loop, base::Unretained(result));
     35 }
     36 
     37 void 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 
     48 void 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 
     63 void 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 
     75 void 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 
     91 const int64 AsyncFileTestHelper::kDontCheckSize = -1;
     92 
     93 base::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 
    100 base::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 
    114 base::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 
    127 base::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 
    139 base::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 
    153 base::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 
    167 base::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 
    179 base::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 
    198 base::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 
    210 base::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 
    223 base::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 
    236 bool 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 
    247 bool 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 
    255 quota::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