summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi/local_file_system_operation_unittest.cc
diff options
context:
space:
mode:
authornhiroki@google.com <nhiroki@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-24 20:05:33 +0000
committernhiroki@google.com <nhiroki@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-24 20:05:33 +0000
commit02a6054b5aa80fc8c346fa70fea336bb63edc4be (patch)
tree4a06cc30ffad1de8b758f0f34c5b36993e560a0b /webkit/fileapi/local_file_system_operation_unittest.cc
parentcd31afc3b22fe58a2e03b269032ed85479d056fd (diff)
downloadchromium_src-02a6054b5aa80fc8c346fa70fea336bb63edc4be.zip
chromium_src-02a6054b5aa80fc8c346fa70fea336bb63edc4be.tar.gz
chromium_src-02a6054b5aa80fc8c346fa70fea336bb63edc4be.tar.bz2
Renamed FileSystemOperation to LocalFileSystemOperation.
BUG=138020 TEST=content_unittests Review URL: https://chromiumcodereview.appspot.com/10790096 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148178 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi/local_file_system_operation_unittest.cc')
-rw-r--r--webkit/fileapi/local_file_system_operation_unittest.cc1155
1 files changed, 1155 insertions, 0 deletions
diff --git a/webkit/fileapi/local_file_system_operation_unittest.cc b/webkit/fileapi/local_file_system_operation_unittest.cc
new file mode 100644
index 0000000..e801590
--- /dev/null
+++ b/webkit/fileapi/local_file_system_operation_unittest.cc
@@ -0,0 +1,1155 @@
+// 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/local_file_system_test_helper.h"
+#include "webkit/quota/quota_manager.h"
+
+using quota::QuotaClient;
+using quota::QuotaManager;
+using quota::QuotaManagerProxy;
+using quota::StorageType;
+using webkit_blob::ShareableFileReference;
+
+namespace fileapi {
+
+namespace {
+
+const int kFileOperationStatusNotSet = 1;
+
+void AssertFileErrorEq(base::PlatformFileError expected,
+ base::PlatformFileError actual) {
+ ASSERT_EQ(expected, actual);
+}
+
+class MockQuotaManager : public QuotaManager {
+ public:
+ MockQuotaManager(const FilePath& base_dir,
+ const GURL& origin,
+ StorageType type)
+ : QuotaManager(false /* is_incognito */, base_dir,
+ base::MessageLoopProxy::current(),
+ base::MessageLoopProxy::current(),
+ NULL),
+ origin_(origin),
+ type_(type),
+ usage_(0),
+ quota_(kint64max),
+ accessed_(0) {}
+
+ virtual void GetUsageAndQuota(
+ const GURL& origin, quota::StorageType type,
+ const GetUsageAndQuotaCallback& callback) OVERRIDE {
+ EXPECT_EQ(origin_, origin);
+ EXPECT_EQ(type_, type);
+ callback.Run(quota::kQuotaStatusOk, usage_, quota_);
+ }
+
+ protected:
+ virtual ~MockQuotaManager() {}
+
+ private:
+ friend class MockQuotaManagerProxy;
+
+ void SetQuota(const GURL& origin, StorageType type, int64 quota) {
+ EXPECT_EQ(origin_, origin);
+ EXPECT_EQ(type_, type);
+ quota_ = quota;
+ }
+
+ void RecordStorageAccessed(const GURL& origin, StorageType type) {
+ EXPECT_EQ(origin_, origin);
+ EXPECT_EQ(type_, type);
+ ++accessed_;
+ }
+
+ void UpdateUsage(const GURL& origin, StorageType type, int64 delta) {
+ EXPECT_EQ(origin_, origin);
+ EXPECT_EQ(type_, type);
+ usage_ += delta;
+ }
+
+ const GURL& origin_;
+ const StorageType type_;
+ int64 usage_;
+ int64 quota_;
+ int accessed_;
+};
+
+class MockQuotaManagerProxy : public QuotaManagerProxy {
+ public:
+ explicit MockQuotaManagerProxy(QuotaManager* quota_manager)
+ : QuotaManagerProxy(quota_manager,
+ base::MessageLoopProxy::current()),
+ registered_client_(NULL) {
+ }
+
+ virtual void RegisterClient(QuotaClient* client) OVERRIDE {
+ EXPECT_FALSE(registered_client_);
+ registered_client_ = client;
+ }
+
+ void SimulateQuotaManagerDestroyed() {
+ if (registered_client_) {
+ // We cannot call this in the destructor as the client (indirectly)
+ // holds a refptr of the proxy.
+ registered_client_->OnQuotaManagerDestroyed();
+ registered_client_ = NULL;
+ }
+ }
+
+ // We don't mock them.
+ virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {}
+ virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {}
+
+ virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type) OVERRIDE {
+ mock_manager()->RecordStorageAccessed(origin, type);
+ }
+
+ virtual void NotifyStorageModified(QuotaClient::ID client_id,
+ const GURL& origin,
+ StorageType type,
+ int64 delta) OVERRIDE {
+ mock_manager()->UpdateUsage(origin, type, delta);
+ }
+
+ int storage_accessed_count() const {
+ return mock_manager()->accessed_;
+ }
+
+ void SetQuota(const GURL& origin, StorageType type, int64 quota) {
+ mock_manager()->SetQuota(origin, type, quota);
+ }
+
+ protected:
+ virtual ~MockQuotaManagerProxy() {
+ EXPECT_FALSE(registered_client_);
+ }
+
+ private:
+ MockQuotaManager* mock_manager() const {
+ return static_cast<MockQuotaManager*>(quota_manager());
+ }
+
+ QuotaClient* registered_client_;
+};
+
+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());
+ }
+
+ 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_;
+
+ MockQuotaManagerProxy* quota_manager_proxy() {
+ return static_cast<MockQuotaManagerProxy*>(quota_manager_proxy_.get());
+ }
+
+ FileSystemFileUtil* file_util() {
+ return test_helper_.file_util();
+ }
+
+ 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 (!file_util()->PathExists(context.get(), path))
+ return false;
+
+ context.reset(NewContext());
+ return !file_util()->DirectoryExists(context.get(), path);
+ }
+
+ bool DirectoryExists(const FilePath& virtual_path) {
+ FileSystemURL url = test_helper_.CreateURL(virtual_path);
+ scoped_ptr<FileSystemOperationContext> context(NewContext());
+ return file_util()->DirectoryExists(context.get(), 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.
+ FileSystemOperationInterface::StatusCallback RecordStatusCallback() {
+ return base::Bind(&LocalFileSystemOperationTest::DidFinish, AsWeakPtr());
+ }
+
+ FileSystemOperationInterface::ReadDirectoryCallback
+ RecordReadDirectoryCallback() {
+ return base::Bind(&LocalFileSystemOperationTest::DidReadDirectory,
+ AsWeakPtr());
+ }
+
+ FileSystemOperationInterface::GetMetadataCallback RecordMetadataCallback() {
+ return base::Bind(&LocalFileSystemOperationTest::DidGetMetadata,
+ AsWeakPtr());
+ }
+
+ FileSystemOperationInterface::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_proxy()->SetQuota(test_helper_.origin(),
+ test_helper_.storage_type(),
+ usage);
+ }
+
+ void AddQuota(int64 quota_delta) {
+ int64 quota;
+ GetUsageAndQuota(NULL, &quota);
+ quota_manager_proxy()->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_;
+
+ int next_unique_path_suffix_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperationTest);
+};
+
+void LocalFileSystemOperationTest::SetUp() {
+ FilePath base_dir = base_.path().AppendASCII("filesystem");
+ quota_manager_ = new MockQuotaManager(
+ base_dir, test_helper_.origin(), test_helper_.storage_type());
+ quota_manager_proxy_ = new MockQuotaManagerProxy(quota_manager_.get());
+ 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() {
+ return test_helper_.NewOperation();
+}
+
+TEST_F(LocalFileSystemOperationTest, TestMoveFailureSrcDoesntExist) {
+ FileSystemURL src(URLForPath(FilePath(FILE_PATH_LITERAL("a"))));
+ FileSystemURL dest(URLForPath(FilePath(FILE_PATH_LITERAL("b"))));
+ operation()->Move(src, dest, RecordStatusCallback());
+ MessageLoop::current()->RunAllPending();
+ EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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));
+
+ // Move is considered 'write' access (for both side), and won't be counted
+ // as read access.
+ EXPECT_EQ(0, quota_manager_proxy()->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));
+}
+
+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));
+
+ // 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));
+}
+
+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))));
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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()->storage_accessed_count());
+}
+
+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()->storage_accessed_count());
+}
+
+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()->storage_accessed_count());
+}
+
+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()->storage_accessed_count());
+}
+
+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()->storage_accessed_count());
+}
+
+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());
+}
+
+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));
+}
+
+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));
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+}
+
+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());
+
+ // 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));
+}
+
+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));
+}
+
+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());
+}
+
+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()->storage_accessed_count());
+}
+
+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());
+}
+
+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()->storage_accessed_count());
+}
+
+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());
+}
+
+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));
+
+ // 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()->storage_accessed_count());
+}
+
+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());
+
+ // 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());
+
+ // 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()->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_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(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(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());
+
+ // The FileSystemOpration implementation does not create a
+ // shareable file reference.
+ EXPECT_EQ(NULL, shareable_file_ref());
+}
+
+} // namespace fileapi