| Index: content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
 | 
| diff --git a/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
 | 
| deleted file mode 100644
 | 
| index 77e708957089b2a79ce558f489102c963a76d9e4..0000000000000000000000000000000000000000
 | 
| --- a/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
 | 
| +++ /dev/null
 | 
| @@ -1,877 +0,0 @@
 | 
| -// Copyright 2013 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include <stddef.h>
 | 
| -#include <stdint.h>
 | 
| -#include <map>
 | 
| -#include <queue>
 | 
| -#include <utility>
 | 
| -
 | 
| -#include "base/bind.h"
 | 
| -#include "base/files/file_util.h"
 | 
| -#include "base/files/scoped_temp_dir.h"
 | 
| -#include "base/location.h"
 | 
| -#include "base/macros.h"
 | 
| -#include "base/run_loop.h"
 | 
| -#include "base/single_thread_task_runner.h"
 | 
| -#include "base/stl_util.h"
 | 
| -#include "base/threading/thread_task_runner_handle.h"
 | 
| -#include "content/browser/quota/mock_quota_manager.h"
 | 
| -#include "content/browser/quota/mock_quota_manager_proxy.h"
 | 
| -#include "content/public/test/async_file_test_helper.h"
 | 
| -#include "content/public/test/test_file_system_backend.h"
 | 
| -#include "content/public/test/test_file_system_context.h"
 | 
| -#include "content/test/fileapi_test_file_set.h"
 | 
| -#include "storage/browser/fileapi/copy_or_move_file_validator.h"
 | 
| -#include "storage/browser/fileapi/copy_or_move_operation_delegate.h"
 | 
| -#include "storage/browser/fileapi/file_stream_reader.h"
 | 
| -#include "storage/browser/fileapi/file_stream_writer.h"
 | 
| -#include "storage/browser/fileapi/file_system_backend.h"
 | 
| -#include "storage/browser/fileapi/file_system_context.h"
 | 
| -#include "storage/browser/fileapi/file_system_operation.h"
 | 
| -#include "storage/browser/fileapi/file_system_url.h"
 | 
| -#include "storage/browser/quota/quota_manager.h"
 | 
| -#include "storage/common/fileapi/file_system_mount_option.h"
 | 
| -#include "storage/common/fileapi/file_system_util.h"
 | 
| -#include "testing/gtest/include/gtest/gtest.h"
 | 
| -
 | 
| -using content::AsyncFileTestHelper;
 | 
| -using storage::CopyOrMoveOperationDelegate;
 | 
| -using storage::FileStreamWriter;
 | 
| -using storage::FileSystemOperation;
 | 
| -using storage::FileSystemURL;
 | 
| -
 | 
