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/files/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 "storage/browser/fileapi/file_system_backend.h"
     11 #include "storage/browser/fileapi/file_system_context.h"
     12 #include "storage/browser/fileapi/file_system_operation_runner.h"
     13 #include "storage/browser/fileapi/file_system_url.h"
     14 #include "storage/browser/quota/quota_manager.h"
     15 #include "storage/common/fileapi/file_system_util.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 
     18 namespace content {
     19 
     20 typedef storage::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<storage::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(storage::QuotaStatusCode* status_out,
     76                          int64* usage_out,
     77                          int64* quota_out,
     78                          storage::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     storage::FileSystemContext* context,
     95     const storage::FileSystemURL& src,
     96     const storage::FileSystemURL& dest) {
     97   return CopyWithProgress(context, src, dest, CopyProgressCallback());
     98 }
     99 
    100 base::File::Error AsyncFileTestHelper::CopyWithProgress(
    101     storage::FileSystemContext* context,
    102     const storage::FileSystemURL& src,
    103     const storage::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(src,
    108                                     dest,
    109                                     storage::FileSystemOperation::OPTION_NONE,
    110                                     progress_callback,
    111                                     AssignAndQuitCallback(&run_loop, &result));
    112   run_loop.Run();
    113   return result;
    114 }
    115 
    116 base::File::Error AsyncFileTestHelper::Move(
    117     storage::FileSystemContext* context,
    118     const storage::FileSystemURL& src,
    119     const storage::FileSystemURL& dest) {
    120   base::File::Error result = base::File::FILE_ERROR_FAILED;
    121   base::RunLoop run_loop;
    122   context->operation_runner()->Move(src,
    123                                     dest,
    124                                     storage::FileSystemOperation::OPTION_NONE,
    125                                     AssignAndQuitCallback(&run_loop, &result));
    126   run_loop.Run();
    127   return result;
    128 }
    129 
    130 base::File::Error AsyncFileTestHelper::Remove(
    131     storage::FileSystemContext* context,
    132     const storage::FileSystemURL& url,
    133     bool recursive) {
    134   base::File::Error result = base::File::FILE_ERROR_FAILED;
    135   base::RunLoop run_loop;
    136   context->operation_runner()->Remove(
    137       url, recursive, AssignAndQuitCallback(&run_loop, &result));
    138   run_loop.Run();
    139   return result;
    140 }
    141 
    142 base::File::Error AsyncFileTestHelper::ReadDirectory(
    143     storage::FileSystemContext* context,
    144     const storage::FileSystemURL& url,
    145     FileEntryList* entries) {
    146   base::File::Error result = base::File::FILE_ERROR_FAILED;
    147   DCHECK(entries);
    148   entries->clear();
    149   base::RunLoop run_loop;
    150   context->operation_runner()->ReadDirectory(
    151       url, base::Bind(&ReadDirectoryCallback, &run_loop, &result, entries));
    152   run_loop.Run();
    153   return result;
    154 }
    155 
    156 base::File::Error AsyncFileTestHelper::CreateDirectory(
    157     storage::FileSystemContext* context,
    158     const storage::FileSystemURL& url) {
    159   base::File::Error result = base::File::FILE_ERROR_FAILED;
    160   base::RunLoop run_loop;
    161   context->operation_runner()->CreateDirectory(
    162       url,
    163       false /* exclusive */,
    164       false /* recursive */,
    165       AssignAndQuitCallback(&run_loop, &result));
    166   run_loop.Run();
    167   return result;
    168 }
    169 
    170 base::File::Error AsyncFileTestHelper::CreateFile(
    171     storage::FileSystemContext* context,
    172     const storage::FileSystemURL& url) {
    173   base::File::Error result = base::File::FILE_ERROR_FAILED;
    174   base::RunLoop run_loop;
    175   context->operation_runner()->CreateFile(
    176       url, false /* exclusive */,
    177       AssignAndQuitCallback(&run_loop, &result));
    178   run_loop.Run();
    179   return result;
    180 }
    181 
    182 base::File::Error AsyncFileTestHelper::CreateFileWithData(
    183     storage::FileSystemContext* context,
    184     const storage::FileSystemURL& url,
    185     const char* buf,
    186     int buf_size) {
    187   base::ScopedTempDir dir;
    188   if (!dir.CreateUniqueTempDir())
    189     return base::File::FILE_ERROR_FAILED;
    190   base::FilePath local_path = dir.path().AppendASCII("tmp");
    191   if (buf_size != base::WriteFile(local_path, buf, buf_size))
    192     return base::File::FILE_ERROR_FAILED;
    193   base::File::Error result = base::File::FILE_ERROR_FAILED;
    194   base::RunLoop run_loop;
    195   context->operation_runner()->CopyInForeignFile(
    196       local_path, url, AssignAndQuitCallback(&run_loop, &result));
    197   run_loop.Run();
    198   return result;
    199 }
    200 
    201 base::File::Error AsyncFileTestHelper::TruncateFile(
    202     storage::FileSystemContext* context,
    203     const storage::FileSystemURL& url,
    204     size_t size) {
    205   base::RunLoop run_loop;
    206   base::File::Error result = base::File::FILE_ERROR_FAILED;
    207   context->operation_runner()->Truncate(
    208       url, size, AssignAndQuitCallback(&run_loop, &result));
    209   run_loop.Run();
    210   return result;
    211 }
    212 
    213 base::File::Error AsyncFileTestHelper::GetMetadata(
    214     storage::FileSystemContext* context,
    215     const storage::FileSystemURL& url,
    216     base::File::Info* file_info) {
    217   base::File::Error result = base::File::FILE_ERROR_FAILED;
    218   base::RunLoop run_loop;
    219   context->operation_runner()->GetMetadata(
    220       url, base::Bind(&GetMetadataCallback, &run_loop, &result,
    221                       file_info));
    222   run_loop.Run();
    223   return result;
    224 }
    225 
    226 base::File::Error AsyncFileTestHelper::GetPlatformPath(
    227     storage::FileSystemContext* context,
    228     const storage::FileSystemURL& url,
    229     base::FilePath* platform_path) {
    230   base::File::Error result = base::File::FILE_ERROR_FAILED;
    231   base::RunLoop run_loop;
    232   context->operation_runner()->CreateSnapshotFile(
    233       url, base::Bind(&CreateSnapshotFileCallback, &run_loop, &result,
    234                       platform_path));
    235   run_loop.Run();
    236   return result;
    237 }
    238 
    239 bool AsyncFileTestHelper::FileExists(storage::FileSystemContext* context,
    240                                      const storage::FileSystemURL& url,
    241                                      int64 expected_size) {
    242   base::File::Info file_info;
    243   base::File::Error result = GetMetadata(context, url, &file_info);
    244   if (result != base::File::FILE_OK || file_info.is_directory)
    245     return false;
    246   return expected_size == kDontCheckSize || file_info.size == expected_size;
    247 }
    248 
    249 bool AsyncFileTestHelper::DirectoryExists(storage::FileSystemContext* context,
    250                                           const storage::FileSystemURL& url) {
    251   base::File::Info file_info;
    252   base::File::Error result = GetMetadata(context, url, &file_info);
    253   return (result == base::File::FILE_OK) && file_info.is_directory;
    254 }
    255 
    256 storage::QuotaStatusCode AsyncFileTestHelper::GetUsageAndQuota(
    257     storage::QuotaManager* quota_manager,
    258     const GURL& origin,
    259     storage::FileSystemType type,
    260     int64* usage,
    261     int64* quota) {
    262   storage::QuotaStatusCode status = storage::kQuotaStatusUnknown;
    263   quota_manager->GetUsageAndQuota(
    264       origin,
    265       FileSystemTypeToQuotaStorageType(type),
    266       base::Bind(&DidGetUsageAndQuota, &status, usage, quota));
    267   base::RunLoop().RunUntilIdle();
    268   return status;
    269 }
    270 
    271 }  // namespace storage
    272