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/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 "testing/gtest/include/gtest/gtest.h"
     22 #include "webkit/browser/fileapi/external_mount_points.h"
     23 #include "webkit/browser/fileapi/file_system_backend.h"
     24 #include "webkit/browser/fileapi/file_system_context.h"
     25 #include "webkit/browser/fileapi/file_system_operation_runner.h"
     26 #include "webkit/browser/fileapi/file_system_url.h"
     27 #include "webkit/browser/fileapi/isolated_context.h"
     28 #include "webkit/browser/fileapi/native_file_util.h"
     29 
     30 #define FPL(x) FILE_PATH_LITERAL(x)
     31 
     32 using fileapi::FileSystemOperation;
     33 using fileapi::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<quota::SpecialStoragePolicy> storage_policy =
    123         new content::MockSpecialStoragePolicy();
    124 
    125     ScopedVector<fileapi::FileSystemBackend> additional_providers;
    126     additional_providers.push_back(new MediaFileSystemBackend(
    127         data_dir_.path(), base::MessageLoopProxy::current().get()));
    128 
    129     file_system_context_ = new fileapi::FileSystemContext(
    130         base::MessageLoopProxy::current().get(),
    131         base::MessageLoopProxy::current().get(),
    132         fileapi::ExternalMountPoints::CreateRefCounted().get(),
    133         storage_policy.get(),
    134         NULL,
    135         additional_providers.Pass(),
    136         std::vector<fileapi::URLRequestAutoMountHandler>(),
    137         data_dir_.path(),
    138         content::CreateAllowFileAccessOptions());
    139 
    140     filesystem_id_ = isolated_context()->RegisterFileSystemForPath(
    141         fileapi::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   fileapi::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         fileapi::kFileSystemTypeIsolated,
    160         GetVirtualPath(test_case_path));
    161   }
    162 
    163   fileapi::IsolatedContext* isolated_context() {
    164     return fileapi::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   fileapi::FileSystemType type() {
    183     return fileapi::kFileSystemTypeNativeMedia;
    184   }
    185 
    186   fileapi::FileSystemOperationRunner* operation_runner() {
    187     return file_system_context_->operation_runner();
    188   }
    189 
    190  private:
    191   base::MessageLoop message_loop_;
    192   content::TestBrowserThread io_thread_;
    193 
    194   base::ScopedTempDir data_dir_;
    195   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
    196 
    197   std::string filesystem_id_;
    198 
    199   DISALLOW_COPY_AND_ASSIGN(NativeMediaFileUtilTest);
    200 };
    201 
    202 TEST_F(NativeMediaFileUtilTest, DirectoryExistsAndFileExistsFiltering) {
    203   PopulateDirectoryWithTestCases(root_path(),
    204                                  kFilteringTestCases,
    205                                  arraysize(kFilteringTestCases));
    206 
    207   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    208     FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    209 
    210     base::File::Error expectation =
    211         kFilteringTestCases[i].visible ?
    212         base::File::FILE_OK :
    213         base::File::FILE_ERROR_NOT_FOUND;
    214 
    215     std::string test_name =
    216         base::StringPrintf("DirectoryExistsAndFileExistsFiltering %" PRIuS, i);
    217     if (kFilteringTestCases[i].is_directory) {
    218       operation_runner()->DirectoryExists(
    219           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    220     } else {
    221       operation_runner()->FileExists(
    222           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    223     }
    224     base::MessageLoop::current()->RunUntilIdle();
    225   }
    226 }
    227 
    228 TEST_F(NativeMediaFileUtilTest, ReadDirectoryFiltering) {
    229   PopulateDirectoryWithTestCases(root_path(),
    230                                  kFilteringTestCases,
    231                                  arraysize(kFilteringTestCases));
    232 
    233   std::set<base::FilePath::StringType> content;
    234   FileSystemURL url = CreateURL(FPL(""));
    235   bool completed = false;
    236   operation_runner()->ReadDirectory(
    237       url, base::Bind(&DidReadDirectory, &content, &completed));
    238   base::MessageLoop::current()->RunUntilIdle();
    239   EXPECT_TRUE(completed);
    240   EXPECT_EQ(6u, content.size());
    241 
    242   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    243     base::FilePath::StringType name =
    244         base::FilePath(kFilteringTestCases[i].path).BaseName().value();
    245     std::set<base::FilePath::StringType>::const_iterator found =
    246         content.find(name);
    247     EXPECT_EQ(kFilteringTestCases[i].visible, found != content.end());
    248   }
    249 }
    250 
    251 TEST_F(NativeMediaFileUtilTest, CreateDirectoryFiltering) {
    252   // Run the loop twice. The second loop attempts to create directories that are
    253   // pre-existing. Though the result should be the same.
    254   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    255     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    256       if (kFilteringTestCases[i].is_directory) {
    257         FileSystemURL root_url = CreateURL(FPL(""));
    258         FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    259 
    260         std::string test_name = base::StringPrintf(
    261             "CreateFileAndCreateDirectoryFiltering run %d, test %" PRIuS,
    262             loop_count, i);
    263         base::File::Error expectation =
    264             kFilteringTestCases[i].visible ?
    265             base::File::FILE_OK :
    266             base::File::FILE_ERROR_SECURITY;
    267         operation_runner()->CreateDirectory(
    268             url, false, false,
    269             base::Bind(&ExpectEqHelper, test_name, expectation));
    270       }
    271       base::MessageLoop::current()->RunUntilIdle();
    272     }
    273   }
    274 }
    275 
    276 TEST_F(NativeMediaFileUtilTest, CopySourceFiltering) {
    277   base::FilePath dest_path = root_path().AppendASCII("dest");
    278   FileSystemURL dest_url = CreateURL(FPL("dest"));
    279 
    280   // Run the loop twice. The first run has no source files. The second run does.
    281   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    282     if (loop_count == 1) {
    283       PopulateDirectoryWithTestCases(root_path(),
    284                                      kFilteringTestCases,
    285                                      arraysize(kFilteringTestCases));
    286     }
    287     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    288       // Always start with an empty destination directory.
    289       // Copying to a non-empty destination directory is an invalid operation.
    290       ASSERT_TRUE(base::DeleteFile(dest_path, true));
    291       ASSERT_TRUE(base::CreateDirectory(dest_path));
    292 
    293       FileSystemURL root_url = CreateURL(FPL(""));
    294       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    295 
    296       std::string test_name = base::StringPrintf(
    297           "CopySourceFiltering run %d test %" PRIuS, loop_count, i);
    298       base::File::Error expectation = base::File::FILE_OK;
    299       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    300         // If the source does not exist or is not visible.
    301         expectation = base::File::FILE_ERROR_NOT_FOUND;
    302       } else if (!kFilteringTestCases[i].is_directory) {
    303         // Cannot copy a visible file to a directory.
    304         expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    305       }
    306       operation_runner()->Copy(
    307           url, dest_url,
    308           fileapi::FileSystemOperation::OPTION_NONE,
    309           fileapi::FileSystemOperationRunner::CopyProgressCallback(),
    310           base::Bind(&ExpectEqHelper, test_name, expectation));
    311       base::MessageLoop::current()->RunUntilIdle();
    312     }
    313   }
    314 }
    315 
    316 TEST_F(NativeMediaFileUtilTest, CopyDestFiltering) {
    317   // Run the loop twice. The first run has no destination files.
    318   // The second run does.
    319   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    320     if (loop_count == 1) {
    321       // Reset the test directory between the two loops to remove old
    322       // directories and create new ones that should pre-exist.
    323       ASSERT_TRUE(base::DeleteFile(root_path(), true));
    324       ASSERT_TRUE(base::CreateDirectory(root_path()));
    325       PopulateDirectoryWithTestCases(root_path(),
    326                                      kFilteringTestCases,
    327                                      arraysize(kFilteringTestCases));
    328     }
    329 
    330     // Always create a dummy source data file.
    331     base::FilePath src_path = root_path().AppendASCII("foo.jpg");
    332     FileSystemURL src_url = CreateURL(FPL("foo.jpg"));
    333     static const char kDummyData[] = "dummy";
    334     ASSERT_TRUE(base::WriteFile(src_path, kDummyData, strlen(kDummyData)));
    335 
    336     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    337       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
    338         // These directories do not exist in this case, so Copy() will not
    339         // treat them as directories. Thus invalidating these test cases.
    340         continue;
    341       }
    342       FileSystemURL root_url = CreateURL(FPL(""));
    343       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    344 
    345       std::string test_name = base::StringPrintf(
    346           "CopyDestFiltering run %d test %" PRIuS, loop_count, i);
    347       base::File::Error expectation;
    348       if (loop_count == 0) {
    349         // The destination path is a file here. The directory case has been
    350         // handled above.
    351         // If the destination path does not exist and is not visible, then
    352         // creating it would be a security violation.
    353         expectation =
    354             kFilteringTestCases[i].visible ?
    355             base::File::FILE_OK :
    356             base::File::FILE_ERROR_SECURITY;
    357       } else {
    358         if (!kFilteringTestCases[i].visible) {
    359           // If the destination path exist and is not visible, then to the copy
    360           // operation, it looks like the file needs to be created, which is a
    361           // security violation.
    362           expectation = base::File::FILE_ERROR_SECURITY;
    363         } else if (kFilteringTestCases[i].is_directory) {
    364           // Cannot copy a file to a directory.
    365           expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    366         } else {
    367           // Copying from a file to a visible file that exists is ok.
    368           expectation = base::File::FILE_OK;
    369         }
    370       }
    371       operation_runner()->Copy(
    372           src_url, url,
    373           fileapi::FileSystemOperation::OPTION_NONE,
    374           fileapi::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, dest_url, fileapi::FileSystemOperation::OPTION_NONE,
    413           base::Bind(&ExpectEqHelper, test_name, expectation));
    414       base::MessageLoop::current()->RunUntilIdle();
    415     }
    416   }
    417 }
    418 
    419 TEST_F(NativeMediaFileUtilTest, MoveDestFiltering) {
    420   // Run the loop twice. The first run has no destination files.
    421   // The second run does.
    422   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    423     if (loop_count == 1) {
    424       // Reset the test directory between the two loops to remove old
    425       // directories and create new ones that should pre-exist.
    426       ASSERT_TRUE(base::DeleteFile(root_path(), true));
    427       ASSERT_TRUE(base::CreateDirectory(root_path()));
    428       PopulateDirectoryWithTestCases(root_path(),
    429                                      kFilteringTestCases,
    430                                      arraysize(kFilteringTestCases));
    431     }
    432 
    433     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    434       if (loop_count == 0 && kFilteringTestCases[i].is_directory) {
    435         // These directories do not exist in this case, so Copy() will not
    436         // treat them as directories. Thus invalidating these test cases.
    437         continue;
    438       }
    439 
    440       // Create the source file for every test case because it might get moved.
    441       base::FilePath src_path = root_path().AppendASCII("foo.jpg");
    442       FileSystemURL src_url = CreateURL(FPL("foo.jpg"));
    443       static const char kDummyData[] = "dummy";
    444       ASSERT_TRUE(
    445           base::WriteFile(src_path, kDummyData, strlen(kDummyData)));
    446 
    447       FileSystemURL root_url = CreateURL(FPL(""));
    448       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    449 
    450       std::string test_name = base::StringPrintf(
    451           "MoveDestFiltering run %d test %" PRIuS, loop_count, i);
    452       base::File::Error expectation;
    453       if (loop_count == 0) {
    454         // The destination path is a file here. The directory case has been
    455         // handled above.
    456         // If the destination path does not exist and is not visible, then
    457         // creating it would be a security violation.
    458         expectation =
    459             kFilteringTestCases[i].visible ?
    460             base::File::FILE_OK :
    461             base::File::FILE_ERROR_SECURITY;
    462       } else {
    463         if (!kFilteringTestCases[i].visible) {
    464           // If the destination path exist and is not visible, then to the move
    465           // operation, it looks like the file needs to be created, which is a
    466           // security violation.
    467           expectation = base::File::FILE_ERROR_SECURITY;
    468         } else if (kFilteringTestCases[i].is_directory) {
    469           // Cannot move a file to a directory.
    470           expectation = base::File::FILE_ERROR_INVALID_OPERATION;
    471         } else {
    472           // Moving from a file to a visible file that exists is ok.
    473           expectation = base::File::FILE_OK;
    474         }
    475       }
    476       operation_runner()->Move(
    477           src_url, url, fileapi::FileSystemOperation::OPTION_NONE,
    478           base::Bind(&ExpectEqHelper, test_name, expectation));
    479       base::MessageLoop::current()->RunUntilIdle();
    480     }
    481   }
    482 }
    483 
    484 TEST_F(NativeMediaFileUtilTest, GetMetadataFiltering) {
    485   // Run the loop twice. The first run has no files. The second run does.
    486   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    487     if (loop_count == 1) {
    488       PopulateDirectoryWithTestCases(root_path(),
    489                                      kFilteringTestCases,
    490                                      arraysize(kFilteringTestCases));
    491     }
    492     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    493       FileSystemURL root_url = CreateURL(FPL(""));
    494       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    495 
    496       std::string test_name = base::StringPrintf(
    497           "GetMetadataFiltering run %d test %" PRIuS, loop_count, i);
    498       base::File::Error expectation = base::File::FILE_OK;
    499       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    500         // Cannot get metadata from files that do not exist or are not visible.
    501         expectation = base::File::FILE_ERROR_NOT_FOUND;
    502       }
    503       operation_runner()->GetMetadata(
    504           url,
    505           base::Bind(&ExpectMetadataEqHelper,
    506                      test_name,
    507                      expectation,
    508                      kFilteringTestCases[i].is_directory));
    509       base::MessageLoop::current()->RunUntilIdle();
    510     }
    511   }
    512 }
    513 
    514 TEST_F(NativeMediaFileUtilTest, RemoveFileFiltering) {
    515   // Run the loop twice. The first run has no files. The second run does.
    516   for (int loop_count = 0; loop_count < 2; ++loop_count) {
    517     if (loop_count == 1) {
    518       PopulateDirectoryWithTestCases(root_path(),
    519                                      kFilteringTestCases,
    520                                      arraysize(kFilteringTestCases));
    521     }
    522     for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    523       FileSystemURL root_url = CreateURL(FPL(""));
    524       FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    525 
    526       std::string test_name = base::StringPrintf(
    527           "RemoveFiltering run %d test %" PRIuS, loop_count, i);
    528       base::File::Error expectation = base::File::FILE_OK;
    529       if (loop_count == 0 || !kFilteringTestCases[i].visible) {
    530         // Cannot remove files that do not exist or are not visible.
    531         expectation = base::File::FILE_ERROR_NOT_FOUND;
    532       } else if (kFilteringTestCases[i].is_directory) {
    533         expectation = base::File::FILE_ERROR_NOT_A_FILE;
    534       }
    535       operation_runner()->RemoveFile(
    536           url, base::Bind(&ExpectEqHelper, test_name, expectation));
    537       base::MessageLoop::current()->RunUntilIdle();
    538     }
    539   }
    540 }
    541 
    542 void CreateSnapshotCallback(
    543     base::File::Error* error,
    544     base::File::Error result,
    545     const base::File::Info&,
    546     const base::FilePath&,
    547     const scoped_refptr<webkit_blob::ShareableFileReference>&) {
    548   *error = result;
    549 }
    550 
    551 TEST_F(NativeMediaFileUtilTest, CreateSnapshot) {
    552   PopulateDirectoryWithTestCases(root_path(),
    553                                  kFilteringTestCases,
    554                                  arraysize(kFilteringTestCases));
    555   for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) {
    556     if (kFilteringTestCases[i].is_directory ||
    557         !kFilteringTestCases[i].visible) {
    558       continue;
    559     }
    560     FileSystemURL root_url = CreateURL(FPL(""));
    561     FileSystemURL url = CreateURL(kFilteringTestCases[i].path);
    562     base::File::Error expected_error, error;
    563     if (kFilteringTestCases[i].media_file)
    564       expected_error = base::File::FILE_OK;
    565     else
    566       expected_error = base::File::FILE_ERROR_SECURITY;
    567     error = base::File::FILE_ERROR_FAILED;
    568     operation_runner()->CreateSnapshotFile(url,
    569         base::Bind(CreateSnapshotCallback, &error));
    570     base::MessageLoop::current()->RunUntilIdle();
    571     ASSERT_EQ(expected_error, error);
    572   }
    573 }
    574