| -namespace content {
 | 
| -
 | 
| -typedef storage::FileSystemOperation::FileEntryList FileEntryList;
 | 
| -
 | 
| -namespace {
 | 
| -
 | 
| -void ExpectOk(const GURL& origin_url,
 | 
| -              const std::string& name,
 | 
| -              base::File::Error error) {
 | 
| -  ASSERT_EQ(base::File::FILE_OK, error);
 | 
| -}
 | 
| -
 | 
| -class TestValidatorFactory : public storage::CopyOrMoveFileValidatorFactory {
 | 
| - public:
 | 
| -  // A factory that creates validators that accept everything or nothing.
 | 
| -  TestValidatorFactory() {}
 | 
| -  ~TestValidatorFactory() override {}
 | 
| -
 | 
| -  storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
 | 
| -      const FileSystemURL& /*src_url*/,
 | 
| -      const base::FilePath& /*platform_path*/) override {
 | 
| -    // Move arg management to TestValidator?
 | 
| -    return new TestValidator(true, true, std::string("2"));
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  class TestValidator : public storage::CopyOrMoveFileValidator {
 | 
| -   public:
 | 
| -    explicit TestValidator(bool pre_copy_valid,
 | 
| -                           bool post_copy_valid,
 | 
| -                           const std::string& reject_string)
 | 
| -        : result_(pre_copy_valid ? base::File::FILE_OK :
 | 
| -                                   base::File::FILE_ERROR_SECURITY),
 | 
| -          write_result_(post_copy_valid ? base::File::FILE_OK :
 | 
| -                                          base::File::FILE_ERROR_SECURITY),
 | 
| -          reject_string_(reject_string) {
 | 
| -    }
 | 
| -    ~TestValidator() override {}
 | 
| -
 | 
| -    void StartPreWriteValidation(
 | 
| -        const ResultCallback& result_callback) override {
 | 
| -      // Post the result since a real validator must do work asynchronously.
 | 
| -      base::ThreadTaskRunnerHandle::Get()->PostTask(
 | 
| -          FROM_HERE, base::Bind(result_callback, result_));
 | 
| -    }
 | 
| -
 | 
| -    void StartPostWriteValidation(
 | 
| -        const base::FilePath& dest_platform_path,
 | 
| -        const ResultCallback& result_callback) override {
 | 
| -      base::File::Error result = write_result_;
 | 
| -      std::string unsafe = dest_platform_path.BaseName().AsUTF8Unsafe();
 | 
| -      if (unsafe.find(reject_string_) != std::string::npos) {
 | 
| -        result = base::File::FILE_ERROR_SECURITY;
 | 
| -      }
 | 
| -      // Post the result since a real validator must do work asynchronously.
 | 
| -      base::ThreadTaskRunnerHandle::Get()->PostTask(
 | 
| -          FROM_HERE, base::Bind(result_callback, result));
 | 
| -    }
 | 
| -
 | 
| -   private:
 | 
| -    base::File::Error result_;
 | 
| -    base::File::Error write_result_;
 | 
| -    std::string reject_string_;
 | 
| -
 | 
| -    DISALLOW_COPY_AND_ASSIGN(TestValidator);
 | 
| -  };
 | 
| -};
 | 
| -
 | 
| -// Records CopyProgressCallback invocations.
 | 
| -struct ProgressRecord {
 | 
| -  storage::FileSystemOperation::CopyProgressType type;
 | 
| -  FileSystemURL source_url;
 | 
| -  FileSystemURL dest_url;
 | 
| -  int64_t size;
 | 
| -};
 | 
| -
 | 
| -void RecordProgressCallback(std::vector<ProgressRecord>* records,
 | 
| -                            storage::FileSystemOperation::CopyProgressType type,
 | 
| -                            const FileSystemURL& source_url,
 | 
| -                            const FileSystemURL& dest_url,
 | 
| -                            int64_t size) {
 | 
| -  ProgressRecord record;
 | 
| -  record.type = type;
 | 
| -  record.source_url = source_url;
 | 
| -  record.dest_url = dest_url;
 | 
| -  record.size = size;
 | 
| -  records->push_back(record);
 | 
| -}
 | 
| -
 | 
| -void RecordFileProgressCallback(std::vector<int64_t>* records,
 | 
| -                                int64_t progress) {
 | 
| -  records->push_back(progress);
 | 
| -}
 | 
| -
 | 
| -void AssignAndQuit(base::RunLoop* run_loop,
 | 
| -                   base::File::Error* result_out,
 | 
| -                   base::File::Error result) {
 | 
| -  *result_out = result;
 | 
| -  run_loop->Quit();
 | 
| -}
 | 
| -
 | 
| -class ScopedThreadStopper {
 | 
| - public:
 | 
| -  ScopedThreadStopper(base::Thread* thread) : thread_(thread) {
 | 
| -  }
 | 
| -
 | 
| -  ~ScopedThreadStopper() {
 | 
| -    if (thread_) {
 | 
| -      // Give another chance for deleted streams to perform Close.
 | 
| -      base::RunLoop run_loop;
 | 
| -      thread_->task_runner()->PostTaskAndReply(
 | 
| -          FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure());
 | 
| -      run_loop.Run();
 | 
| -      thread_->Stop();
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  bool is_valid() const { return thread_; }
 | 
| -
 | 
| - private:
 | 
| -  base::Thread* thread_;
 | 
| -  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStopper);
 | 
| -};
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -class CopyOrMoveOperationTestHelper {
 | 
| - public:
 | 
| -  CopyOrMoveOperationTestHelper(const GURL& origin,
 | 
| -                                storage::FileSystemType src_type,
 | 
| -                                storage::FileSystemType dest_type)
 | 
| -      : origin_(origin), src_type_(src_type), dest_type_(dest_type) {}
 | 
| -
 | 
| -  ~CopyOrMoveOperationTestHelper() {
 | 
| -    file_system_context_ = NULL;
 | 
| -    quota_manager_proxy_->SimulateQuotaManagerDestroyed();
 | 
| -    quota_manager_ = NULL;
 | 
| -    quota_manager_proxy_ = NULL;
 | 
| -    base::RunLoop().RunUntilIdle();
 | 
| -  }
 | 
| -
 | 
| -  void SetUp() {
 | 
| -    SetUp(true, true);
 | 
| -  }
 | 
| -
 | 
| -  void SetUpNoValidator() {
 | 
| -    SetUp(true, false);
 | 
| -  }
 | 
| -
 | 
| -  void SetUp(bool require_copy_or_move_validator,
 | 
| -             bool init_copy_or_move_validator) {
 | 
| -    ASSERT_TRUE(base_.CreateUniqueTempDir());
 | 
| -    base::FilePath base_dir = base_.GetPath();
 | 
| -    quota_manager_ =
 | 
| -        new MockQuotaManager(false /* is_incognito */, base_dir,
 | 
| -                             base::ThreadTaskRunnerHandle::Get().get(),
 | 
| -                             base::ThreadTaskRunnerHandle::Get().get(),
 | 
| -                             NULL /* special storage policy */);
 | 
| -    quota_manager_proxy_ = new MockQuotaManagerProxy(
 | 
| -        quota_manager_.get(), base::ThreadTaskRunnerHandle::Get().get());
 | 
| -    file_system_context_ =
 | 
| -        CreateFileSystemContextForTesting(quota_manager_proxy_.get(), base_dir);
 | 
| -
 | 
| -    // Prepare the origin's root directory.
 | 
| -    storage::FileSystemBackend* backend =
 | 
| -        file_system_context_->GetFileSystemBackend(src_type_);
 | 
| -    backend->ResolveURL(
 | 
| -        FileSystemURL::CreateForTest(origin_, src_type_, base::FilePath()),
 | 
| -        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
 | 
| -        base::Bind(&ExpectOk));
 | 
| -    backend = file_system_context_->GetFileSystemBackend(dest_type_);
 | 
| -    if (dest_type_ == storage::kFileSystemTypeTest) {
 | 
| -      TestFileSystemBackend* test_backend =
 | 
| -          static_cast<TestFileSystemBackend*>(backend);
 | 
| -      std::unique_ptr<storage::CopyOrMoveFileValidatorFactory> factory(
 | 
| -          new TestValidatorFactory);
 | 
| -      test_backend->set_require_copy_or_move_validator(
 | 
| -          require_copy_or_move_validator);
 | 
| -      if (init_copy_or_move_validator)
 | 
| -        test_backend->InitializeCopyOrMoveFileValidatorFactory(
 | 
| -            std::move(factory));
 | 
| -    }
 | 
| -    backend->ResolveURL(
 | 
| -        FileSystemURL::CreateForTest(origin_, dest_type_, base::FilePath()),
 | 
| -        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
 | 
| -        base::Bind(&ExpectOk));
 | 
| -    base::RunLoop().RunUntilIdle();
 | 
| -
 | 
| -    // Grant relatively big quota initially.
 | 
| -    quota_manager_->SetQuota(
 | 
| -        origin_,
 | 
| -        storage::FileSystemTypeToQuotaStorageType(src_type_),
 | 
| -        1024 * 1024);
 | 
| -    quota_manager_->SetQuota(
 | 
| -        origin_,
 | 
| -        storage::FileSystemTypeToQuotaStorageType(dest_type_),
 | 
| -        1024 * 1024);
 | 
| -  }
 | 
| -
 | 
| -  int64_t GetSourceUsage() {
 | 
| -    int64_t usage = 0;
 | 
| -    GetUsageAndQuota(src_type_, &usage, NULL);
 | 
| -    return usage;
 | 
| -  }
 | 
| -
 | 
| -  int64_t GetDestUsage() {
 | 
| -    int64_t usage = 0;
 | 
| -    GetUsageAndQuota(dest_type_, &usage, NULL);
 | 
| -    return usage;
 | 
| -  }
 | 
| -
 | 
| -  FileSystemURL SourceURL(const std::string& path) {
 | 
| -    return file_system_context_->CreateCrackedFileSystemURL(
 | 
| -        origin_, src_type_, base::FilePath::FromUTF8Unsafe(path));
 | 
| -  }
 | 
| -
 | 
| -  FileSystemURL DestURL(const std::string& path) {
 | 
| -    return file_system_context_->CreateCrackedFileSystemURL(
 | 
| -        origin_, dest_type_, base::FilePath::FromUTF8Unsafe(path));
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error Copy(const FileSystemURL& src,
 | 
| -                         const FileSystemURL& dest) {
 | 
| -    return AsyncFileTestHelper::Copy(file_system_context_.get(), src, dest);
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error CopyWithProgress(
 | 
| -      const FileSystemURL& src,
 | 
| -      const FileSystemURL& dest,
 | 
| -      const AsyncFileTestHelper::CopyProgressCallback& progress_callback) {
 | 
| -    return AsyncFileTestHelper::CopyWithProgress(
 | 
| -        file_system_context_.get(), src, dest, progress_callback);
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error Move(const FileSystemURL& src,
 | 
| -                         const FileSystemURL& dest) {
 | 
| -    return AsyncFileTestHelper::Move(file_system_context_.get(), src, dest);
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error SetUpTestCaseFiles(
 | 
| -      const FileSystemURL& root,
 | 
| -      const FileSystemTestCaseRecord* const test_cases,
 | 
| -      size_t test_case_size) {
 | 
| -    base::File::Error result = base::File::FILE_ERROR_FAILED;
 | 
| -    for (size_t i = 0; i < test_case_size; ++i) {
 | 
| -      const FileSystemTestCaseRecord& test_case = test_cases[i];
 | 
| -      FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
 | 
| -          root.origin(),
 | 
| -          root.mount_type(),
 | 
| -          root.virtual_path().Append(test_case.path));
 | 
| -      if (test_case.is_directory)
 | 
| -        result = CreateDirectory(url);
 | 
| -      else
 | 
| -        result = CreateFile(url, test_case.data_file_size);
 | 
| -      EXPECT_EQ(base::File::FILE_OK, result) << url.DebugString();
 | 
| -      if (result != base::File::FILE_OK)
 | 
| -        return result;
 | 
| -    }
 | 
| -    return result;
 | 
| -  }
 | 
| -
 | 
| -  void VerifyTestCaseFiles(
 | 
| -      const FileSystemURL& root,
 | 
| -      const FileSystemTestCaseRecord* const test_cases,
 | 
| -      size_t test_case_size) {
 | 
| -    std::map<base::FilePath, const FileSystemTestCaseRecord*> test_case_map;
 | 
| -    for (size_t i = 0; i < test_case_size; ++i) {
 | 
| -      test_case_map[
 | 
| -          base::FilePath(test_cases[i].path).NormalizePathSeparators()] =
 | 
| -              &test_cases[i];
 | 
| -    }
 | 
| -
 | 
| -    std::queue<FileSystemURL> directories;
 | 
| -    FileEntryList entries;
 | 
| -    directories.push(root);
 | 
| -    while (!directories.empty()) {
 | 
| -      FileSystemURL dir = directories.front();
 | 
| -      directories.pop();
 | 
| -      ASSERT_EQ(base::File::FILE_OK, ReadDirectory(dir, &entries));
 | 
| -      for (size_t i = 0; i < entries.size(); ++i) {
 | 
| -        FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
 | 
| -            dir.origin(),
 | 
| -            dir.mount_type(),
 | 
| -            dir.virtual_path().Append(entries[i].name));
 | 
| -        base::FilePath relative;
 | 
| -        root.virtual_path().AppendRelativePath(url.virtual_path(), &relative);
 | 
| -        relative = relative.NormalizePathSeparators();
 | 
| -        ASSERT_TRUE(base::ContainsKey(test_case_map, relative));
 | 
| -        if (entries[i].is_directory) {
 | 
| -          EXPECT_TRUE(test_case_map[relative]->is_directory);
 | 
| -          directories.push(url);
 | 
| -        } else {
 | 
| -          EXPECT_FALSE(test_case_map[relative]->is_directory);
 | 
| -          EXPECT_TRUE(FileExists(url, test_case_map[relative]->data_file_size));
 | 
| -        }
 | 
| -        test_case_map.erase(relative);
 | 
| -      }
 | 
| -    }
 | 
| -    EXPECT_TRUE(test_case_map.empty());
 | 
| -    std::map<base::FilePath,
 | 
| -        const FileSystemTestCaseRecord*>::const_iterator it;
 | 
| -    for (it = test_case_map.begin(); it != test_case_map.end(); ++it) {
 | 
| -      LOG(ERROR) << "Extra entry: " << it->first.LossyDisplayName();
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error ReadDirectory(const FileSystemURL& url,
 | 
| -                                  FileEntryList* entries) {
 | 
| -    return AsyncFileTestHelper::ReadDirectory(
 | 
| -        file_system_context_.get(), url, entries);
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error CreateDirectory(const FileSystemURL& url) {
 | 
| -    return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
 | 
| -                                                url);
 | 
| -  }
 | 
| -
 | 
| -  base::File::Error CreateFile(const FileSystemURL& url, size_t size) {
 | 
| -    base::File::Error result =
 | 
| -        AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
 | 
| -    if (result != base::File::FILE_OK)
 | 
| -      return result;
 | 
| -    return AsyncFileTestHelper::TruncateFile(
 | 
| -        file_system_context_.get(), url, size);
 | 
| -  }
 | 
| -
 | 
| -  bool FileExists(const FileSystemURL& url, int64_t expected_size) {
 | 
| -    return AsyncFileTestHelper::FileExists(
 | 
| -        file_system_context_.get(), url, expected_size);
 | 
| -  }
 | 
| -
 | 
| -  bool DirectoryExists(const FileSystemURL& url) {
 | 
| -    return AsyncFileTestHelper::DirectoryExists(file_system_context_.get(),
 | 
| -                                                url);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  void GetUsageAndQuota(storage::FileSystemType type,
 | 
| -                        int64_t* usage,
 | 
| -                        int64_t* quota) {
 | 
| -    storage::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota(
 | 
| -        quota_manager_.get(), origin_, type, usage, quota);
 | 
| -    ASSERT_EQ(storage::kQuotaStatusOk, status);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  base::ScopedTempDir base_;
 | 
| -
 | 
| -  const GURL origin_;
 | 
| -  const storage::FileSystemType src_type_;
 | 
| -  const storage::FileSystemType dest_type_;
 | 
| -
 | 
| -  base::MessageLoopForIO message_loop_;
 | 
| -  scoped_refptr<storage::FileSystemContext> file_system_context_;
 | 
| -  scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
 | 
| -  scoped_refptr<MockQuotaManager> quota_manager_;
 | 
| -
 | 
| -  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationTestHelper);
 | 
| -};
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFile) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source file.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Copy it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_TRUE(helper.FileExists(src, 10));
 | 
| -  ASSERT_TRUE(helper.FileExists(dest, 10));
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFile) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source file.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Move it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_FALSE(helper.FileExists(src, AsyncFileTestHelper::kDontCheckSize));
 | 
| -  ASSERT_TRUE(helper.FileExists(dest, 10));
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleDirectory) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Copy it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(src));
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(dest));
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectory) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Move it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_FALSE(helper.DirectoryExists(src));
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(dest));
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.SetUpTestCaseFiles(src,
 | 
| -                                      kRegularFileSystemTestCases,
 | 
| -                                      kRegularFileSystemTestCaseSize));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Copy it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.CopyWithProgress(
 | 
| -                src, dest,
 | 
| -                AsyncFileTestHelper::CopyProgressCallback()));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(src));
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(dest));
 | 
