| // Copyright 2013 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include <map> | 
 | #include <memory> | 
 | #include <set> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | #include "base/containers/queue.h" | 
 | #include "base/files/file_enumerator.h" | 
 | #include "base/files/file_util.h" | 
 | #include "base/files/scoped_temp_dir.h" | 
 | #include "base/logging.h" | 
 | #include "base/macros.h" | 
 | #include "base/memory/ptr_util.h" | 
 | #include "base/message_loop/message_loop.h" | 
 | #include "base/time/time.h" | 
 | #include "build/build_config.h" | 
 | #include "storage/browser/fileapi/dragged_file_util.h" | 
 | #include "storage/browser/fileapi/file_system_context.h" | 
 | #include "storage/browser/fileapi/file_system_operation_context.h" | 
 | #include "storage/browser/fileapi/isolated_context.h" | 
 | #include "storage/browser/fileapi/local_file_util.h" | 
 | #include "storage/browser/fileapi/native_file_util.h" | 
 | #include "storage/browser/test/async_file_test_helper.h" | 
 | #include "storage/browser/test/fileapi_test_file_set.h" | 
 | #include "storage/browser/test/test_file_system_context.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 |  | 
 | using content::AsyncFileTestHelper; | 
 | using storage::FileSystemContext; | 
 | using storage::FileSystemOperationContext; | 
 | using storage::FileSystemType; | 
 | using storage::FileSystemURL; | 
 |  | 
 | namespace content { | 
 |  | 
 | namespace { | 
 |  | 
 | typedef AsyncFileTestHelper::FileEntryList FileEntryList; | 
 |  | 
 | // Used in DraggedFileUtilTest::SimulateDropFiles(). | 
 | // Random root paths in which we create each file/directory of the | 
 | // RegularTestCases (so that we can simulate a drop with files/directories | 
 | // from multiple directories). | 
 | constexpr const base::FilePath::CharType* kRootPaths[] = { | 
 |     FILE_PATH_LITERAL("a"), FILE_PATH_LITERAL("b/c"), FILE_PATH_LITERAL("etc"), | 
 | }; | 
 |  | 
 | base::FilePath GetTopLevelPath(const base::FilePath& path) { | 
 |   std::vector<base::FilePath::StringType> components; | 
 |   path.GetComponents(&components); | 
 |   return base::FilePath(components[0]); | 
 | } | 
 |  | 
 | bool IsDirectoryEmpty(FileSystemContext* context, const FileSystemURL& url) { | 
 |   FileEntryList entries; | 
 |   EXPECT_EQ(base::File::FILE_OK, | 
 |             AsyncFileTestHelper::ReadDirectory(context, url, &entries)); | 
 |   return entries.empty(); | 
 | } | 
 |  | 
 | FileSystemURL GetEntryURL(FileSystemContext* file_system_context, | 
 |                           const FileSystemURL& dir, | 
 |                           const base::FilePath::StringType& name) { | 
 |   return file_system_context->CreateCrackedFileSystemURL( | 
 |       dir.origin(), | 
 |       dir.mount_type(), | 
 |       dir.virtual_path().Append(name)); | 
 | } | 
 |  | 
 | base::FilePath GetRelativeVirtualPath(const FileSystemURL& root, | 
 |                                       const FileSystemURL& url) { | 
 |   if (root.virtual_path().empty()) | 
 |     return url.virtual_path(); | 
 |   base::FilePath relative; | 
 |   const bool success = root.virtual_path().AppendRelativePath( | 
 |       url.virtual_path(), &relative); | 
 |   DCHECK(success); | 
 |   return relative; | 
 | } | 
 |  | 
 | FileSystemURL GetOtherURL(FileSystemContext* file_system_context, | 
 |                           const FileSystemURL& root, | 
 |                           const FileSystemURL& other_root, | 
 |                           const FileSystemURL& url) { | 
 |   return file_system_context->CreateCrackedFileSystemURL( | 
 |       other_root.origin(), | 
 |       other_root.mount_type(), | 
 |       other_root.virtual_path().Append(GetRelativeVirtualPath(root, url))); | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | class DraggedFileUtilTest : public testing::Test { | 
 |  public: | 
 |   DraggedFileUtilTest() {} | 
 |  | 
 |   void SetUp() override { | 
 |     ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); | 
 |     ASSERT_TRUE(partition_dir_.CreateUniqueTempDir()); | 
 |     file_util_.reset(new storage::DraggedFileUtil()); | 
 |  | 
 |     // Register the files/directories of RegularTestCases (with random | 
 |     // root paths) as dropped files. | 
 |     SimulateDropFiles(); | 
 |  | 
 |     file_system_context_ = CreateFileSystemContextForTesting( | 
 |         NULL /* quota_manager */, partition_dir_.GetPath()); | 
 |  | 
 |     isolated_context()->AddReference(filesystem_id_); | 
 |   } | 
 |  | 
 |   void TearDown() override { | 
 |     isolated_context()->RemoveReference(filesystem_id_); | 
 |   } | 
 |  | 
 |  protected: | 
 |   storage::IsolatedContext* isolated_context() const { | 
 |     return storage::IsolatedContext::GetInstance(); | 
 |   } | 
 |   const base::FilePath& root_path() const { return data_dir_.GetPath(); } | 
 |   FileSystemContext* file_system_context() const { | 
 |     return file_system_context_.get(); | 
 |   } | 
 |   storage::FileSystemFileUtil* file_util() const { return file_util_.get(); } | 
 |   std::string filesystem_id() const { return filesystem_id_; } | 
 |  | 
 |   base::FilePath GetTestCasePlatformPath( | 
 |       const base::FilePath::StringType& path) { | 
 |     return toplevel_root_map_[GetTopLevelPath(base::FilePath(path))] | 
 |         .Append(path).NormalizePathSeparators(); | 
 |   } | 
 |  | 
 |   base::FilePath GetTestCaseLocalPath(const base::FilePath& path) { | 
 |     base::FilePath relative; | 
 |     if (data_dir_.GetPath().AppendRelativePath(path, &relative)) | 
 |       return relative; | 
 |     return path; | 
 |   } | 
 |  | 
 |   FileSystemURL GetFileSystemURL(const base::FilePath& path) const { | 
 |     base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath( | 
 |         filesystem_id()).Append(path); | 
 |     return file_system_context_->CreateCrackedFileSystemURL( | 
 |         GURL("http://example.com"), | 
 |         storage::kFileSystemTypeIsolated, | 
 |         virtual_path); | 
 |   } | 
 |  | 
 |   FileSystemURL GetOtherFileSystemURL(const base::FilePath& path) const { | 
 |     return file_system_context()->CreateCrackedFileSystemURL( | 
 |         GURL("http://example.com"), | 
 |         storage::kFileSystemTypeTemporary, | 
 |         base::FilePath().AppendASCII("dest").Append(path)); | 
 |   } | 
 |  | 
 |   void VerifyFilesHaveSameContent(const FileSystemURL& url1, | 
 |                                   const FileSystemURL& url2) { | 
 |     // Get the file info and the platform path for url1. | 
 |     base::File::Info info1; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::GetMetadata( | 
 |                   file_system_context(), url1, &info1)); | 
 |     base::FilePath platform_path1; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::GetPlatformPath( | 
 |                   file_system_context(), url1, &platform_path1)); | 
 |  | 
 |     // Get the file info and the platform path  for url2. | 
 |     base::File::Info info2; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::GetMetadata( | 
 |                   file_system_context(), url2, &info2)); | 
 |     base::FilePath platform_path2; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::GetPlatformPath( | 
 |                   file_system_context(), url2, &platform_path2)); | 
 |  | 
 |     // See if file info matches with the other one. | 
 |     EXPECT_EQ(info1.is_directory, info2.is_directory); | 
 |     EXPECT_EQ(info1.size, info2.size); | 
 |     EXPECT_EQ(info1.is_symbolic_link, info2.is_symbolic_link); | 
 |     EXPECT_NE(platform_path1, platform_path2); | 
 |  | 
 |     std::string content1, content2; | 
 |     EXPECT_TRUE(base::ReadFileToString(platform_path1, &content1)); | 
 |     EXPECT_TRUE(base::ReadFileToString(platform_path2, &content2)); | 
 |     EXPECT_EQ(content1, content2); | 
 |   } | 
 |  | 
 |   void VerifyDirectoriesHaveSameContent(const FileSystemURL& root1, | 
 |                                         const FileSystemURL& root2) { | 
 |     base::FilePath root_path1 = root1.path(); | 
 |     base::FilePath root_path2 = root2.path(); | 
 |  | 
 |     FileEntryList entries; | 
 |     base::queue<FileSystemURL> directories; | 
 |  | 
 |     directories.push(root1); | 
 |     std::set<base::FilePath> file_set1; | 
 |     while (!directories.empty()) { | 
 |       FileSystemURL dir = directories.front(); | 
 |       directories.pop(); | 
 |  | 
 |       ASSERT_EQ(base::File::FILE_OK, | 
 |                 AsyncFileTestHelper::ReadDirectory( | 
 |                     file_system_context(), dir, &entries)); | 
 |       for (size_t i = 0; i < entries.size(); ++i) { | 
 |         FileSystemURL url = GetEntryURL(file_system_context(), | 
 |                                         dir, entries[i].name); | 
 |         if (entries[i].is_directory) { | 
 |           directories.push(url); | 
 |           continue; | 
 |         } | 
 |         file_set1.insert(GetRelativeVirtualPath(root1, url)); | 
 |       } | 
 |     } | 
 |  | 
 |     directories.push(root2); | 
 |     while (!directories.empty()) { | 
 |       FileSystemURL dir = directories.front(); | 
 |       directories.pop(); | 
 |  | 
 |       ASSERT_EQ(base::File::FILE_OK, | 
 |                 AsyncFileTestHelper::ReadDirectory( | 
 |                     file_system_context(), dir, &entries)); | 
 |       for (size_t i = 0; i < entries.size(); ++i) { | 
 |         FileSystemURL url2 = GetEntryURL(file_system_context(), | 
 |                                          dir, entries[i].name); | 
 |         FileSystemURL url1 = GetOtherURL(file_system_context(), | 
 |                                          root2, root1, url2); | 
 |         if (entries[i].is_directory) { | 
 |           directories.push(url2); | 
 |           EXPECT_EQ(IsDirectoryEmpty(file_system_context(), url1), | 
 |                     IsDirectoryEmpty(file_system_context(), url2)); | 
 |           continue; | 
 |         } | 
 |         base::FilePath relative = GetRelativeVirtualPath(root2, url2); | 
 |         EXPECT_TRUE(file_set1.find(relative) != file_set1.end()); | 
 |         VerifyFilesHaveSameContent(url1, url2); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   std::unique_ptr<storage::FileSystemOperationContext> GetOperationContext() { | 
 |     return base::MakeUnique<storage::FileSystemOperationContext>( | 
 |         file_system_context()); | 
 |   } | 
 |  | 
 |  | 
 |  private: | 
 |   void SimulateDropFiles() { | 
 |     size_t root_path_index = 0; | 
 |  | 
 |     storage::IsolatedContext::FileInfoSet toplevels; | 
 |     for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |       const FileSystemTestCaseRecord& test_case = | 
 |           kRegularFileSystemTestCases[i]; | 
 |       base::FilePath path(test_case.path); | 
 |       base::FilePath toplevel = GetTopLevelPath(path); | 
 |  | 
 |       // We create the test case files under one of the kRootPaths | 
 |       // to simulate a drop with multiple directories. | 
 |       if (toplevel_root_map_.find(toplevel) == toplevel_root_map_.end()) { | 
 |         base::FilePath root = root_path().Append( | 
 |             kRootPaths[(root_path_index++) % arraysize(kRootPaths)]); | 
 |         toplevel_root_map_[toplevel] = root; | 
 |         toplevels.AddPath(root.Append(path), NULL); | 
 |       } | 
 |  | 
 |       SetUpOneFileSystemTestCase(toplevel_root_map_[toplevel], test_case); | 
 |     } | 
 |  | 
 |     // Register the toplevel entries. | 
 |     filesystem_id_ = isolated_context()->RegisterDraggedFileSystem(toplevels); | 
 |   } | 
 |  | 
 |   base::ScopedTempDir data_dir_; | 
 |   base::ScopedTempDir partition_dir_; | 
 |   base::MessageLoopForIO message_loop_; | 
 |   std::string filesystem_id_; | 
 |   scoped_refptr<FileSystemContext> file_system_context_; | 
 |   std::map<base::FilePath, base::FilePath> toplevel_root_map_; | 
 |   std::unique_ptr<storage::DraggedFileUtil> file_util_; | 
 |   DISALLOW_COPY_AND_ASSIGN(DraggedFileUtilTest); | 
 | }; | 
 |  | 
 | TEST_F(DraggedFileUtilTest, BasicTest) { | 
 |   for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |     SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i); | 
 |     const FileSystemTestCaseRecord& test_case = | 
 |         kRegularFileSystemTestCases[i]; | 
 |  | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |  | 
 |     // See if we can query the file info via the isolated FileUtil. | 
 |     // (This should succeed since we have registered all the top-level | 
 |     // entries of the test cases in SetUp()) | 
 |     base::File::Info info; | 
 |     base::FilePath platform_path; | 
 |     FileSystemOperationContext context(file_system_context()); | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               file_util()->GetFileInfo(&context, url, &info, &platform_path)); | 
 |  | 
 |     // See if the obtained file info is correct. | 
 |     if (!test_case.is_directory) | 
 |       ASSERT_EQ(test_case.data_file_size, info.size); | 
 |     ASSERT_EQ(test_case.is_directory, info.is_directory); | 
 |     ASSERT_EQ(GetTestCasePlatformPath(test_case.path), | 
 |               platform_path.NormalizePathSeparators()); | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, UnregisteredPathsTest) { | 
 |   static const FileSystemTestCaseRecord kUnregisteredCases[] = { | 
 |     {true, FILE_PATH_LITERAL("nonexistent"), 0}, | 
 |     {true, FILE_PATH_LITERAL("nonexistent/dir foo"), 0}, | 
 |     {false, FILE_PATH_LITERAL("nonexistent/false"), 0}, | 
 |     {false, FILE_PATH_LITERAL("foo"), 30}, | 
 |     {false, FILE_PATH_LITERAL("bar"), 20}, | 
 |   }; | 
 |  | 
 |   for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) { | 
 |     SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i); | 
 |     const FileSystemTestCaseRecord& test_case = kUnregisteredCases[i]; | 
 |  | 
 |     // Prepare the test file/directory. | 
 |     SetUpOneFileSystemTestCase(root_path(), test_case); | 
 |  | 
 |     // Make sure regular GetFileInfo succeeds. | 
 |     base::File::Info info; | 
 |     ASSERT_TRUE(base::GetFileInfo(root_path().Append(test_case.path), &info)); | 
 |     if (!test_case.is_directory) | 
 |       ASSERT_EQ(test_case.data_file_size, info.size); | 
 |     ASSERT_EQ(test_case.is_directory, info.is_directory); | 
 |   } | 
 |  | 
 |   for (size_t i = 0; i < arraysize(kUnregisteredCases); ++i) { | 
 |     SCOPED_TRACE(testing::Message() << "Creating kUnregisteredCases " << i); | 
 |     const FileSystemTestCaseRecord& test_case = kUnregisteredCases[i]; | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |  | 
 |     // We should not be able to get the valid URL for unregistered files. | 
 |     ASSERT_FALSE(url.is_valid()); | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, ReadDirectoryTest) { | 
 |   for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |     const FileSystemTestCaseRecord& test_case = | 
 |         kRegularFileSystemTestCases[i]; | 
 |     if (!test_case.is_directory) | 
 |       continue; | 
 |  | 
 |     SCOPED_TRACE(testing::Message() << "Testing RegularTestCases " << i | 
 |                  << ": " << test_case.path); | 
 |  | 
 |     // Read entries in the directory to construct the expected results map. | 
 |     typedef std::map<base::FilePath::StringType, storage::DirectoryEntry> | 
 |         EntryMap; | 
 |     EntryMap expected_entry_map; | 
 |  | 
 |     base::FilePath dir_path = GetTestCasePlatformPath(test_case.path); | 
 |     base::FileEnumerator file_enum( | 
 |         dir_path, false /* not recursive */, | 
 |         base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); | 
 |     base::FilePath current; | 
 |     while (!(current = file_enum.Next()).empty()) { | 
 |       base::FileEnumerator::FileInfo file_info = file_enum.GetInfo(); | 
 |       storage::DirectoryEntry entry; | 
 |       entry.is_directory = file_info.IsDirectory(); | 
 |       entry.name = current.BaseName().value(); | 
 |       expected_entry_map[entry.name] = entry; | 
 |  | 
 | #if defined(OS_POSIX) | 
 |       // Creates a symlink for each file/directory. | 
 |       // They should be ignored by ReadDirectory, so we don't add them | 
 |       // to expected_entry_map. | 
 |       base::CreateSymbolicLink( | 
 |           current, | 
 |           dir_path.Append(current.BaseName().AddExtension( | 
 |               FILE_PATH_LITERAL("link")))); | 
 | #endif | 
 |     } | 
 |  | 
 |     // Perform ReadDirectory in the isolated filesystem. | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |     FileEntryList entries; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::ReadDirectory( | 
 |                   file_system_context(), url, &entries)); | 
 |  | 
 |     EXPECT_EQ(expected_entry_map.size(), entries.size()); | 
 |     for (size_t i = 0; i < entries.size(); ++i) { | 
 |       const storage::DirectoryEntry& entry = entries[i]; | 
 |       EntryMap::iterator found = expected_entry_map.find(entry.name); | 
 |       EXPECT_TRUE(found != expected_entry_map.end()); | 
 |       EXPECT_EQ(found->second.name, entry.name); | 
 |       EXPECT_EQ(found->second.is_directory, entry.is_directory); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, GetLocalFilePathTest) { | 
 |   for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |     const FileSystemTestCaseRecord& test_case = | 
 |         kRegularFileSystemTestCases[i]; | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |  | 
 |     FileSystemOperationContext context(file_system_context()); | 
 |  | 
 |     base::FilePath local_file_path; | 
 |     EXPECT_EQ(base::File::FILE_OK, | 
 |               file_util()->GetLocalFilePath(&context, url, &local_file_path)); | 
 |     EXPECT_EQ(GetTestCasePlatformPath(test_case.path).value(), | 
 |               local_file_path.value()); | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, CopyOutFileTest) { | 
 |   FileSystemURL src_root = GetFileSystemURL(base::FilePath()); | 
 |   FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath()); | 
 |  | 
 |   FileEntryList entries; | 
 |   base::queue<FileSystemURL> directories; | 
 |   directories.push(src_root); | 
 |  | 
 |   ASSERT_EQ(base::File::FILE_OK, | 
 |             AsyncFileTestHelper::CreateDirectory(file_system_context(), | 
 |                                                  dest_root)); | 
 |  | 
 |   while (!directories.empty()) { | 
 |     FileSystemURL dir = directories.front(); | 
 |     directories.pop(); | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::ReadDirectory(file_system_context(), | 
 |                                                  dir, &entries)); | 
 |     for (size_t i = 0; i < entries.size(); ++i) { | 
 |       FileSystemURL src_url = GetEntryURL(file_system_context(), | 
 |                                           dir, entries[i].name); | 
 |       FileSystemURL dest_url = GetOtherURL(file_system_context(), | 
 |                                            src_root, dest_root, src_url); | 
 |  | 
 |       if (entries[i].is_directory) { | 
 |         ASSERT_EQ(base::File::FILE_OK, | 
 |                   AsyncFileTestHelper::CreateDirectory(file_system_context(), | 
 |                                                        dest_url)); | 
 |         directories.push(src_url); | 
 |         continue; | 
 |       } | 
 |       SCOPED_TRACE(testing::Message() << "Testing file copy " | 
 |                    << src_url.path().value()); | 
 |       ASSERT_EQ(base::File::FILE_OK, | 
 |                 AsyncFileTestHelper::Copy(file_system_context(), | 
 |                                           src_url, dest_url)); | 
 |       VerifyFilesHaveSameContent(src_url, dest_url); | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, CopyOutDirectoryTest) { | 
 |   FileSystemURL src_root = GetFileSystemURL(base::FilePath()); | 
 |   FileSystemURL dest_root = GetOtherFileSystemURL(base::FilePath()); | 
 |  | 
 |   ASSERT_EQ(base::File::FILE_OK, | 
 |             AsyncFileTestHelper::CreateDirectory(file_system_context(), | 
 |                                                  dest_root)); | 
 |  | 
 |   FileEntryList entries; | 
 |   ASSERT_EQ(base::File::FILE_OK, | 
 |             AsyncFileTestHelper::ReadDirectory(file_system_context(), | 
 |                                                src_root, &entries)); | 
 |   for (size_t i = 0; i < entries.size(); ++i) { | 
 |     if (!entries[i].is_directory) | 
 |       continue; | 
 |     FileSystemURL src_url = GetEntryURL(file_system_context(), | 
 |                                         src_root, entries[i].name); | 
 |     FileSystemURL dest_url = GetOtherURL(file_system_context(), | 
 |                                          src_root, dest_root, src_url); | 
 |     SCOPED_TRACE(testing::Message() << "Testing file copy " | 
 |                  << src_url.path().value()); | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               AsyncFileTestHelper::Copy(file_system_context(), | 
 |                                         src_url, dest_url)); | 
 |     VerifyDirectoriesHaveSameContent(src_url, dest_url); | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, TouchTest) { | 
 |   for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |     const FileSystemTestCaseRecord& test_case = | 
 |         kRegularFileSystemTestCases[i]; | 
 |     if (test_case.is_directory) | 
 |       continue; | 
 |     SCOPED_TRACE(testing::Message() << test_case.path); | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |  | 
 |     base::Time last_access_time = base::Time::FromTimeT(1000); | 
 |     base::Time last_modified_time = base::Time::FromTimeT(2000); | 
 |  | 
 |     EXPECT_EQ(base::File::FILE_OK, | 
 |               file_util()->Touch(GetOperationContext().get(), url, | 
 |                                  last_access_time, | 
 |                                  last_modified_time)); | 
 |  | 
 |     // Verification. | 
 |     base::File::Info info; | 
 |     base::FilePath platform_path; | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               file_util()->GetFileInfo(GetOperationContext().get(), url, | 
 |                                        &info, &platform_path)); | 
 |     EXPECT_EQ(last_access_time.ToTimeT(), info.last_accessed.ToTimeT()); | 
 |     EXPECT_EQ(last_modified_time.ToTimeT(), info.last_modified.ToTimeT()); | 
 |   } | 
 | } | 
 |  | 
 | TEST_F(DraggedFileUtilTest, TruncateTest) { | 
 |   for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) { | 
 |     const FileSystemTestCaseRecord& test_case = | 
 |         kRegularFileSystemTestCases[i]; | 
 |     if (test_case.is_directory) | 
 |       continue; | 
 |  | 
 |     SCOPED_TRACE(testing::Message() << test_case.path); | 
 |     FileSystemURL url = GetFileSystemURL(base::FilePath(test_case.path)); | 
 |  | 
 |     // Truncate to 0. | 
 |     base::File::Info info; | 
 |     base::FilePath platform_path; | 
 |     EXPECT_EQ(base::File::FILE_OK, | 
 |               file_util()->Truncate(GetOperationContext().get(), url, 0)); | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               file_util()->GetFileInfo(GetOperationContext().get(), url, | 
 |                                        &info, &platform_path)); | 
 |     EXPECT_EQ(0, info.size); | 
 |  | 
 |     // Truncate (extend) to 999. | 
 |     EXPECT_EQ(base::File::FILE_OK, | 
 |               file_util()->Truncate(GetOperationContext().get(), url, 999)); | 
 |     ASSERT_EQ(base::File::FILE_OK, | 
 |               file_util()->GetFileInfo(GetOperationContext().get(), url, | 
 |                                        &info, &platform_path)); | 
 |     EXPECT_EQ(999, info.size); | 
 |   } | 
 | } | 
 |  | 
 | }  // namespace content |