| // Copyright (c) 2010 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 "webkit/fileapi/file_system_operation.h" |
| |
| #include "base/logging.h" |
| #include "base/message_loop.h" |
| #include "base/scoped_ptr.h" |
| #include "base/scoped_temp_dir.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "webkit/fileapi/file_system_callback_dispatcher.h" |
| #include "webkit/fileapi/file_system_operation.h" |
| |
| namespace fileapi { |
| |
| const int kInvalidRequestId = -1; |
| const int kFileOperationStatusNotSet = 0; |
| const int kFileOperationSucceeded = 1; |
| |
| static int last_request_id = -1; |
| |
| static bool FileExists(FilePath path) { |
| return file_util::PathExists(path) && !file_util::DirectoryExists(path); |
| } |
| |
| class MockDispatcher : public FileSystemCallbackDispatcher { |
| public: |
| MockDispatcher(int request_id) |
| : status_(kFileOperationStatusNotSet), |
| request_id_(request_id) { |
| } |
| |
| virtual void DidFail(base::PlatformFileError status) { |
| status_ = status; |
| } |
| |
| virtual void DidSucceed() { |
| status_ = kFileOperationSucceeded; |
| } |
| |
| virtual void DidReadMetadata(const base::PlatformFileInfo& info) { |
| info_ = info; |
| status_ = kFileOperationSucceeded; |
| } |
| |
| virtual void DidReadDirectory( |
| const std::vector<base::FileUtilProxy::Entry>& entries, |
| bool /* has_more */) { |
| entries_ = entries; |
| } |
| |
| virtual void DidOpenFileSystem(const std::string&, const FilePath&) { |
| NOTREACHED(); |
| } |
| |
| virtual void DidWrite(int64 bytes, bool complete) { |
| NOTREACHED(); |
| } |
| |
| // Helpers for testing. |
| int status() const { return status_; } |
| int request_id() const { return request_id_; } |
| const base::PlatformFileInfo& info() const { return info_; } |
| const std::vector<base::FileUtilProxy::Entry>& entries() const { |
| return entries_; |
| } |
| |
| private: |
| int status_; |
| int request_id_; |
| base::PlatformFileInfo info_; |
| std::vector<base::FileUtilProxy::Entry> entries_; |
| }; |
| |
| class FileSystemOperationTest : public testing::Test { |
| public: |
| FileSystemOperationTest() |
| : request_id_(kInvalidRequestId), |
| operation_(NULL) { |
| base_.CreateUniqueTempDir(); |
| EXPECT_TRUE(base_.IsValid()); |
| } |
| |
| FileSystemOperation* operation() { |
| request_id_ = ++last_request_id; |
| mock_dispatcher_ = new MockDispatcher(request_id_); |
| operation_.reset(new FileSystemOperation( |
| mock_dispatcher_, base::MessageLoopProxy::CreateForCurrentThread())); |
| return operation_.get(); |
| } |
| |
| protected: |
| // Common temp base for nondestructive uses. |
| ScopedTempDir base_; |
| |
| int request_id_; |
| scoped_ptr<FileSystemOperation> operation_; |
| |
| // Owned by |operation_|. |
| MockDispatcher* mock_dispatcher_; |
| |
| DISALLOW_COPY_AND_ASSIGN(FileSystemOperationTest); |
| }; |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureSrcDoesntExist) { |
| FilePath src(base_.path().Append(FILE_PATH_LITERAL("a"))); |
| FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b"))); |
| operation()->Move(src, dest); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureContainsPath) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath dest_dir_path; |
| ASSERT_TRUE(file_util::CreateTemporaryDirInDir(src_dir.path(), |
| FILE_PATH_LITERAL("child_dir"), |
| &dest_dir_path)); |
| operation()->Move(src_dir.path(), dest_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) { |
| // Src exists and is dir. Dest is a file. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file); |
| |
| operation()->Move(src_dir.path(), dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureSrcFileExistsDestNonEmptyDir) { |
| // Src exists and is a directory. Dest is a non-empty directory. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &child_file); |
| |
| operation()->Move(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureSrcFileExistsDestDir) { |
| // Src exists and is a file. Dest is a directory. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Move(src_file, dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath nonexisting_file = base_.path().Append( |
| FILE_PATH_LITERAL("NonexistingDir")).Append( |
| FILE_PATH_LITERAL("NonexistingFile")); |
| |
| operation()->Move(src_dir.path(), nonexisting_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file); |
| |
| operation()->Move(src_file, dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(dest_file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndNew) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile"))); |
| |
| operation()->Move(src_file, dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(dest_file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirAndOverwrite) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Move(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| EXPECT_FALSE(file_util::DirectoryExists(src_dir.path())); |
| |
| // Make sure we've overwritten but not moved the source under the |dest_dir|. |
| EXPECT_TRUE(file_util::DirectoryExists(dest_dir.path())); |
| EXPECT_FALSE(file_util::DirectoryExists( |
| dest_dir.path().Append(src_dir.path().BaseName()))); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirAndNew) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath dest_dir_path(dir.path().Append(FILE_PATH_LITERAL("NewDirectory"))); |
| |
| operation()->Move(src_dir.path(), dest_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| EXPECT_FALSE(file_util::DirectoryExists(src_dir.path())); |
| EXPECT_TRUE(file_util::DirectoryExists(dest_dir_path)); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirRecursive) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &child_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Move(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| EXPECT_TRUE(FileExists(dest_dir.path().Append(child_file.BaseName()))); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureSrcDoesntExist) { |
| FilePath src(base_.path().Append(FILE_PATH_LITERAL("a"))); |
| FilePath dest(base_.path().Append(FILE_PATH_LITERAL("b"))); |
| operation()->Copy(src, dest); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureContainsPath) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath dest_dir_path; |
| ASSERT_TRUE(file_util::CreateTemporaryDirInDir(src_dir.path(), |
| FILE_PATH_LITERAL("child_dir"), |
| &dest_dir_path)); |
| operation()->Copy(src_dir.path(), dest_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) { |
| // Src exists and is dir. Dest is a file. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file); |
| |
| operation()->Copy(src_dir.path(), dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureSrcFileExistsDestNonEmptyDir) { |
| // Src exists and is a directory. Dest is a non-empty directory. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &child_file); |
| |
| operation()->Copy(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureSrcFileExistsDestDir) { |
| // Src exists and is a file. Dest is a directory. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Copy(src_file, dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopyFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath src_dir = dir.path(); |
| |
| FilePath nonexisting(base_.path().Append(FILE_PATH_LITERAL("DontExistDir"))); |
| file_util::EnsureEndsWithSeparator(&nonexisting); |
| FilePath nonexisting_file = nonexisting.Append( |
| FILE_PATH_LITERAL("DontExistFile")); |
| |
| operation()->Copy(src_dir, nonexisting_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file; |
| file_util::CreateTemporaryFileInDir(dest_dir.path(), &dest_file); |
| |
| operation()->Copy(src_file, dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(dest_file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndNew) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath src_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &src_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| FilePath dest_file(dest_dir.path().Append(FILE_PATH_LITERAL("NewFile"))); |
| |
| operation()->Copy(src_file, dest_file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(dest_file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Copy(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Make sure we've overwritten but not copied the source under the |dest_dir|. |
| EXPECT_TRUE(file_util::DirectoryExists(dest_dir.path())); |
| EXPECT_FALSE(file_util::DirectoryExists( |
| dest_dir.path().Append(src_dir.path().BaseName()))); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndNew) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath dest_dir(dir.path().Append(FILE_PATH_LITERAL("NewDirectory"))); |
| |
| operation()->Copy(src_dir.path(), dest_dir); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| EXPECT_TRUE(file_util::DirectoryExists(dest_dir)); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirRecursive) { |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(src_dir.path(), &child_file); |
| |
| ScopedTempDir dest_dir; |
| ASSERT_TRUE(dest_dir.CreateUniqueTempDir()); |
| |
| operation()->Copy(src_dir.path(), dest_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| EXPECT_TRUE(FileExists(dest_dir.path().Append(child_file.BaseName()))); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateFileFailure) { |
| // Already existing file and exclusive true. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file; |
| |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| operation()->CreateFile(file, true); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateVeryLongName) { |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| |
| #if defined(OS_WIN) |
| FilePath dir_path(FILE_PATH_LITERAL("\\\\?\\") + dir.path().value()); |
| #else |
| FilePath dir_path = dir.path(); |
| #endif |
| |
| // TODO(kkanetkar): Once each platform's limitations have been enforced |
| // consider that in this test. Currently this test is for |
| // windows primarily. |
| FilePath dir1 = dir_path.AppendASCII( |
| "012345678901234567890123456789012345678901234567890123456789" |
| "012345678901234567890123456789012345678901234567890123456789" |
| "0123456789012345678901234567890123456789"); |
| FilePath file = dir1.AppendASCII( |
| "012345678901234567890123456789012345678901234567890123456789" |
| "012345678901234567890123456789012345678901234567890123456789" |
| "0123456789012345678901234567890123456789"); |
| operation()->CreateDirectory(dir1, false, true); |
| MessageLoop::current()->RunAllPending(); |
| operation()->CreateFile(file, true); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_TRUE(file_util::PathExists(file)); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileExists) { |
| // Already existing file and exclusive false. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file; |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| |
| operation()->CreateFile(file, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateFileSuccessExclusive) { |
| // File doesn't exist but exclusive is true. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist")); |
| operation()->CreateFile(file, true); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(FileExists(file)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) { |
| // Non existing file. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file = dir.path().Append(FILE_PATH_LITERAL("FileDoesntExist")); |
| operation()->CreateFile(file, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, |
| TestCreateDirFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| FilePath nonexisting(base_.path().Append( |
| FILE_PATH_LITERAL("DirDoesntExist"))); |
| FilePath nonexisting_file = nonexisting.Append( |
| FILE_PATH_LITERAL("FileDoesntExist")); |
| operation()->CreateDirectory(nonexisting_file, false, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateDirFailureDirExists) { |
| // Exclusive and dir existing at path. |
| ScopedTempDir src_dir; |
| ASSERT_TRUE(src_dir.CreateUniqueTempDir()); |
| operation()->CreateDirectory(src_dir.path(), true, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateDirFailureFileExists) { |
| // Exclusive true and file existing at path. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file; |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| operation()->CreateDirectory(file, true, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateDirSuccess) { |
| // Dir exists and exclusive is false. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| operation()->CreateDirectory(dir.path(), false, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Dir doesn't exist. |
| FilePath nonexisting_dir_path(base_.path().Append( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| operation()->CreateDirectory(nonexisting_dir_path, false, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestCreateDirSuccessExclusive) { |
| // Dir doesn't exist. |
| FilePath nonexisting_dir_path(base_.path().Append( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| |
| operation()->CreateDirectory(nonexisting_dir_path, true, false); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(file_util::DirectoryExists(nonexisting_dir_path)); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestExistsAndMetadataFailure) { |
| FilePath nonexisting_dir_path(base_.path().Append( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| operation()->GetMetadata(nonexisting_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| |
| operation()->FileExists(nonexisting_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| file_util::EnsureEndsWithSeparator(&nonexisting_dir_path); |
| operation()->DirectoryExists(nonexisting_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestExistsAndMetadataSuccess) { |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| |
| operation()->DirectoryExists(dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| operation()->GetMetadata(dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_TRUE(mock_dispatcher_->info().is_directory); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| FilePath file; |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| operation()->FileExists(file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| operation()->GetMetadata(file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_FALSE(mock_dispatcher_->info().is_directory); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestReadDirFailure) { |
| // Path doesn't exists |
| FilePath nonexisting_dir_path(base_.path().Append( |
| FILE_PATH_LITERAL("NonExistingDir"))); |
| file_util::EnsureEndsWithSeparator(&nonexisting_dir_path); |
| operation()->ReadDirectory(nonexisting_dir_path); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // File exists. |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file; |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| operation()->ReadDirectory(file); |
| MessageLoop::current()->RunAllPending(); |
| // TODO(kkanetkar) crbug.com/54309 to change the error code. |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestReadDirSuccess) { |
| // parent_dir |
| // | | |
| // child_dir child_file |
| // Verify reading parent_dir. |
| ScopedTempDir parent_dir; |
| ASSERT_TRUE(parent_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file); |
| FilePath child_dir; |
| ASSERT_TRUE(file_util::CreateTemporaryDirInDir( |
| parent_dir.path(), FILE_PATH_LITERAL("child_dir"), &child_dir)); |
| |
| operation()->ReadDirectory(parent_dir.path()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationStatusNotSet, mock_dispatcher_->status()); |
| EXPECT_EQ(2u, mock_dispatcher_->entries().size()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| for (size_t i = 0; i < mock_dispatcher_->entries().size(); ++i) { |
| if (mock_dispatcher_->entries()[i].is_directory) { |
| EXPECT_EQ(child_dir.BaseName().value(), |
| mock_dispatcher_->entries()[i].name); |
| } else { |
| EXPECT_EQ(child_file.BaseName().value(), |
| mock_dispatcher_->entries()[i].name); |
| } |
| } |
| } |
| |
| TEST_F(FileSystemOperationTest, TestRemoveFailure) { |
| // Path doesn't exist. |
| FilePath nonexisting(base_.path().Append( |
| FILE_PATH_LITERAL("NonExistingDir"))); |
| file_util::EnsureEndsWithSeparator(&nonexisting); |
| |
| operation()->Remove(nonexisting, false /* recursive */); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // It's an error to try to remove a non-empty directory if recursive flag |
| // is false. |
| // parent_dir |
| // | | |
| // child_dir child_file |
| // Verify deleting parent_dir. |
| ScopedTempDir parent_dir; |
| ASSERT_TRUE(parent_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file); |
| FilePath child_dir; |
| ASSERT_TRUE(file_util::CreateTemporaryDirInDir( |
| parent_dir.path(), FILE_PATH_LITERAL("child_dir"), &child_dir)); |
| |
| operation()->Remove(parent_dir.path(), false /* recursive */); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, |
| mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| TEST_F(FileSystemOperationTest, TestRemoveSuccess) { |
| ScopedTempDir empty_dir; |
| ASSERT_TRUE(empty_dir.CreateUniqueTempDir()); |
| EXPECT_TRUE(file_util::DirectoryExists(empty_dir.path())); |
| |
| operation()->Remove(empty_dir.path(), false /* recursive */); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_FALSE(file_util::DirectoryExists(empty_dir.path())); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Removing a non-empty directory with recursive flag == true should be ok. |
| // parent_dir |
| // | | |
| // child_dir child_file |
| // Verify deleting parent_dir. |
| ScopedTempDir parent_dir; |
| ASSERT_TRUE(parent_dir.CreateUniqueTempDir()); |
| FilePath child_file; |
| file_util::CreateTemporaryFileInDir(parent_dir.path(), &child_file); |
| FilePath child_dir; |
| ASSERT_TRUE(file_util::CreateTemporaryDirInDir( |
| parent_dir.path(), FILE_PATH_LITERAL("child_dir"), &child_dir)); |
| |
| operation()->Remove(parent_dir.path(), true /* recursive */); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_FALSE(file_util::DirectoryExists(parent_dir.path())); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| } |
| |
| // TODO(ericu): Add tests for Write, Cancel. |
| |
| TEST_F(FileSystemOperationTest, TestTruncate) { |
| ScopedTempDir dir; |
| ASSERT_TRUE(dir.CreateUniqueTempDir()); |
| FilePath file; |
| file_util::CreateTemporaryFileInDir(dir.path(), &file); |
| |
| char test_data[] = "test data"; |
| int data_size = static_cast<int>(sizeof(test_data)); |
| EXPECT_EQ(data_size, |
| file_util::WriteFile(file, test_data, data_size)); |
| |
| // Check that its length is the size of the data written. |
| operation()->GetMetadata(file); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_FALSE(mock_dispatcher_->info().is_directory); |
| EXPECT_EQ(data_size, mock_dispatcher_->info().size); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Extend the file by truncating it. |
| int length = 17; |
| operation()->Truncate(file, length); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Check that its length is now 17 and that it's all zeroes after the test |
| // data. |
| base::PlatformFileInfo info; |
| |
| EXPECT_TRUE(file_util::GetFileInfo(file, &info)); |
| EXPECT_EQ(length, info.size); |
| char data[100]; |
| EXPECT_EQ(length, file_util::ReadFile(file, data, length)); |
| for (int i = 0; i < length; ++i) { |
| if (i < static_cast<int>(sizeof(test_data))) |
| EXPECT_EQ(test_data[i], data[i]); |
| else |
| EXPECT_EQ(0, data[i]); |
| } |
| |
| // Shorten the file by truncating it. |
| length = 3; |
| operation()->Truncate(file, length); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(kFileOperationSucceeded, mock_dispatcher_->status()); |
| EXPECT_EQ(request_id_, mock_dispatcher_->request_id()); |
| |
| // Check that its length is now 3 and that it contains only bits of test data. |
| EXPECT_TRUE(file_util::GetFileInfo(file, &info)); |
| EXPECT_EQ(length, info.size); |
| EXPECT_EQ(length, file_util::ReadFile(file, data, length)); |
| for (int i = 0; i < length; ++i) |
| EXPECT_EQ(test_data[i], data[i]); |
| } |
| |
| } // namespace fileapi |