| -
 | 
| -  helper.VerifyTestCaseFiles(dest,
 | 
| -                             kRegularFileSystemTestCases,
 | 
| -                             kRegularFileSystemTestCaseSize);
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, MoveDirectory) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -  int64_t src_initial_usage = helper.GetSourceUsage();
 | 
| -  int64_t dest_initial_usage = helper.GetDestUsage();
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.SetUpTestCaseFiles(src,
 | 
| -                                      kRegularFileSystemTestCases,
 | 
| -                                      kRegularFileSystemTestCaseSize));
 | 
| -  int64_t src_increase = helper.GetSourceUsage() - src_initial_usage;
 | 
| -
 | 
| -  // Move it.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_FALSE(helper.DirectoryExists(src));
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(dest));
 | 
| -
 | 
| -  helper.VerifyTestCaseFiles(dest,
 | 
| -                             kRegularFileSystemTestCases,
 | 
| -                             kRegularFileSystemTestCaseSize);
 | 
| -
 | 
| -  int64_t src_new_usage = helper.GetSourceUsage();
 | 
| -  ASSERT_EQ(src_initial_usage, src_new_usage);
 | 
| -
 | 
| -  int64_t dest_increase = helper.GetDestUsage() - dest_initial_usage;
 | 
| -  ASSERT_EQ(src_increase, dest_increase);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest,
 | 
