Home | History | Annotate | Download | only in fileapi
      1 // Copyright (c) 2012 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 <set>
      6 #include <string>
      7 
      8 #include "base/bind.h"
      9 #include "base/files/file_util.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/format_macros.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/message_loop/message_loop_proxy.h"
     14 #include "base/strings/stringprintf.h"
     15 #include "base/time/time.h"
     16 #include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
     17 #include "chrome/browser/media_galleries/fileapi/native_media_file_util.h"
     18 #include "content/public/test/mock_special_storage_policy.h"
     19 #include "content/public/test/test_browser_thread.h"
     20 #include "content/public/test/test_file_system_options.h"
     21 #include "storage/browser/fileapi/external_mount_points.h"
     22 #include "storage/browser/fileapi/file_system_backend.h"
     23 #include "storage/browser/fileapi/file_system_context.h"
     24 #include "storage/browser/fileapi/file_system_operation_runner.h"
     25 #include "storage/browser/fileapi/file_system_url.h"
     26 #include "storage/browser/fileapi/isolated_context.h"
     27 #include "storage/browser/fileapi/native_file_util.h"
     28 #include "testing/gtest/include/gtest/gtest.h"
     29 
     30 #define FPL(x) FILE_PATH_LITERAL(x)
     31 
     32 using storage::FileSystemOperation;
     33 using storage::FileSystemURL;
     34 
     35 namespace {
     36 
     37 typedef FileSystemOperation::FileEntryList FileEntryList;
     38 
     39 struct FilteringTestCase {
     40   const base::FilePath::CharType* path;
     41   bool is_directory;
     42   bool visible;
     43   bool media_file;
     44   const char* content;
     45 };
     46 
     47 const FilteringTestCase kFilteringTestCases[] = {
     48   // Directory should always be visible.
     49   { FPL("hoge"), true, true, false, NULL },
     50   { FPL("fuga.jpg"), true, true, false, NULL },
     51   { FPL("piyo.txt"), true, true, false, NULL },
     52   { FPL("moga.cod"), true, true, false, NULL },
     53 
     54   // File should be visible if it's a supported media file.
     55   // File without extension.
     56   { FPL("foo"), false, false, false, "abc" },
     57   // Supported media file.
     58   { FPL("bar.jpg"), false, true, true, "\xFF\xD8\xFF" },
     59   // Unsupported masquerading file.
     60   { FPL("sna.jpg"), false, true, false, "abc" },
     61   // Non-media file.
     62   { FPL("baz.txt"), false, false, false, "abc" },
     63   // Unsupported media file.
     64   { FPL("foobar.cod"), false, false, false, "abc" },
     65 };
     66 
     67 void ExpectEqHelper(const std::string& test_name,
     68                     base::File::Error expected,
     69                     base::File::Error actual) {
     70   EXPECT_EQ(expected, actual) << test_name;
     71 }
     72 
     73 void ExpectMetadataEqHelper(const std::string& test_name,
     74                             base::File::Error expected,
     75                             bool expected_is_directory,
     76                             base::File::Error actual,
     77                             const base::File::Info& file_info) {
     78   EXPECT_EQ(expected, actual) << test_name;
     79   if (actual == base::File::FILE_OK)
     80     EXPECT_EQ(expected_is_directory, file_info.is_directory) << test_name;
     81 }
     82 
     83 void DidReadDirectory(std::set<base::FilePath::StringType>* content,
     84                       bool* completed,
     85                       base::File::Error error,
     86                       const FileEntryList& file_list,
     87                       bool has_more) {
     88   EXPECT_TRUE(!*completed);
     89   *completed = !has_more;
     90   for (FileEntryList::const_iterator itr = file_list.begin();
     91        itr != file_list.end(); ++itr)
     92     EXPECT_TRUE(content->insert(itr->name).second);
     93 }
     94 
     95 void PopulateDirectoryWithTestCases(const base::FilePath& dir,
     96                                     const FilteringTestCase* test_cases,
     97                                     size_t n) {
     98   for (size_t i = 0; i < n; ++i) {
     99     base::FilePath path = dir.Append(test_cases[i].path);
    100     if (test_cases[i].is_directory) {
    101       ASSERT_TRUE(base::CreateDirectory(path));
    102     } else {
    103       ASSERT_TRUE(test_cases[i].content != NULL);
    104       int len = strlen(test_cases[i].content);
    105       ASSERT_EQ(len, base::WriteFile(path, test_cases[i].content, len));
    106     }
    107   }
    108 }
    109 
    110 }  // namespace
    111 
    112 class NativeMediaFileUtilTest : public testing::Test {
    113  public:
    114   NativeMediaFileUtilTest()
    115       : io_thread_(content::BrowserThread::IO, &message_loop_) {
    116   }
    117 
    118   virtual void SetUp() {
    119     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    120     ASSERT_TRUE(base::CreateDirectory(root_path()));
    121 
    122     scoped_refptr<storage::SpecialStoragePolicy> storage_policy =
    123         new content::MockSpecialStoragePolicy();
    124 
    125     ScopedVector<storage::FileSystemBackend> additional_providers;
    126     additional_providers.push_back(new MediaFileSystemBackend(
    127         data_dir_.path(), base::MessageLoopProxy::current().get()));
    128 
    129     file_system_context_ = new storage::FileSystemContext(
    130         base::MessageLoopProxy::current().get(),
    131         base::MessageLoopProxy::current().get(),
    132         storage::ExternalMountPoints::CreateRefCounted().get(),
    133         storage_policy.get(),
    134         NULL,
    135         additional_providers.Pass(),
    136         std::vector<storage::URLRequestAutoMountHandler>(),
    137         data_dir_.path(),
    138         content::CreateAllowFileAccessOptions());
    139 
    140     filesystem_id_ = isolated_context()->RegisterFileSystemForPath(
    141         storage::kFileSystemTypeNativeMedia, std::string(), root_path(), NULL);
    142 
    143     isolated_context()->AddReference(filesystem_id_);
    144   }
    145 
    146   virtual void TearDown() {
    147     isolated_context()->RemoveReference(filesystem_id_);
    148     file_system_context_ = NULL;
    149   }
    150 
    151  protected:
    152   storage::FileSystemContext* file_system_context() {
    153     return file_system_context_.get();
    154   }
    155 
    156   FileSystemURL CreateURL(const base::FilePath::CharType* test_case_path) {
    157     return file_system_context_->CreateCrackedFileSystemURL(
    158         origin(),
    159         storage::kFileSystemTypeIsolated,
    160         GetVirtualPath(test_case_path));
    161   }
    162 
    163   storage::IsolatedContext* isolated_context() {
    164     return storage::IsolatedContext::GetInstance();
    165   }
    166 
    167   base::FilePath root_path() {
    168     return data_dir_.path().Append(FPL("Media Directory"));
    169   }
    170 
    171   base::FilePath GetVirtualPath(
    172       const base::FilePath::CharType* test_case_path) {
    173     return base::FilePath::FromUTF8Unsafe(filesystem_id_).
    174                Append(FPL("Media Directory")).
    175                Append(base::FilePath(test_case_path));
    176   }
    177 
    178   GURL origin() {
    179     return GURL("http://example.com");
    180   }
    181 
    182   storage::FileSystemType type() { return storage::kFileSystemTypeNativeMedia; }
    183 
    184   storage::FileSystemOperationRunner* operation_runner() {
    185     return file_system_context_->operation_runner();
    186   }
    187 
    188  private:
    189   base::MessageLoop message_loop_;
    190   content::TestBrowserThread io_thread_;
    191 
    192   base::ScopedTempDir data_dir_;
    193   scoped_refptr<storage::FileSystemContext> file_system_context_;
    194 
    195   std::string filesystem_id_;
    196 
    197   DISALLOW_COPY_AND_ASSIGN(NativeMediaFileUtilTest);
    198 };
    199 
    200 TEST_F(NativeMediaFileUtilTest, DirectoryExistsAndFileExistsFiltering) {
    201   PopulateDirectoryWithTestCases(root_path(),
    202                                  kFilteringTestCases,
    203                                  arraysize(kFilteringTestCases));
    204 
    205   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    206     FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    207 
    208     base::File::Error expectation =
    209         kFilteringTestCases[i].visible ?
    210         base::File::FILE_OK :
    211         base::File::FILE_ERROR_NOT_FOUND;
    212 
    213     std::string test_name =
    214         base::StringPrintf("DirectoryExistsAndFileExistsFiltering %" PRIuS, i);
    215     if (kFilteringTestCases[i].is_directory) {
    216       operation_runner()->DirectoryExists(
    217           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    218     } else {
    219       operation_runner()->FileExists(
    220           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    221     }
    222     base::MessageLoop::current()->RunUntilIdle();
    223   }
    224 }
    225 
    226 TEST_F(NativeMediaFileUtilTest, ReadDirectoryFiltering) {
    227   PopulateDirectoryWithTestCases(root_path(),
    228                                  kFilteringTestCases,
    229                                  arraysize(kFilteringTestCases));
    230 
    231   std::set<base::FilePath::StringType> content;
    232   FileSystemURL url = CreateURL(FPL(""));
    233   bool completed = false;
    234   operation_runner()->ReadDirectory(
    235       url, base::Bind(&DidReadDirectory, &content, &completed));
    236   base::MessageLoop::current()->RunUntilIdle();
    237   EXPECT_TRUE(completed);
    238   EXPECT_EQ(6u, content.size());
    239 
    240   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    241     base::FilePath::StringType name =
    242         base::FilePath(kFilteringTestCases[i].path).BaseName().value();
    243     std::set<base::FilePath::StringType>::const_iterator found =
    244         content.find(name);
    245     EXPECT_EQ(kFilteringTestCases[i].visible, found != content.end());
    246   }
    247 }
    248 
    249 TEST_F(NativeMediaFileUtilTest, CreateDirectoryFiltering) {
    250   // Run the loop twice. The second loop attempts to create directories that are
    251   // pre-existing. Though the result should be the same.
    252   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    253     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    254       if (kFilteringTestCases[i].is_directory) {
    255         FileSystemURL root_url = CreateURL(FPL(""));
    256         FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    257 
    258         std::string test_name = base::StringPrintf(
    259             "CreateFileAndCreateDirectoryFiltering run %d, test %" PRIuS,
    260             loop_count, i);
    261         base::File::Error expectation =
    262             kFilteringTestCases[i].visible ?
    263             base::File::FILE_OK :
    264             base::File::FILE_ERROR_SECURITY;
    265         operation_runner()->CreateDirectory(
    266             url, false, false,
    267             base::Bind(&ExpectEqHelper, test_name, expectation));
    268       }
    269       base::MessageLoop::current()->RunUntilIdle();
    270     }
    271   }
    272 }
    273 
    274 TEST_F(NativeMediaFileUtilTest, CopySourceFiltering) {
    275   base::FilePath dest_path = root_path().AppendASCII("dest");
    276   FileSystemURL dest_url = CreateURL(FPL("dest"));
    277 
    278   // Run the loop twice. The first run has no source files. The second run does.
    279   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    280     if (loop_count == 1) {
    281       PopulateDirectoryWithTestCases(root_path(),
    282                                      kFilteringTestCases,
    283                                      arraysize(kFilteringTestCases));
    284     }
    285     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    286       // Always start with an empty destination directory.
    287       // Copying to a non-empty destination directory is an invalid operation.
    288       ASSERT_TRUE(base::DeleteFile(dest_path, true));
    289       ASSERT_TRUE(base::CreateDirectory(dest_path));
    290 
    291       FileSystemURL root_url = CreateURL(FPL(""));
    292       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    293 
    294       std::string test_name = base::StringPrintf(
    295           "CopySourceFiltering run %d test %" PRIuS, loop_count, i);
    296       base::File::Error expectation = base::File::FILE_OK;
    297       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    298         // If the source does not exist or is not visible.
    299         expectation = base::File::FILE_ERROR_NOT_FOUND;
    300       } else if (!kFilteringTestCases[i].is_directory) {
    301         // Cannot copy a visible file to a directory.
    302         expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    303       }
    304       operation_runner()->Copy(
    305           url,
    306           dest_url,
    307           storage::FileSystemOperation::OPTION_NONE,
    308           storage::FileSystemOperationRunner::CopyProgressCallback(),
    309           base::Bind(&ExpectEqHelper, test_name, expectation));
    310       base::MessageLoop::current()->RunUntilIdle();
    311     }
    312   }
    313 }
    314 
    315 TEST_F(NativeMediaFileUtilTest, CopyDestFiltering) {
    316   // Run the loop twice. The first run has no destination files.
    317   // The second run does.
    318   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    319     if (loop_count == 1) {
    320       // Reset the test directory between the two loops to remove old
    321       // directories and create new ones that should pre-exist.
    322       ASSERT_TRUE(base::DeleteFile(root_path(), true));
    323       ASSERT_TRUE(base::CreateDirectory(root_path()));
    324       PopulateDirectoryWithTestCases(root_path(),
    325                                      kFilteringTestCases,
    326                                      arraysize(kFilteringTestCases));
    327     }
    328 
    329     // Always create a dummy source data file.
    330     base::FilePath src_path = root_path().AppendASCII("foo.jpg");
    331     FileSystemURL src_url = CreateURL(FPL("foo.jpg"));
    332     static const char kDummyData[] = "dummy";
    333     ASSERT_TRUE(base::WriteFile(src_path, kDummyData, strlen(kDummyData)));
    334 
    335     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    336       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
    337         // These directories do not exist in this case, so Copy() will not
    338         // treat them as directories. Thus invalidating these test cases.
    339         continue;
    340       }
    341       FileSystemURL root_url = CreateURL(FPL(""));
    342       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    343 
    344       std::string test_name = base::StringPrintf(
    345           "CopyDestFiltering run %d test %" PRIuS, loop_count, i);
    346       base::File::Error expectation;
    347       if (loop_count == 0) {
    348         // The destination path is a file here. The directory case has been
    349         // handled above.
    350         // If the destination path does not exist and is not visible, then
    351         // creating it would be a security violation.
    352         expectation =
    353             kFilteringTestCases[i].visible ?
    354             base::File::FILE_OK :
    355             base::File::FILE_ERROR_SECURITY;
    356       } else {
    357         if (!kFilteringTestCases[i].visible) {
    358           // If the destination path exist and is not visible, then to the copy
    359           // operation, it looks like the file needs to be created, which is a
    360           // security violation.
    361           expectation = base::File::FILE_ERROR_SECURITY;
    362         } else if (kFilteringTestCases[i].is_directory) {
    363           // Cannot copy a file to a directory.
    364           expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    365         } else {
    366           // Copying from a file to a visible file that exists is ok.
    367           expectation = base::File::FILE_OK;
    368         }
    369       }
    370       operation_runner()->Copy(
    371           src_url,
    372           url,
    373           storage::FileSystemOperation::OPTION_NONE,
    374           storage::FileSystemOperationRunner::CopyProgressCallback(),
    375           base::Bind(&ExpectEqHelper, test_name, expectation));
    376       base::MessageLoop::current()->RunUntilIdle();
    377     }
    378   }
    379 }
    380 
    381 TEST_F(NativeMediaFileUtilTest, MoveSourceFiltering) {
    382   base::FilePath dest_path = root_path().AppendASCII("dest");
    383   FileSystemURL dest_url = CreateURL(FPL("dest"));
    384 
    385   // Run the loop twice. The first run has no source files. The second run does.
    386   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    387     if (loop_count == 1) {
    388       PopulateDirectoryWithTestCases(root_path(),
    389                                      kFilteringTestCases,
    390                                      arraysize(kFilteringTestCases));
    391     }
    392     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    393       // Always start with an empty destination directory.
    394       // Moving to a non-empty destination directory is an invalid operation.
    395       ASSERT_TRUE(base::DeleteFile(dest_path, true));
    396       ASSERT_TRUE(base::CreateDirectory(dest_path));
    397 
    398       FileSystemURL root_url = CreateURL(FPL(""));
    399       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    400 
    401       std::string test_name = base::StringPrintf(
    402           "MoveSourceFiltering run %d test %" PRIuS, loop_count, i);
    403       base::File::Error expectation = base::File::FILE_OK;
    404       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    405         // If the source does not exist or is not visible.
    406         expectation = base::File::FILE_ERROR_NOT_FOUND;
    407       } else if (!kFilteringTestCases[i].is_directory) {
    408         // Cannot move a visible file to a directory.
    409         expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    410       }
    411       operation_runner()->Move(
    412           url,
    413           dest_url,
    414           storage::FileSystemOperation::OPTION_NONE,
    415           base::Bind(&ExpectEqHelper, test_name, expectation));
    416       base::MessageLoop::current()->RunUntilIdle();
    417     }
    418   }
    419 }
    420 
    421 TEST_F(NativeMediaFileUtilTest, MoveDestFiltering) {
    422   // Run the loop twice. The first run has no destination files.
    423   // The second run does.
    424   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    425     if (loop_count == 1) {
    426       // Reset the test directory between the two loops to remove old
    427       // directories and create new ones that should pre-exist.
    428       ASSERT_TRUE(base::DeleteFile(root_path(), true));
    429       ASSERT_TRUE(base::CreateDirectory(root_path()));
    430       PopulateDirectoryWithTestCases(root_path(),
    431                                      kFilteringTestCases,
    432                                      arraysize(kFilteringTestCases));
    433     }
    434 
    435     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    436       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
    437         // These directories do not exist in this case, so Copy() will not
    438         // treat them as directories. Thus invalidating these test cases.
    439         continue;
    440       }
    441 
    442       // Create the source file for every test case because it might get moved.
    443       base::FilePath src_path = root_path().AppendASCII("foo.jpg");
    444       FileSystemURL src_url = CreateURL(FPL("foo.jpg"));
    445       static const char kDummyData[] = "dummy";
    446       ASSERT_TRUE(
    447           base::WriteFile(src_path, kDummyData, strlen(kDummyData)));
    448 
    449       FileSystemURL root_url = CreateURL(FPL(""));
    450       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    451 
    452       std::string test_name = base::StringPrintf(
    453           "MoveDestFiltering run %d test %" PRIuS, loop_count, i);
    454       base::File::Error expectation;
    455       if (loop_count == 0) {
    456         // The destination path is a file here. The directory case has been
    457         // handled above.
    458         // If the destination path does not exist and is not visible, then
    459         // creating it would be a security violation.
    460         expectation =
    461             kFilteringTestCases[i].visible ?
    462             base::File::FILE_OK :
    463             base::File::FILE_ERROR_SECURITY;
    464       } else {
    465         if (!kFilteringTestCases[i].visible) {
    466           // If the destination path exist and is not visible, then to the move
    467           // operation, it looks like the file needs to be created, which is a
    468           // security violation.
    469           expectation = base::File::FILE_ERROR_SECURITY;
    470         } else if (kFilteringTestCases[i].is_directory) {
    471           // Cannot move a file to a directory.
    472           expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    473         } else {
    474           // Moving from a file to a visible file that exists is ok.
    475           expectation = base::File::FILE_OK;
    476         }
    477       }
    478       operation_runner()->Move(
    479           src_url,
    480           url,
    481           storage::FileSystemOperation::OPTION_NONE,
    482           base::Bind(&ExpectEqHelper, test_name, expectation));
    483       base::MessageLoop::current()->RunUntilIdle();
    484     }
    485   }
    486 }
    487 
    488 TEST_F(NativeMediaFileUtilTest, GetMetadataFiltering) {
    489   // Run the loop twice. The first run has no files. The second run does.
    490   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    491     if (loop_count == 1) {
    492       PopulateDirectoryWithTestCases(root_path(),
    493                                      kFilteringTestCases,
    494                                      arraysize(kFilteringTestCases));
    495     }
    496     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    497       FileSystemURL root_url = CreateURL(FPL(""));
    498       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    499 
    500       std::string test_name = base::StringPrintf(
    501           "GetMetadataFiltering run %d test %" PRIuS, loop_count, i);
    502       base::File::Error expectation = base::File::FILE_OK;
    503       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    504         // Cannot get metadata from files that do not exist or are not visible.
    505         expectation = base::File::FILE_ERROR_NOT_FOUND;
    506       }
    507       operation_runner()->GetMetadata(
    508           url,
    509           base::Bind(&ExpectMetadataEqHelper,
    510                      test_name,
    511                      expectation,
    512                      kFilteringTestCases[i].is_directory));
    513       base::MessageLoop::current()->RunUntilIdle();
    514     }
    515   }
    516 }
    517 
    518 TEST_F(NativeMediaFileUtilTest, RemoveFileFiltering) {
    519   // Run the loop twice. The first run has no files. The second run does.
    520   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    521     if (loop_count == 1) {
    522       PopulateDirectoryWithTestCases(root_path(),
    523                                      kFilteringTestCases,
    524                                      arraysize(kFilteringTestCases));
    525     }
    526     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    527       FileSystemURL root_url = CreateURL(FPL(""));
    528       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    529 
    530       std::string test_name = base::StringPrintf(
    531           "RemoveFiltering run %d test %" PRIuS, loop_count, i);
    532       base::File::Error expectation = base::File::FILE_OK;
    533       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    534         // Cannot remove files that do not exist or are not visible.
    535         expectation = base::File::FILE_ERROR_NOT_FOUND;
    536       } else if (kFilteringTestCases[i].is_directory) {
    537         expectation = base::File::FILE_ERROR_NOT_A_FILE;
    538       }
    539       operation_runner()->RemoveFile(
    540           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    541       base::MessageLoop::current()->RunUntilIdle();
    542     }
    543   }
    544 }
    545 
    546 void CreateSnapshotCallback(
    547     base::File::Error* error,
    548     base::File::Error result,
    549     const base::File::Info&,
    550     const base::FilePath&,
    551     const scoped_refptr<storage::ShareableFileReference>&) {
    552   *error = result;
    553 }
    554 
    555 TEST_F(NativeMediaFileUtilTest, CreateSnapshot) {
    556   PopulateDirectoryWithTestCases(root_path(),
    557                                  kFilteringTestCases,
    558                                  arraysize(kFilteringTestCases));
    559   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    560     if (kFilteringTestCases[i].is_directory ||
    561         !kFilteringTestCases[i].visible) {
    562       continue;
    563     }
    564     FileSystemURL root_url = CreateURL(FPL(""));
    565     FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    566     base::File::Error expected_error, error;
    567     if (kFilteringTestCases[i].media_file)
    568       expected_error = base::File::FILE_OK;
    569     else
    570       expected_error = base::File::FILE_ERROR_SECURITY;
    571     error = base::File::FILE_ERROR_FAILED;
    572     operation_runner()->CreateSnapshotFile(url,
    573         base::Bind(CreateSnapshotCallback, &error));
    574     base::MessageLoop::current()->RunUntilIdle();
    575     ASSERT_EQ(expected_error, error);
    576   }
    577 }
    578