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 <map>
      6 #include <queue>
      7 #include <set>
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/file_util.h"
     12 #include "base/files/file_enumerator.h"
     13 #include "base/files/scoped_temp_dir.h"
     14 #include "base/logging.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/message_loop/message_loop_proxy.h"
     17 #include "base/time/time.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 #include "webkit/browser/fileapi/async_file_test_helper.h"
     20 #include "webkit/browser/fileapi/file_system_context.h"
     21 #include "webkit/browser/fileapi/file_system_operation_context.h"
     22 #include "webkit/browser/fileapi/isolated_context.h"
     23 #include "webkit/browser/fileapi/isolated_file_util.h"
     24 #include "webkit/browser/fileapi/local_file_util.h"
     25 #include "webkit/browser/fileapi/mock_file_system_context.h"
     26 #include "webkit/browser/fileapi/native_file_util.h"
     27 #include "webkit/browser/fileapi/test_file_set.h"
     28 
     29 namespace fileapi {
     30 
     31 namespace {
     32 
     33 typedef AsyncFileTestHelper::FileEntryList FileEntryList;
     34 
     35 // Used in IsolatedFileUtilTest::SimulateDropFiles().
     36 // Random root paths in which we create each file/directory of the
     37 // RegularTestCases (so that we can simulate a drop with files/directories
     38 // from multiple directories).
     39 static const base::FilePath::CharType* kRootPaths[] = {
     40   FILE_PATH_LITERAL("a"),
     41   FILE_PATH_LITERAL("b/c"),
     42   FILE_PATH_LITERAL("etc"),
     43 };
     44 
     45 base::FilePath GetTopLevelPath(const base::FilePath& path) {
     46   std::vector<base::FilePath::StringType> components;
     47   path.GetComponents(&components);
     48   return base::FilePath(components[0]);
     49 }
     50 
     51 bool IsDirectoryEmpty(FileSystemContext* context, const FileSystemURL& url) {
     52   FileEntryList entries;
     53   EXPECT_EQ(base::PLATFORM_FILE_OK,
     54             AsyncFileTestHelper::ReadDirectory(context, url, &entries));
     55   return entries.empty();
     56 }
     57 
     58 FileSystemURL GetEntryURL(FileSystemContext* file_system_context,
     59                           const FileSystemURL& dir,
     60                           const base::FilePath::StringType& name) {
     61   return file_system_context->CreateCrackedFileSystemURL(
     62       dir.origin(),
     63       dir.mount_type(),
     64       dir.virtual_path().Append(name));
     65 }
     66 
     67 base::FilePath GetRelativeVirtualPath(const FileSystemURL& root,
     68                                       const FileSystemURL& url) {
     69   if (root.virtual_path().empty())
     70     return url.virtual_path();
     71   base::FilePath relative;
     72   const bool success = root.virtual_path().AppendRelativePath(
     73       url.virtual_path(), &relative);
     74   DCHECK(success);
     75   return relative;
     76 }
     77 
     78 FileSystemURL GetOtherURL(FileSystemContext* file_system_context,
     79                           const FileSystemURL& root,
     80                           const FileSystemURL& other_root,
     81                           const FileSystemURL& url) {
     82   return file_system_context->CreateCrackedFileSystemURL(
     83       other_root.origin(),
     84       other_root.mount_type(),
     85       other_root.virtual_path().Append(GetRelativeVirtualPath(root, url)));
     86 }
     87 
     88 }  // namespace
     89 
     90 // TODO(kinuko): we should have separate tests for DraggedFileUtil and
     91 // IsolatedFileUtil.
     92 class IsolatedFileUtilTest : public testing::Test {
     93  public:
     94   IsolatedFileUtilTest() {}
     95 
     96   virtual void SetUp() {
     97     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
     98     ASSERT_TRUE(partition_dir_.CreateUniqueTempDir());
     99     file_util_.reset(new DraggedFileUtil());
    100 
    101     // Register the files/directories of RegularTestCases (with random
    102     // root paths) as dropped files.
    103     SimulateDropFiles();
    104 
    105     file_system_context_ = CreateFileSystemContextForTesting(
    106         NULL /* quota_manager */,
    107         partition_dir_.path());
    108 
    109     isolated_context()->AddReference(filesystem_id_);
    110   }
    111 
    112   virtual void TearDown() {
    113     isolated_context()->RemoveReference(filesystem_id_);
    114   }
    115 
    116  protected:
    117   IsolatedContext* isolated_context() const {
    118     return IsolatedContext::GetInstance();
    119   }
    120   const base::FilePath& root_path() const {
    121     return data_dir_.path();
    122   }
    123   FileSystemContext* file_system_context() const {
    124     return file_system_context_.get();
    125   }
    126   FileSystemFileUtil* file_util() const { return file_util_.get(); }
    127   std::string filesystem_id() const { return filesystem_id_; }
    128 
    129   base::FilePath GetTestCasePlatformPath(
    130       const base::FilePath::StringType& path) {
    131     return toplevel_root_map_[GetTopLevelPath(base::FilePath(path))]
    132         .Append(path).NormalizePathSeparators();
    133   }
    134 
    135   base::FilePath GetTestCaseLocalPath(const base::FilePath& path) {
    136     base::FilePath relative;
    137     if (data_dir_.path().AppendRelativePath(path, &relative))
    138       return relative;
    139     return path;
    140   }
    141 
    142   FileSystemURL GetFileSystemURL(const base::FilePath& path) const {
    143     base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(
    144         filesystem_id()).Append(path);
    145     return file_system_context_->CreateCrackedFileSystemURL(
    146         GURL("http://example.com"),
    147         kFileSystemTypeIsolated,
    148         virtual_path);
    149   }
    150 
    151   FileSystemURL GetOtherFileSystemURL(const base::FilePath& path) const {
    152     return file_system_context()->CreateCrackedFileSystemURL(
    153         GURL("http://example.com"),
    154         kFileSystemTypeTemporary,
    155         base::FilePath().AppendASCII("dest").Append(path));
    156   }
    157 
    158   void VerifyFilesHaveSameContent(const FileSystemURL& url1,
    159                                   const FileSystemURL& url2) {
    160     // Get the file info and the platform path for url1.
    161     base::PlatformFileInfo info1;
    162     ASSERT_EQ(base::PLATFORM_FILE_OK,
    163               AsyncFileTestHelper::GetMetadata(
    164                   file_system_context(), url1, &info1));
    165     base::FilePath platform_path1;
    166     ASSERT_EQ(base::PLATFORM_FILE_OK,
    167               AsyncFileTestHelper::GetPlatformPath(
    168                   file_system_context(), url1, &platform_path1));
    169 
    170     // Get the file info and the platform path  for url2.
    171     base::PlatformFileInfo info2;
    172     ASSERT_EQ(base::PLATFORM_FILE_OK,
    173               AsyncFileTestHelper::GetMetadata(
    174                   file_system_context(), url2, &info2));
    175     base::FilePath platform_path2;
    176     ASSERT_EQ(base::PLATFORM_FILE_OK,
    177               AsyncFileTestHelper::GetPlatformPath(
    178                   file_system_context(), url2, &platform_path2));
    179 
    180     // See if file info matches with the other one.
    181     EXPECT_EQ(info1.is_directory, info2.is_directory);
    182     EXPECT_EQ(info1.size, info2.size);
    183     EXPECT_EQ(info1.is_symbolic_link, info2.is_symbolic_link);
    184     EXPECT_NE(platform_path1, platform_path2);
    185 
    186     std::string content1, content2;
    187     EXPECT_TRUE(file_util::ReadFileToString(platform_path1, &content1));
    188     EXPECT_TRUE(file_util::ReadFileToString(platform_path2, &content2));
    189     EXPECT_EQ(content1, content2);
    190   }
    191 
    192   void VerifyDirectoriesHaveSameContent(const FileSystemURL& root1,
    193                                         const FileSystemURL& root2) {
    194     base::FilePath root_path1 = root1.path();
    195     base::FilePath root_path2 = root2.path();
    196 
    197     FileEntryList entries;
    198     std::queue<FileSystemURL> directories;
    199 
    200     directories.push(root1);
    201     std::set<base::FilePath> file_set1;
    202     while (!directories.empty()) {
    203       FileSystemURL dir = directories.front();
    204       directories.pop();
    205 
    206       ASSERT_EQ(base::PLATFORM_FILE_OK,
    207                 AsyncFileTestHelper::ReadDirectory(
    208                     file_system_context(), dir, &entries));
    209       for (size_t i = 0; i < entries.size(); ++i) {
    210         FileSystemURL url = GetEntryURL(file_system_context(),
    211                                         dir, entries[i].name);
    212         if (entries[i].is_directory) {
    213           directories.push(url);
    214           continue;
    215         }
    216         file_set1.insert(GetRelativeVirtualPath(root1, url));
    217       }
    218     }
    219 
    220     directories.push(root2);
    221     while (!directories.empty()) {
    222       FileSystemURL dir = directories.front();
    223       directories.pop();
    224 
    225       ASSERT_EQ(base::PLATFORM_FILE_OK,
    226                 AsyncFileTestHelper::ReadDirectory(
    227                     file_system_context(), dir, &entries));
    228       for (size_t i = 0; i < entries.size(); ++i) {
    229         FileSystemURL url2 = GetEntryURL(file_system_context(),
    230                                          dir, entries[i].name);
    231         FileSystemURL url1 = GetOtherURL(file_system_context(),
    232                                          root2, root1, url2);
    233         if (entries[i].is_directory) {
    234           directories.push(url2);
    235           EXPECT_EQ(IsDirectoryEmpty(file_system_context(), url1),
    236                     IsDirectoryEmpty(file_system_context(), url2));
    237           continue;
    238         }
    239         base::FilePath relative = GetRelativeVirtualPath(root2, url2);
    240         EXPECT_TRUE(file_set1.find(relative) != file_set1.end());
    241         VerifyFilesHaveSameContent(url1, url2);
    242       }
    243     }
    244   }
    245 
    246   scoped_ptr<FileSystemOperationContext> GetOperationContext() {
    247     return make_scoped_ptr(
    248         new FileSystemOperationContext(file_system_context())).Pass();
    249   }
    250 
    251 
    252  private:
    253   void SimulateDropFiles() {
    254     size_t root_path_index = 0;
    255 
    256     IsolatedContext::FileInfoSet toplevels;
    257     for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    258       const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    259       base::FilePath path(test_case.path);
    260       base::FilePath toplevel = GetTopLevelPath(path);
    261 
    262       // We create the test case files under one of the kRootPaths
    263       // to simulate a drop with multiple directories.
    264       if (toplevel_root_map_.find(toplevel) == toplevel_root_map_.end()) {
    265         base::FilePath root = root_path().Append(
    266             kRootPaths[(root_path_index++) % arraysize(kRootPaths)]);
    267         toplevel_root_map_[toplevel] = root;
    268         toplevels.AddPath(root.Append(path), NULL);
    269       }
    270 
    271       test::SetUpOneTestCase(toplevel_root_map_[toplevel], test_case);
    272     }
    273 
    274     // Register the toplevel entries.
    275     filesystem_id_ = isolated_context()->RegisterDraggedFileSystem(toplevels);
    276   }
    277 
    278   base::ScopedTempDir data_dir_;
    279   base::ScopedTempDir partition_dir_;
    280   base::MessageLoop message_loop_;
    281   std::string filesystem_id_;
    282   scoped_refptr<FileSystemContext> file_system_context_;
    283   std::map<base::FilePath, base::FilePath> toplevel_root_map_;
    284   scoped_ptr<IsolatedFileUtil> file_util_;
    285   DISALLOW_COPY_AND_ASSIGN(IsolatedFileUtilTest);
    286 };
    287 
    288 TEST_F(IsolatedFileUtilTest, BasicTest) {
    289   for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    290     SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i);
    291     const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    292 
    293     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    294 
    295     // See if we can query the file info via the isolated FileUtil.
    296     // (This should succeed since we have registered all the top-level
    297     // entries of the test cases in SetUp())
    298     base::PlatformFileInfo info;
    299     base::FilePath platform_path;
    300     FileSystemOperationContext context(file_system_context());
    301     ASSERT_EQ(base::PLATFORM_FILE_OK,
    302               file_util()->GetFileInfo(&context, url, &info, &platform_path));
    303 
    304     // See if the obtained file info is correct.
    305     if (!test_case.is_directory)
    306       ASSERT_EQ(test_case.data_file_size, info.size);
    307     ASSERT_EQ(test_case.is_directory, info.is_directory);
    308     ASSERT_EQ(GetTestCasePlatformPath(test_case.path),
    309               platform_path.NormalizePathSeparators());
    310   }
    311 }
    312 
    313 TEST_F(IsolatedFileUtilTest, UnregisteredPathsTest) {
    314   static const fileapi::test::TestCaseRecord kUnregisteredCases[] = {
    315     {true, FILE_PATH_LITERAL("nonexistent"), 0},
    316     {true, FILE_PATH_LITERAL("nonexistent/dir foo"), 0},
    317     {false, FILE_PATH_LITERAL("nonexistent/false"), 0},
    318     {false, FILE_PATH_LITERAL("foo"), 30},
    319     {false, FILE_PATH_LITERAL("bar"), 20},
    320   };
    321 
    322   for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) {
    323     SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i);
    324     const test::TestCaseRecord& test_case = kUnregisteredCases[i];
    325 
    326     // Prepare the test file/directory.
    327     SetUpOneTestCase(root_path(), test_case);
    328 
    329     // Make sure regular GetFileInfo succeeds.
    330     base::PlatformFileInfo info;
    331     ASSERT_TRUE(file_util::GetFileInfo(
    332         root_path().Append(test_case.path), &info));
    333     if (!test_case.is_directory)
    334       ASSERT_EQ(test_case.data_file_size, info.size);
    335     ASSERT_EQ(test_case.is_directory, info.is_directory);
    336   }
    337 
    338   for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) {
    339     SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i);
    340     const test::TestCaseRecord& test_case = kUnregisteredCases[i];
    341     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    342 
    343     // We should not be able to get the valid URL for unregistered files.
    344     ASSERT_FALSE(url.is_valid());
    345   }
    346 }
    347 
    348 TEST_F(IsolatedFileUtilTest, ReadDirectoryTest) {
    349   for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    350     const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    351     if (!test_case.is_directory)
    352       continue;
    353 
    354     SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i
    355                  << ": " << test_case.path);
    356 
    357     // Read entries in the directory to construct the expected results map.
    358     typedef std::map<base::FilePath::StringType, DirectoryEntry> EntryMap;
    359     EntryMap expected_entry_map;
    360 
    361     base::FilePath dir_path = GetTestCasePlatformPath(test_case.path);
    362     base::FileEnumerator file_enum(
    363         dir_path, false /* not recursive */,
    364         base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
    365     base::FilePath current;
    366     while (!(current = file_enum.Next()).empty()) {
    367       base::FileEnumerator::FileInfo file_info = file_enum.GetInfo();
    368       DirectoryEntry entry;
    369       entry.is_directory = file_info.IsDirectory();
    370       entry.name = current.BaseName().value();
    371       entry.size = file_info.GetSize();
    372       entry.last_modified_time = file_info.GetLastModifiedTime();
    373       expected_entry_map[entry.name] = entry;
    374 
    375 #if defined(OS_POSIX)
    376       // Creates a symlink for each file/directory.
    377       // They should be ignored by ReadDirectory, so we don't add them
    378       // to expected_entry_map.
    379       file_util::CreateSymbolicLink(
    380           current,
    381           dir_path.Append(current.BaseName().AddExtension(
    382               FILE_PATH_LITERAL("link"))));
    383 #endif
    384     }
    385 
    386     // Perform ReadDirectory in the isolated filesystem.
    387     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    388     FileEntryList entries;
    389     ASSERT_EQ(base::PLATFORM_FILE_OK,
    390               AsyncFileTestHelper::ReadDirectory(
    391                   file_system_context(), url, &entries));
    392 
    393     EXPECT_EQ(expected_entry_map.size(), entries.size());
    394     for (size_t i = 0; i < entries.size(); ++i) {
    395       const DirectoryEntry& entry = entries[i];
    396       EntryMap::iterator found = expected_entry_map.find(entry.name);
    397       EXPECT_TRUE(found != expected_entry_map.end());
    398       EXPECT_EQ(found->second.name, entry.name);
    399       EXPECT_EQ(found->second.is_directory, entry.is_directory);
    400       EXPECT_EQ(found->second.size, entry.size);
    401       EXPECT_EQ(found->second.last_modified_time.ToDoubleT(),
    402                 entry.last_modified_time.ToDoubleT());
    403     }
    404   }
    405 }
    406 
    407 TEST_F(IsolatedFileUtilTest, GetLocalFilePathTest) {
    408   for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    409     const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    410     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    411 
    412     FileSystemOperationContext context(file_system_context());
    413 
    414     base::FilePath local_file_path;
    415     EXPECT_EQ(base::PLATFORM_FILE_OK,
    416               file_util()->GetLocalFilePath(&context, url, &local_file_path));
    417     EXPECT_EQ(GetTestCasePlatformPath(test_case.path).value(),
    418               local_file_path.value());
    419   }
    420 }
    421 
    422 TEST_F(IsolatedFileUtilTest, CopyOutFileTest) {
    423   FileSystemURL src_root = GetFileSystemURL(base::FilePath());
    424   FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath());
    425 
    426   FileEntryList entries;
    427   std::queue<FileSystemURL> directories;
    428   directories.push(src_root);
    429 
    430   ASSERT_EQ(base::PLATFORM_FILE_OK,
    431             AsyncFileTestHelper::CreateDirectory(file_system_context(),
    432                                                  dest_root));
    433 
    434   while (!directories.empty()) {
    435     FileSystemURL dir = directories.front();
    436     directories.pop();
    437     ASSERT_EQ(base::PLATFORM_FILE_OK,
    438               AsyncFileTestHelper::ReadDirectory(file_system_context(),
    439                                                  dir, &entries));
    440     for (size_t i = 0; i < entries.size(); ++i) {
    441       FileSystemURL src_url = GetEntryURL(file_system_context(),
    442                                           dir, entries[i].name);
    443       FileSystemURL dest_url = GetOtherURL(file_system_context(),
    444                                            src_root, dest_root, src_url);
    445 
    446       if (entries[i].is_directory) {
    447         ASSERT_EQ(base::PLATFORM_FILE_OK,
    448                   AsyncFileTestHelper::CreateDirectory(file_system_context(),
    449                                                        dest_url));
    450         directories.push(src_url);
    451         continue;
    452       }
    453       SCOPED_TRACE(testing::Message() << "Testing file copy "
    454                    << src_url.path().value());
    455       ASSERT_EQ(base::PLATFORM_FILE_OK,
    456                 AsyncFileTestHelper::Copy(file_system_context(),
    457                                           src_url, dest_url));
    458       VerifyFilesHaveSameContent(src_url, dest_url);
    459     }
    460   }
    461 }
    462 
    463 TEST_F(IsolatedFileUtilTest, CopyOutDirectoryTest) {
    464   FileSystemURL src_root = GetFileSystemURL(base::FilePath());
    465   FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath());
    466 
    467   ASSERT_EQ(base::PLATFORM_FILE_OK,
    468             AsyncFileTestHelper::CreateDirectory(file_system_context(),
    469                                                  dest_root));
    470 
    471   FileEntryList entries;
    472   ASSERT_EQ(base::PLATFORM_FILE_OK,
    473             AsyncFileTestHelper::ReadDirectory(file_system_context(),
    474                                                src_root, &entries));
    475   for (size_t i = 0; i < entries.size(); ++i) {
    476     if (!entries[i].is_directory)
    477       continue;
    478     FileSystemURL src_url = GetEntryURL(file_system_context(),
    479                                         src_root, entries[i].name);
    480     FileSystemURL dest_url = GetOtherURL(file_system_context(),
    481                                          src_root, dest_root, src_url);
    482     SCOPED_TRACE(testing::Message() << "Testing file copy "
    483                  << src_url.path().value());
    484     ASSERT_EQ(base::PLATFORM_FILE_OK,
    485               AsyncFileTestHelper::Copy(file_system_context(),
    486                                         src_url, dest_url));
    487     VerifyDirectoriesHaveSameContent(src_url, dest_url);
    488   }
    489 }
    490 
    491 TEST_F(IsolatedFileUtilTest, TouchTest) {
    492   for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    493     const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    494     if (test_case.is_directory)
    495       continue;
    496     SCOPED_TRACE(testing::Message() << test_case.path);
    497     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    498 
    499     base::Time last_access_time = base::Time::FromTimeT(1000);
    500     base::Time last_modified_time = base::Time::FromTimeT(2000);
    501 
    502     EXPECT_EQ(base::PLATFORM_FILE_OK,
    503               file_util()->Touch(GetOperationContext().get(), url,
    504                                  last_access_time,
    505                                  last_modified_time));
    506 
    507     // Verification.
    508     base::PlatformFileInfo info;
    509     base::FilePath platform_path;
    510     ASSERT_EQ(base::PLATFORM_FILE_OK,
    511               file_util()->GetFileInfo(GetOperationContext().get(), url,
    512                                        &info, &platform_path));
    513     EXPECT_EQ(last_access_time.ToTimeT(), info.last_accessed.ToTimeT());
    514     EXPECT_EQ(last_modified_time.ToTimeT(), info.last_modified.ToTimeT());
    515   }
    516 }
    517 
    518 TEST_F(IsolatedFileUtilTest, TruncateTest) {
    519   for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
    520     const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
    521     if (test_case.is_directory)
    522       continue;
    523 
    524     SCOPED_TRACE(testing::Message() << test_case.path);
    525     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path));
    526 
    527     // Truncate to 0.
    528     base::PlatformFileInfo info;
    529     base::FilePath platform_path;
    530     EXPECT_EQ(base::PLATFORM_FILE_OK,
    531               file_util()->Truncate(GetOperationContext().get(), url, 0));
    532     ASSERT_EQ(base::PLATFORM_FILE_OK,
    533               file_util()->GetFileInfo(GetOperationContext().get(), url,
    534                                        &info, &platform_path));
    535     EXPECT_EQ(0, info.size);
    536 
    537     // Truncate (extend) to 999.
    538     EXPECT_EQ(base::PLATFORM_FILE_OK,
    539               file_util()->Truncate(GetOperationContext().get(), url, 999));
    540     ASSERT_EQ(base::PLATFORM_FILE_OK,
    541               file_util()->GetFileInfo(GetOperationContext().get(), url,
    542                                        &info, &platform_path));
    543     EXPECT_EQ(999, info.size);
    544   }
    545 }
    546 
    547 }  // namespace fileapi
    548