| -     MoveDirectoryFailPostWriteValidation) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypeTest);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.SetUpTestCaseFiles(src,
 | 
| -                                      kRegularFileSystemTestCases,
 | 
| -                                      kRegularFileSystemTestCaseSize));
 | 
| -
 | 
| -  // Move it.
 | 
| -  helper.Move(src, dest);
 | 
| -
 | 
| -  // Verify.
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(src));
 | 
| -  ASSERT_TRUE(helper.DirectoryExists(dest));
 | 
| -
 | 
| -  // In the move operation, [file 0, file 2, file 3] are processed as LIFO.
 | 
| -  // After file 3 is processed, file 2 is rejected by the validator and the
 | 
| -  // operation fails. That is, only file 3 should be in dest.
 | 
| -  FileSystemTestCaseRecord kMoveDirResultCases[] = {
 | 
| -    {false, FILE_PATH_LITERAL("file 3"), 0},
 | 
| -  };
 | 
| -
 | 
| -  helper.VerifyTestCaseFiles(dest,
 | 
| -                             kMoveDirResultCases,
 | 
| -                             arraysize(kMoveDirResultCases));
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFileNoValidator) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypeTest);
 | 
| -  helper.SetUpNoValidator();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -
 | 
| -  // Set up a source file.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
 | 
