| // Copyright (c) 2012 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/local_file_system_operation.h" |
| |
| #include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop.h" |
| #include "base/scoped_temp_dir.h" |
| #include "base/string_number_conversions.h" |
| #include "googleurl/src/gurl.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "webkit/blob/shareable_file_reference.h" |
| #include "webkit/fileapi/file_system_context.h" |
| #include "webkit/fileapi/file_system_file_util.h" |
| #include "webkit/fileapi/file_system_mount_point_provider.h" |
| #include "webkit/fileapi/file_system_quota_util.h" |
| #include "webkit/fileapi/file_system_util.h" |
| #include "webkit/fileapi/file_util_helper.h" |
| #include "webkit/fileapi/local_file_system_test_helper.h" |
| #include "webkit/fileapi/mock_file_change_observer.h" |
| #include "webkit/quota/quota_manager.h" |
| #include "webkit/quota/mock_quota_manager.h" |
| |
| using quota::QuotaManager; |
| using quota::QuotaManagerProxy; |
| using webkit_blob::ShareableFileReference; |
| |
| namespace fileapi { |
| |
| namespace { |
| |
| const int kFileOperationStatusNotSet = 1; |
| |
| void AssertFileErrorEq(base::PlatformFileError expected, |
| base::PlatformFileError actual) { |
| ASSERT_EQ(expected, actual); |
| } |
| |
| FilePath ASCIIToFilePath(const std::string& str) { |
| return FilePath().AppendASCII(str); |
| } |
| |
| } // namespace (anonymous) |
| |
| // Test class for LocalFileSystemOperation. |
| class LocalFileSystemOperationTest |
| : public testing::Test, |
| public base::SupportsWeakPtr<LocalFileSystemOperationTest> { |
| public: |
| LocalFileSystemOperationTest() |
| : status_(kFileOperationStatusNotSet), |
| next_unique_path_suffix_(0) { |
| EXPECT_TRUE(base_.CreateUniqueTempDir()); |
| change_observers_ = MockFileChangeObserver::CreateList(&change_observer_); |
| } |
| |
| LocalFileSystemOperation* operation(); |
| |
| int status() const { return status_; } |
| const base::PlatformFileInfo& info() const { return info_; } |
| const FilePath& path() const { return path_; } |
| const std::vector<base::FileUtilProxy::Entry>& entries() const { |
| return entries_; |
| } |
| const ShareableFileReference* shareable_file_ref() const { |
| return shareable_file_ref_; |
| } |
| |
| virtual void SetUp() OVERRIDE; |
| virtual void TearDown() OVERRIDE; |
| |
| protected: |
| // Common temp base for nondestructive uses. |
| ScopedTempDir base_; |
| |
| quota::MockQuotaManager* quota_manager() { |
| return static_cast<quota::MockQuotaManager*>(quota_manager_.get()); |
| } |
| |
| quota::MockQuotaManagerProxy* quota_manager_proxy() { |
| return static_cast<quota::MockQuotaManagerProxy*>( |
| quota_manager_proxy_.get()); |
| } |
| |
| FileSystemFileUtil* file_util() { |
| return test_helper_.file_util(); |
| } |
| |
| const ChangeObserverList& change_observers() const { |
| return change_observers_; |
| } |
| |
| MockFileChangeObserver* change_observer() { |
| return &change_observer_; |
| } |
| |
| FileSystemOperationContext* NewContext() { |
| FileSystemOperationContext* context = test_helper_.NewOperationContext(); |
| // Grant enough quota for all test cases. |
| context->set_allowed_bytes_growth(1000000); |
| return context; |
| } |
| |
| FileSystemURL URLForPath(const FilePath& path) const { |
| return test_helper_.CreateURL(path); |
| } |
| |
| FilePath PlatformPath(const FilePath& virtual_path) { |
| return test_helper_.GetLocalPath(virtual_path); |
| } |
| |
| bool FileExists(const FilePath& virtual_path) { |
| FileSystemURL path = test_helper_.CreateURL(virtual_path); |
| scoped_ptr<FileSystemOperationContext> context(NewContext()); |
| if (!FileUtilHelper::PathExists(context.get(), file_util(), path)) |
| return false; |
| |
| context.reset(NewContext()); |
| return !FileUtilHelper::DirectoryExists(context.get(), file_util(), path); |
| } |
| |
| bool DirectoryExists(const FilePath& virtual_path) { |
| FileSystemURL url = test_helper_.CreateURL(virtual_path); |
| scoped_ptr<FileSystemOperationContext> context(NewContext()); |
| return FileUtilHelper::DirectoryExists(context.get(), file_util(), url); |
| } |
| |
| FilePath CreateUniqueFileInDir(const FilePath& virtual_dir_path) { |
| FilePath file_name = FilePath::FromUTF8Unsafe( |
| "tmpfile-" + base::IntToString(next_unique_path_suffix_++)); |
| FileSystemURL url = test_helper_.CreateURL( |
| virtual_dir_path.Append(file_name)); |
| |
| scoped_ptr<FileSystemOperationContext> context(NewContext()); |
| bool created; |
| EXPECT_EQ(base::PLATFORM_FILE_OK, |
| file_util()->EnsureFileExists(context.get(), url, &created)); |
| EXPECT_TRUE(created); |
| return url.path(); |
| } |
| |
| FilePath CreateUniqueDirInDir(const FilePath& virtual_dir_path) { |
| FilePath dir_name = FilePath::FromUTF8Unsafe( |
| "tmpdir-" + base::IntToString(next_unique_path_suffix_++)); |
| FileSystemURL url = test_helper_.CreateURL( |
| virtual_dir_path.Append(dir_name)); |
| |
| scoped_ptr<FileSystemOperationContext> context(NewContext()); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, |
| file_util()->CreateDirectory(context.get(), url, false, true)); |
| return url.path(); |
| } |
| |
| FilePath CreateUniqueDir() { |
| return CreateUniqueDirInDir(FilePath()); |
| } |
| |
| LocalFileSystemTestOriginHelper test_helper_; |
| |
| // Callbacks for recording test results. |
| FileSystemOperation::StatusCallback RecordStatusCallback() { |
| return base::Bind(&LocalFileSystemOperationTest::DidFinish, AsWeakPtr()); |
| } |
| |
| FileSystemOperation::ReadDirectoryCallback |
| RecordReadDirectoryCallback() { |
| return base::Bind(&LocalFileSystemOperationTest::DidReadDirectory, |
| AsWeakPtr()); |
| } |
| |
| FileSystemOperation::GetMetadataCallback RecordMetadataCallback() { |
| return base::Bind(&LocalFileSystemOperationTest::DidGetMetadata, |
| AsWeakPtr()); |
| } |
| |
| FileSystemOperation::SnapshotFileCallback RecordSnapshotFileCallback() { |
| return base::Bind(&LocalFileSystemOperationTest::DidCreateSnapshotFile, |
| AsWeakPtr()); |
| } |
| |
| void DidFinish(base::PlatformFileError status) { |
| status_ = status; |
| } |
| |
| void DidReadDirectory( |
| base::PlatformFileError status, |
| const std::vector<base::FileUtilProxy::Entry>& entries, |
| bool /* has_more */) { |
| entries_ = entries; |
| status_ = status; |
| } |
| |
| void DidGetMetadata(base::PlatformFileError status, |
| const base::PlatformFileInfo& info, |
| const FilePath& platform_path) { |
| info_ = info; |
| path_ = platform_path; |
| status_ = status; |
| } |
| |
| void DidCreateSnapshotFile( |
| base::PlatformFileError status, |
| const base::PlatformFileInfo& info, |
| const FilePath& platform_path, |
| const scoped_refptr<ShareableFileReference>& shareable_file_ref) { |
| info_ = info; |
| path_ = platform_path; |
| status_ = status; |
| shareable_file_ref_ = shareable_file_ref; |
| } |
| |
| static void DidGetUsageAndQuota(quota::QuotaStatusCode* status_out, |
| int64* usage_out, |
| int64* quota_out, |
| quota::QuotaStatusCode status, |
| int64 usage, |
| int64 quota) { |
| if (status_out) |
| *status_out = status; |
| |
| if (usage_out) |
| *usage_out = usage; |
| |
| if (quota_out) |
| *quota_out = quota; |
| } |
| |
| void GetUsageAndQuota(int64* usage, int64* quota) { |
| quota::QuotaStatusCode status = quota::kQuotaStatusUnknown; |
| quota_manager_->GetUsageAndQuota( |
| test_helper_.origin(), |
| test_helper_.storage_type(), |
| base::Bind(&LocalFileSystemOperationTest::DidGetUsageAndQuota, |
| &status, usage, quota)); |
| MessageLoop::current()->RunAllPending(); |
| ASSERT_EQ(quota::kQuotaStatusOk, status); |
| } |
| |
| void GenerateUniquePathInDir(const FilePath& dir, |
| FilePath* file_path, |
| int64* path_cost) { |
| int64 base_usage; |
| GetUsageAndQuota(&base_usage, NULL); |
| *file_path = CreateUniqueFileInDir(dir); |
| operation()->Remove(URLForPath(*file_path), |
| false /* recursive */, |
| base::Bind(&AssertFileErrorEq, |
| base::PLATFORM_FILE_OK)); |
| MessageLoop::current()->RunAllPending(); |
| |
| int64 total_usage; |
| GetUsageAndQuota(&total_usage, NULL); |
| *path_cost = total_usage - base_usage; |
| } |
| |
| void GrantQuotaForCurrentUsage() { |
| int64 usage; |
| GetUsageAndQuota(&usage, NULL); |
| quota_manager()->SetQuota(test_helper_.origin(), |
| test_helper_.storage_type(), |
| usage); |
| } |
| |
| void AddQuota(int64 quota_delta) { |
| int64 quota; |
| GetUsageAndQuota(NULL, "a); |
| quota_manager()->SetQuota(test_helper_.origin(), |
| test_helper_.storage_type(), |
| quota + quota_delta); |
| } |
| |
| // For post-operation status. |
| int status_; |
| base::PlatformFileInfo info_; |
| FilePath path_; |
| std::vector<base::FileUtilProxy::Entry> entries_; |
| scoped_refptr<ShareableFileReference> shareable_file_ref_; |
| |
| private: |
| MessageLoop message_loop_; |
| scoped_refptr<QuotaManager> quota_manager_; |
| scoped_refptr<QuotaManagerProxy> quota_manager_proxy_; |
| |
| MockFileChangeObserver change_observer_; |
| ChangeObserverList change_observers_; |
| |
| int next_unique_path_suffix_; |
| |
| DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperationTest); |
| }; |
| |
| void LocalFileSystemOperationTest::SetUp() { |
| FilePath base_dir = base_.path().AppendASCII("filesystem"); |
| quota_manager_ = new quota::MockQuotaManager( |
| false /* is_incognito */, base_dir, |
| base::MessageLoopProxy::current(), |
| base::MessageLoopProxy::current(), |
| NULL /* special storage policy */); |
| quota_manager_proxy_ = new quota::MockQuotaManagerProxy( |
| quota_manager(), |
| base::MessageLoopProxy::current()); |
| test_helper_.SetUp(base_dir, |
| false /* unlimited quota */, |
| quota_manager_proxy_.get(), |
| NULL); |
| } |
| |
| void LocalFileSystemOperationTest::TearDown() { |
| // Let the client go away before dropping a ref of the quota manager proxy. |
| quota_manager_proxy()->SimulateQuotaManagerDestroyed(); |
| quota_manager_ = NULL; |
| quota_manager_proxy_ = NULL; |
| test_helper_.TearDown(); |
| } |
| |
| LocalFileSystemOperation* LocalFileSystemOperationTest::operation() { |
| LocalFileSystemOperation* operation = test_helper_.NewOperation(); |
| operation->operation_context()->set_change_observers(change_observers()); |
| return operation; |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcDoesntExist) { |
| FileSystemURL src(URLForPath(FilePath(FILE_PATH_LITERAL("a")))); |
| FileSystemURL dest(URLForPath(FilePath(FILE_PATH_LITERAL("b")))); |
| change_observer()->ResetCount(); |
| operation()->Move(src, dest, RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveFailureContainsPath) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDirInDir(src_dir_path)); |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) { |
| // Src exists and is dir. Dest is a file. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, |
| TestMoveFailureSrcFileExistsDestNonEmptyDir) { |
| // Src exists and is a directory. Dest is a non-empty directory. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath child_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcFileExistsDestDir) { |
| // Src exists and is a file. Dest is a directory. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| operation()->Move(URLForPath(src_file_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath nonexisting_file = FilePath(FILE_PATH_LITERAL("NonexistingDir")). |
| Append(FILE_PATH_LITERAL("NonexistingFile")); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(nonexisting_file), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Move(URLForPath(src_file_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(dest_file_path)); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // Move is considered 'write' access (for both side), and won't be counted |
| // as read access. |
| EXPECT_EQ(0, quota_manager_proxy()->notify_storage_accessed_count()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcFileAndNew) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile"))); |
| |
| operation()->Move(URLForPath(src_file_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(dest_file_path)); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirAndOverwrite) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(DirectoryExists(src_dir_path)); |
| |
| EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // Make sure we've overwritten but not moved the source under the |dest_dir|. |
| EXPECT_TRUE(DirectoryExists(dest_dir_path)); |
| EXPECT_FALSE(DirectoryExists( |
| dest_dir_path.Append(VirtualPath::BaseName(src_dir_path)))); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirAndNew) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_parent_dir_path(CreateUniqueDir()); |
| FilePath dest_child_dir_path(dest_parent_dir_path. |
| Append(FILE_PATH_LITERAL("NewDirectory"))); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_child_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(DirectoryExists(src_dir_path)); |
| EXPECT_TRUE(DirectoryExists(dest_child_dir_path)); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestMoveSuccessSrcDirRecursive) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath child_dir_path(CreateUniqueDirInDir(src_dir_path)); |
| FilePath grandchild_file_path( |
| CreateUniqueFileInDir(child_dir_path)); |
| |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(DirectoryExists(dest_dir_path.Append( |
| VirtualPath::BaseName(child_dir_path)))); |
| EXPECT_TRUE(FileExists(dest_dir_path.Append( |
| VirtualPath::BaseName(child_dir_path)).Append( |
| VirtualPath::BaseName(grandchild_file_path)))); |
| |
| EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcDoesntExist) { |
| operation()->Copy(URLForPath(FilePath(FILE_PATH_LITERAL("a"))), |
| URLForPath(FilePath(FILE_PATH_LITERAL("b"))), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureContainsPath) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDirInDir(src_dir_path)); |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) { |
| // Src exists and is dir. Dest is a file. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, |
| TestCopyFailureSrcFileExistsDestNonEmptyDir) { |
| // Src exists and is a directory. Dest is a non-empty directory. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath child_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureSrcFileExistsDestDir) { |
| // Src exists and is a file. Dest is a directory. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| operation()->Copy(URLForPath(src_file_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath nonexisting_path = FilePath(FILE_PATH_LITERAL("DontExistDir")); |
| file_util::EnsureEndsWithSeparator(&nonexisting_path); |
| FilePath nonexisting_file_path(nonexisting_path.Append( |
| FILE_PATH_LITERAL("DontExistFile"))); |
| |
| operation()->Copy(URLForPath(src_dir_path), |
| URLForPath(nonexisting_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyFailureByQuota) { |
| base::PlatformFileInfo info; |
| |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| FilePath dest_file_path; |
| int64 dest_path_cost; |
| GenerateUniquePathInDir(dest_dir_path, &dest_file_path, &dest_path_cost); |
| |
| GrantQuotaForCurrentUsage(); |
| AddQuota(6); |
| |
| operation()->Truncate(URLForPath(src_file_path), 6, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| |
| AddQuota(6 + dest_path_cost - 1); |
| |
| EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(src_file_path), &info)); |
| EXPECT_EQ(6, info.size); |
| |
| operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); |
| EXPECT_FALSE(FileExists(dest_file_path)); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(CreateUniqueFileInDir(dest_dir_path)); |
| |
| operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(dest_file_path)); |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcFileAndNew) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath src_file_path(CreateUniqueFileInDir(src_dir_path)); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile"))); |
| |
| operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(dest_file_path)); |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| |
| // Make sure we've overwritten but not copied the source under the |dest_dir|. |
| EXPECT_TRUE(DirectoryExists(dest_dir_path)); |
| EXPECT_FALSE(DirectoryExists( |
| dest_dir_path.Append(VirtualPath::BaseName(src_dir_path)))); |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirAndNew) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath dest_parent_dir_path(CreateUniqueDir()); |
| FilePath dest_child_dir_path(dest_parent_dir_path. |
| Append(FILE_PATH_LITERAL("NewDirectory"))); |
| |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_child_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(DirectoryExists(dest_child_dir_path)); |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopySuccessSrcDirRecursive) { |
| FilePath src_dir_path(CreateUniqueDir()); |
| FilePath child_dir_path(CreateUniqueDirInDir(src_dir_path)); |
| FilePath grandchild_file_path( |
| CreateUniqueFileInDir(child_dir_path)); |
| |
| FilePath dest_dir_path(CreateUniqueDir()); |
| operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(DirectoryExists(dest_dir_path.Append( |
| VirtualPath::BaseName(child_dir_path)))); |
| EXPECT_TRUE(FileExists(dest_dir_path.Append( |
| VirtualPath::BaseName(child_dir_path)).Append( |
| VirtualPath::BaseName(grandchild_file_path)))); |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyInForeignFileSuccess) { |
| FilePath src_local_disk_file_path; |
| file_util::CreateTemporaryFile(&src_local_disk_file_path); |
| const char test_data[] = "foo"; |
| int data_size = ARRAYSIZE_UNSAFE(test_data); |
| file_util::WriteFile(src_local_disk_file_path, test_data, data_size); |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(dest_dir_path.Append( |
| src_local_disk_file_path.BaseName())); |
| FileSystemURL dest_file_url = URLForPath(dest_file_path); |
| int64 before_usage; |
| GetUsageAndQuota(&before_usage, NULL); |
| |
| // Check that the file copied and corresponding usage increased. |
| operation()->CopyInForeignFile(src_local_disk_file_path, |
| dest_file_url, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(1, change_observer()->create_file_count()); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(dest_file_path)); |
| int64 after_usage; |
| GetUsageAndQuota(&after_usage, NULL); |
| EXPECT_GT(after_usage, before_usage); |
| |
| // Compare contents of src and copied file. |
| char buffer[100]; |
| EXPECT_EQ(data_size, file_util::ReadFile(PlatformPath(dest_file_path), |
| buffer, data_size)); |
| for (int i = 0; i < data_size; ++i) |
| EXPECT_EQ(test_data[i], buffer[i]); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCopyInForeignFileFailureByQuota) { |
| FilePath src_local_disk_file_path; |
| file_util::CreateTemporaryFile(&src_local_disk_file_path); |
| const char test_data[] = "foo"; |
| file_util::WriteFile(src_local_disk_file_path, test_data, |
| ARRAYSIZE_UNSAFE(test_data)); |
| |
| FilePath dest_dir_path(CreateUniqueDir()); |
| FilePath dest_file_path(dest_dir_path.Append( |
| src_local_disk_file_path.BaseName())); |
| FileSystemURL dest_file_url = URLForPath(dest_file_path); |
| |
| // Set quota of 0 which should force copy to fail by quota. |
| quota_manager()->SetQuota(dest_file_url.origin(), |
| test_helper_.storage_type(), |
| static_cast<int64>(0)); |
| operation()->CopyInForeignFile(src_local_disk_file_path, |
| dest_file_url, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| |
| EXPECT_TRUE(!FileExists(dest_file_path)); |
| EXPECT_EQ(0, change_observer()->create_file_count()); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateFileFailure) { |
| // Already existing file and exclusive true. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->CreateFile(URLForPath(file_path), true, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessFileExists) { |
| // Already existing file and exclusive false. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->CreateFile(URLForPath(file_path), false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(file_path)); |
| |
| // The file was already there; did nothing. |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessExclusive) { |
| // File doesn't exist but exclusive is true. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist"))); |
| operation()->CreateFile(URLForPath(file_path), true, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(FileExists(file_path)); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) { |
| // Non existing file. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist"))); |
| operation()->CreateFile(URLForPath(file_path), false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, |
| TestCreateDirFailureDestParentDoesntExist) { |
| // Dest. parent path does not exist. |
| FilePath nonexisting_path(FilePath( |
| FILE_PATH_LITERAL("DirDoesntExist"))); |
| FilePath nonexisting_file_path(nonexisting_path.Append( |
| FILE_PATH_LITERAL("FileDoesntExist"))); |
| operation()->CreateDirectory(URLForPath(nonexisting_file_path), false, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateDirFailureDirExists) { |
| // Exclusive and dir existing at path. |
| FilePath src_dir_path(CreateUniqueDir()); |
| operation()->CreateDirectory(URLForPath(src_dir_path), true, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateDirFailureFileExists) { |
| // Exclusive true and file existing at path. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->CreateDirectory(URLForPath(file_path), true, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateDirSuccess) { |
| // Dir exists and exclusive is false. |
| FilePath dir_path(CreateUniqueDir()); |
| operation()->CreateDirectory(URLForPath(dir_path), false, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // Dir doesn't exist. |
| FilePath nonexisting_dir_path(FilePath( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| operation()->CreateDirectory(URLForPath(nonexisting_dir_path), false, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(DirectoryExists(nonexisting_dir_path)); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateDirSuccessExclusive) { |
| // Dir doesn't exist. |
| FilePath nonexisting_dir_path(FilePath( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| |
| operation()->CreateDirectory(URLForPath(nonexisting_dir_path), true, false, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(DirectoryExists(nonexisting_dir_path)); |
| EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestExistsAndMetadataFailure) { |
| FilePath nonexisting_dir_path(FilePath( |
| FILE_PATH_LITERAL("nonexistingdir"))); |
| operation()->GetMetadata(URLForPath(nonexisting_dir_path), |
| RecordMetadataCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| |
| operation()->FileExists(URLForPath(nonexisting_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| |
| file_util::EnsureEndsWithSeparator(&nonexisting_dir_path); |
| operation()->DirectoryExists(URLForPath(nonexisting_dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestExistsAndMetadataSuccess) { |
| FilePath dir_path(CreateUniqueDir()); |
| int read_access = 0; |
| |
| operation()->DirectoryExists(URLForPath(dir_path), |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| ++read_access; |
| |
| operation()->GetMetadata(URLForPath(dir_path), RecordMetadataCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(info().is_directory); |
| EXPECT_EQ(FilePath(), path()); |
| ++read_access; |
| |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->FileExists(URLForPath(file_path), RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| ++read_access; |
| |
| operation()->GetMetadata(URLForPath(file_path), RecordMetadataCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(info().is_directory); |
| EXPECT_EQ(PlatformPath(file_path), path()); |
| ++read_access; |
| |
| EXPECT_EQ(read_access, |
| quota_manager_proxy()->notify_storage_accessed_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestTypeMismatchErrors) { |
| FilePath dir_path(CreateUniqueDir()); |
| operation()->FileExists(URLForPath(dir_path), RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, status()); |
| |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| ASSERT_FALSE(file_path.empty()); |
| operation()->DirectoryExists(URLForPath(file_path), RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, status()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestReadDirFailure) { |
| // Path doesn't exist |
| FilePath nonexisting_dir_path(FilePath( |
| FILE_PATH_LITERAL("NonExistingDir"))); |
| file_util::EnsureEndsWithSeparator(&nonexisting_dir_path); |
| operation()->ReadDirectory(URLForPath(nonexisting_dir_path), |
| RecordReadDirectoryCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| |
| // File exists. |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->ReadDirectory(URLForPath(file_path), |
| RecordReadDirectoryCallback()); |
| MessageLoop::current()->RunAllPending(); |
| // TODO(kkanetkar) crbug.com/54309 to change the error code. |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestReadDirSuccess) { |
| // parent_dir |
| // | | |
| // child_dir child_file |
| // Verify reading parent_dir. |
| FilePath parent_dir_path(CreateUniqueDir()); |
| FilePath child_file_path(CreateUniqueFileInDir(parent_dir_path)); |
| FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); |
| ASSERT_FALSE(child_dir_path.empty()); |
| |
| operation()->ReadDirectory(URLForPath(parent_dir_path), |
| RecordReadDirectoryCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_EQ(2u, entries().size()); |
| |
| for (size_t i = 0; i < entries().size(); ++i) { |
| if (entries()[i].is_directory) { |
| EXPECT_EQ(VirtualPath::BaseName(child_dir_path).value(), |
| entries()[i].name); |
| } else { |
| EXPECT_EQ(VirtualPath::BaseName(child_file_path).value(), |
| entries()[i].name); |
| } |
| } |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestRemoveFailure) { |
| // Path doesn't exist. |
| FilePath nonexisting_path(FilePath( |
| FILE_PATH_LITERAL("NonExistingDir"))); |
| file_util::EnsureEndsWithSeparator(&nonexisting_path); |
| |
| operation()->Remove(URLForPath(nonexisting_path), false /* recursive */, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); |
| |
| // 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. |
| FilePath parent_dir_path(CreateUniqueDir()); |
| FilePath child_file_path(CreateUniqueFileInDir(parent_dir_path)); |
| FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); |
| ASSERT_FALSE(child_dir_path.empty()); |
| |
| operation()->Remove(URLForPath(parent_dir_path), false /* recursive */, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, |
| status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestRemoveSuccess) { |
| FilePath empty_dir_path(CreateUniqueDir()); |
| EXPECT_TRUE(DirectoryExists(empty_dir_path)); |
| |
| operation()->Remove(URLForPath(empty_dir_path), false /* recursive */, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(DirectoryExists(empty_dir_path)); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // Removing a non-empty directory with recursive flag == true should be ok. |
| // parent_dir |
| // | | |
| // child_dir child_file |
| // Verify deleting parent_dir. |
| FilePath parent_dir_path(CreateUniqueDir()); |
| FilePath child_file_path(CreateUniqueFileInDir(parent_dir_path)); |
| FilePath child_dir_path(CreateUniqueDirInDir(parent_dir_path)); |
| ASSERT_FALSE(child_dir_path.empty()); |
| |
| operation()->Remove(URLForPath(parent_dir_path), true /* recursive */, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(DirectoryExists(parent_dir_path)); |
| |
| // Remove is not a 'read' access. |
| EXPECT_EQ(0, quota_manager_proxy()->notify_storage_accessed_count()); |
| |
| EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestTruncate) { |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| |
| char test_data[] = "test data"; |
| int data_size = static_cast<int>(sizeof(test_data)); |
| EXPECT_EQ(data_size, |
| file_util::WriteFile(PlatformPath(file_path), |
| test_data, data_size)); |
| |
| // Check that its length is the size of the data written. |
| operation()->GetMetadata(URLForPath(file_path), RecordMetadataCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(info().is_directory); |
| EXPECT_EQ(data_size, info().size); |
| |
| // Extend the file by truncating it. |
| int length = 17; |
| operation()->Truncate(URLForPath(file_path), length, RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // 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(PlatformPath(file_path), &info)); |
| EXPECT_EQ(length, info.size); |
| char data[100]; |
| EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), 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(URLForPath(file_path), length, RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| |
| EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // Check that its length is now 3 and that it contains only bits of test data. |
| EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); |
| EXPECT_EQ(length, info.size); |
| EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length)); |
| for (int i = 0; i < length; ++i) |
| EXPECT_EQ(test_data[i], data[i]); |
| |
| // Truncate is not a 'read' access. (Here expected access count is 1 |
| // since we made 1 read access for GetMetadata.) |
| EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestTruncateFailureByQuota) { |
| base::PlatformFileInfo info; |
| |
| FilePath dir_path(CreateUniqueDir()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| |
| GrantQuotaForCurrentUsage(); |
| AddQuota(10); |
| |
| operation()->Truncate(URLForPath(file_path), 10, RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); |
| EXPECT_EQ(10, info.size); |
| |
| operation()->Truncate(URLForPath(file_path), 11, RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); |
| EXPECT_EQ(10, info.size); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestTouchFile) { |
| FilePath file_path(CreateUniqueFileInDir(FilePath())); |
| FilePath platform_path = PlatformPath(file_path); |
| |
| base::PlatformFileInfo info; |
| |
| EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info)); |
| EXPECT_FALSE(info.is_directory); |
| EXPECT_EQ(0, info.size); |
| const base::Time last_modified = info.last_modified; |
| const base::Time last_accessed = info.last_accessed; |
| |
| const base::Time new_modified_time = base::Time::UnixEpoch(); |
| const base::Time new_accessed_time = new_modified_time + |
| base::TimeDelta::FromHours(77); |
| ASSERT_NE(last_modified, new_modified_time); |
| ASSERT_NE(last_accessed, new_accessed_time); |
| |
| operation()->TouchFile( |
| URLForPath(file_path), new_accessed_time, new_modified_time, |
| RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info)); |
| // We compare as time_t here to lower our resolution, to avoid false |
| // negatives caused by conversion to the local filesystem's native |
| // representation and back. |
| EXPECT_EQ(new_modified_time.ToTimeT(), info.last_modified.ToTimeT()); |
| EXPECT_EQ(new_accessed_time.ToTimeT(), info.last_accessed.ToTimeT()); |
| } |
| |
| TEST_F(LocalFileSystemOperationTest, TestCreateSnapshotFile) { |
| FilePath dir_path(CreateUniqueDir()); |
| |
| // Create a file for the testing. |
| operation()->DirectoryExists(URLForPath(dir_path), |
| RecordStatusCallback()); |
| FilePath file_path(CreateUniqueFileInDir(dir_path)); |
| operation()->FileExists(URLForPath(file_path), RecordStatusCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| |
| // See if we can get a 'snapshot' file info for the file. |
| // Since LocalFileSystemOperation assumes the file exists in the local |
| // directory it should just returns the same metadata and platform_path |
| // as the file itself. |
| operation()->CreateSnapshotFile(URLForPath(file_path), |
| RecordSnapshotFileCallback()); |
| MessageLoop::current()->RunAllPending(); |
| EXPECT_EQ(base::PLATFORM_FILE_OK, status()); |
| EXPECT_FALSE(info().is_directory); |
| EXPECT_EQ(PlatformPath(file_path), path()); |
| EXPECT_TRUE(change_observer()->HasNoChange()); |
| |
| // The FileSystemOpration implementation does not create a |
| // shareable file reference. |
| EXPECT_EQ(NULL, shareable_file_ref()); |
| } |
| |
| } // namespace fileapi |