| -
 | 
| -  // The copy attempt should fail with a security error -- getting
 | 
| -  // the factory returns a security error, and the copy operation must
 | 
| -  // respect that.
 | 
| -  ASSERT_EQ(base::File::FILE_ERROR_SECURITY, helper.Copy(src, dest));
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) {
 | 
| -  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
 | 
| -                                       storage::kFileSystemTypeTemporary,
 | 
| -                                       storage::kFileSystemTypePersistent);
 | 
| -  helper.SetUp();
 | 
| -
 | 
| -  FileSystemURL src = helper.SourceURL("a");
 | 
| -  FileSystemURL dest = helper.DestURL("b");
 | 
| -
 | 
| -  // Set up a source directory.
 | 
| -  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.SetUpTestCaseFiles(src,
 | 
| -                                      kRegularFileSystemTestCases,
 | 
| -                                      kRegularFileSystemTestCaseSize));
 | 
| -
 | 
| -  std::vector<ProgressRecord> records;
 | 
| -  ASSERT_EQ(base::File::FILE_OK,
 | 
| -            helper.CopyWithProgress(src, dest,
 | 
| -                                    base::Bind(&RecordProgressCallback,
 | 
| -                                               base::Unretained(&records))));
 | 
| -
 | 
| -  // Verify progress callback.
 | 
| -  for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
 | 
| -    const FileSystemTestCaseRecord& test_case = kRegularFileSystemTestCases[i];
 | 
| -
 | 
| -    FileSystemURL src_url = helper.SourceURL(
 | 
| -        std::string("a/") + base::FilePath(test_case.path).AsUTF8Unsafe());
 | 
| -    FileSystemURL dest_url = helper.DestURL(
 | 
| -        std::string("b/") + base::FilePath(test_case.path).AsUTF8Unsafe());
 | 
| -
 | 
| -    // Find the first and last progress record.
 | 
| -    size_t begin_index = records.size();
 | 
| -    size_t end_index = records.size();
 | 
| -    for (size_t j = 0; j < records.size(); ++j) {
 | 
| -      if (records[j].source_url == src_url) {
 | 
| -        if (begin_index == records.size())
 | 
| -          begin_index = j;
 | 
| -        end_index = j;
 | 
| -      }
 | 
| -    }
 | 
| -
 | 
| -    // The record should be found.
 | 
| -    ASSERT_NE(begin_index, records.size());
 | 
| -    ASSERT_NE(end_index, records.size());
 | 
| -    ASSERT_NE(begin_index, end_index);
 | 
| -
 | 
| -    EXPECT_EQ(FileSystemOperation::BEGIN_COPY_ENTRY,
 | 
| -              records[begin_index].type);
 | 
| -    EXPECT_FALSE(records[begin_index].dest_url.is_valid());
 | 
| -    EXPECT_EQ(FileSystemOperation::END_COPY_ENTRY, records[end_index].type);
 | 
| -    EXPECT_EQ(dest_url, records[end_index].dest_url);
 | 
| -
 | 
| -    if (test_case.is_directory) {
 | 
| -      // For directory copy, the progress shouldn't be interlaced.
 | 
| -      EXPECT_EQ(begin_index + 1, end_index);
 | 
| -    } else {
 | 
| -      // PROGRESS event's size should be assending order.
 | 
| -      int64_t current_size = 0;
 | 
| -      for (size_t j = begin_index + 1; j < end_index; ++j) {
 | 
| -        if (records[j].source_url == src_url) {
 | 
| -          EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type);
 | 
| -          EXPECT_FALSE(records[j].dest_url.is_valid());
 | 
| -          EXPECT_GE(records[j].size, current_size);
 | 
| -          current_size = records[j].size;
 | 
| -        }
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper) {
 | 
| -  base::ScopedTempDir temp_dir;
 | 
| -  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 | 
| -  base::FilePath source_path = temp_dir.GetPath().AppendASCII("source");
 | 
| -  base::FilePath dest_path = temp_dir.GetPath().AppendASCII("dest");
 | 
| -  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
 | 
| -  base::WriteFile(source_path, kTestData,
 | 
| -                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
 | 
| -
 | 
| -  base::MessageLoopForIO message_loop;
 | 
| -  base::Thread file_thread("file_thread");
 | 
| -  ASSERT_TRUE(file_thread.Start());
 | 
| -  ScopedThreadStopper thread_stopper(&file_thread);
 | 
| -  ASSERT_TRUE(thread_stopper.is_valid());
 | 
| -
 | 
| -  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
 | 
| -      file_thread.task_runner();
 | 
| -
 | 
| -  std::unique_ptr<storage::FileStreamReader> reader(
 | 
| -      storage::FileStreamReader::CreateForLocalFile(
 | 
| -          task_runner.get(), source_path, 0, base::Time()));
 | 
| -
 | 
| -  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
 | 
| -      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
 | 
| -
 | 
| -  std::vector<int64_t> progress;
 | 
| -  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
 | 
| -      std::move(reader), std::move(writer),
 | 
| -      storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
 | 
| -      10,  // buffer size
 | 
| -      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
 | 
| -      base::TimeDelta());  // For testing, we need all the progress.
 | 
| -
 | 
| -  base::File::Error error = base::File::FILE_ERROR_FAILED;
 | 
| -  base::RunLoop run_loop;
 | 
| -  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
 | 
| -  run_loop.Run();
 | 
| -
 | 
| -  EXPECT_EQ(base::File::FILE_OK, error);
 | 
| -  ASSERT_EQ(5U, progress.size());
 | 
| -  EXPECT_EQ(0, progress[0]);
 | 
| -  EXPECT_EQ(10, progress[1]);
 | 
| -  EXPECT_EQ(20, progress[2]);
 | 
| -  EXPECT_EQ(30, progress[3]);
 | 
| -  EXPECT_EQ(36, progress[4]);
 | 
| -
 | 
| -  std::string content;
 | 
| -  ASSERT_TRUE(base::ReadFileToString(dest_path, &content));
 | 
| -  EXPECT_EQ(kTestData, content);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelperWithFlush) {
 | 
| -  // Testing the same configuration as StreamCopyHelper, but with |need_flush|
 | 
| -  // parameter set to true. Since it is hard to test that the flush is indeed
 | 
| -  // taking place, this test just only verifies that the file is correctly
 | 
| -  // written with or without the flag.
 | 
| -  base::ScopedTempDir temp_dir;
 | 
| -  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 | 
| -  base::FilePath source_path = temp_dir.GetPath().AppendASCII("source");
 | 
| -  base::FilePath dest_path = temp_dir.GetPath().AppendASCII("dest");
 | 
| -  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
 | 
| -  base::WriteFile(source_path, kTestData,
 | 
| -                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
 | 
| -
 | 
| -
 | 
| -  base::MessageLoopForIO message_loop;
 | 
| -  base::Thread file_thread("file_thread");
 | 
| -  ASSERT_TRUE(file_thread.Start());
 | 
| -  ScopedThreadStopper thread_stopper(&file_thread);
 | 
| -  ASSERT_TRUE(thread_stopper.is_valid());
 | 
| -
 | 
| -  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
 | 
| -      file_thread.task_runner();
 | 
| -
 | 
| -  std::unique_ptr<storage::FileStreamReader> reader(
 | 
| -      storage::FileStreamReader::CreateForLocalFile(
 | 
| -          task_runner.get(), source_path, 0, base::Time()));
 | 
| -
 | 
| -  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
 | 
| -      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
 | 
| -
 | 
| -  std::vector<int64_t> progress;
 | 
| -  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
 | 
| -      std::move(reader), std::move(writer),
 | 
| -      storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
 | 
| -      10,  // buffer size
 | 
| -      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
 | 
| -      base::TimeDelta());  // For testing, we need all the progress.
 | 
| -
 | 
| -  base::File::Error error = base::File::FILE_ERROR_FAILED;
 | 
| -  base::RunLoop run_loop;
 | 
| -  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
 | 
| -  run_loop.Run();
 | 
| -
 | 
| -  EXPECT_EQ(base::File::FILE_OK, error);
 | 
| -  ASSERT_EQ(5U, progress.size());
 | 
| -  EXPECT_EQ(0, progress[0]);
 | 
| -  EXPECT_EQ(10, progress[1]);
 | 
| -  EXPECT_EQ(20, progress[2]);
 | 
| -  EXPECT_EQ(30, progress[3]);
 | 
| -  EXPECT_EQ(36, progress[4]);
 | 
| -
 | 
| -  std::string content;
 | 
| -  ASSERT_TRUE(base::ReadFileToString(dest_path, &content));
 | 
| -  EXPECT_EQ(kTestData, content);
 | 
| -}
 | 
| -
 | 
| -TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper_Cancel) {
 | 
| -  base::ScopedTempDir temp_dir;
 | 
| -  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
 | 
| -  base::FilePath source_path = temp_dir.GetPath().AppendASCII("source");
 | 
| -  base::FilePath dest_path = temp_dir.GetPath().AppendASCII("dest");
 | 
| -  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
 | 
| -  base::WriteFile(source_path, kTestData,
 | 
| -                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
 | 
| -
 | 
| -  base::MessageLoopForIO message_loop;
 | 
| -  base::Thread file_thread("file_thread");
 | 
| -  ASSERT_TRUE(file_thread.Start());
 | 
| -  ScopedThreadStopper thread_stopper(&file_thread);
 | 
| -  ASSERT_TRUE(thread_stopper.is_valid());
 | 
| -
 | 
| -  scoped_refptr<base::SingleThreadTaskRunner> task_runner =
 | 
| -      file_thread.task_runner();
 | 
| -
 | 
| -  std::unique_ptr<storage::FileStreamReader> reader(
 | 
| -      storage::FileStreamReader::CreateForLocalFile(
 | 
| -          task_runner.get(), source_path, 0, base::Time()));
 | 
| -
 | 
| -  std::unique_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
 | 
| -      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
 | 
| -
 | 
| -  std::vector<int64_t> progress;
 | 
| -  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
 | 
| -      std::move(reader), std::move(writer),
 | 
| -      storage::FlushPolicy::NO_FLUSH_ON_COMPLETION,
 | 
| -      10,  // buffer size
 | 
| -      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
 | 
| -      base::TimeDelta());  // For testing, we need all the progress.
 | 
| -
 | 
| -  // Call Cancel() later.
 | 
| -  base::ThreadTaskRunnerHandle::Get()->PostTask(
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&CopyOrMoveOperationDelegate::StreamCopyHelper::Cancel,
 | 
| -                 base::Unretained(&helper)));
 | 
| -
 | 
| -  base::File::Error error = base::File::FILE_ERROR_FAILED;
 | 
| -  base::RunLoop run_loop;
 | 
| -  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
 | 
| -  run_loop.Run();
 | 
| -
 | 
| -  EXPECT_EQ(base::File::FILE_ERROR_ABORT, error);
 | 
| -}
 | 
| -
 | 
| -}  // namespace content
 | 
| 
 |