14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <queue>
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/quota/mock_quota_manager.h"
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/quota/mock_quota_manager_proxy.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/async_file_test_helper.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_backend.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_context.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/test/fileapi_test_file_set.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/copy_or_move_file_validator.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/copy_or_move_operation_delegate.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_stream_writer.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_backend.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h"
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::AsyncFileTestHelper;
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::CopyOrMoveOperationDelegate;
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileStreamWriter;
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperation;
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef storage::FileSystemOperation::FileEntryList FileEntryList;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ExpectOk(const GURL& origin_url,
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              const std::string& name,
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              base::File::Error error) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, error);
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class TestValidatorFactory : public storage::CopyOrMoveFileValidatorFactory {
52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch public:
53a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // A factory that creates validators that accept everything or nothing.
54a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  TestValidatorFactory() {}
55a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  virtual ~TestValidatorFactory() {}
56a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
58a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      const FileSystemURL& /*src_url*/,
59a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      const base::FilePath& /*platform_path*/) OVERRIDE {
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Move arg management to TestValidator?
61a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return new TestValidator(true, true, std::string("2"));
62a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
64a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch private:
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  class TestValidator : public storage::CopyOrMoveFileValidator {
66a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch   public:
67a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    explicit TestValidator(bool pre_copy_valid,
68a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                           bool post_copy_valid,
69a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                           const std::string& reject_string)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        : result_(pre_copy_valid ? base::File::FILE_OK :
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   base::File::FILE_ERROR_SECURITY),
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          write_result_(post_copy_valid ? base::File::FILE_OK :
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          base::File::FILE_ERROR_SECURITY),
74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          reject_string_(reject_string) {
75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    virtual ~TestValidator() {}
77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    virtual void StartPreWriteValidation(
79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        const ResultCallback& result_callback) OVERRIDE {
80a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      // Post the result since a real validator must do work asynchronously.
81a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      base::MessageLoop::current()->PostTask(
82a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          FROM_HERE, base::Bind(result_callback, result_));
83a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
85a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    virtual void StartPostWriteValidation(
86a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        const base::FilePath& dest_platform_path,
87a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        const ResultCallback& result_callback) OVERRIDE {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::File::Error result = write_result_;
89a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      std::string unsafe = dest_platform_path.BaseName().AsUTF8Unsafe();
90a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      if (unsafe.find(reject_string_) != std::string::npos) {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        result = base::File::FILE_ERROR_SECURITY;
92a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      }
93a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      // Post the result since a real validator must do work asynchronously.
94a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      base::MessageLoop::current()->PostTask(
95a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          FROM_HERE, base::Bind(result_callback, result));
96a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
97a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
98a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch   private:
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result_;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error write_result_;
101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    std::string reject_string_;
102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    DISALLOW_COPY_AND_ASSIGN(TestValidator);
104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  };
105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch};
106a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Records CopyProgressCallback invocations.
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)struct ProgressRecord {
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemOperation::CopyProgressType type;
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemURL source_url;
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  FileSystemURL dest_url;
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int64 size;
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void RecordProgressCallback(std::vector<ProgressRecord>* records,
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                            storage::FileSystemOperation::CopyProgressType type,
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            const FileSystemURL& source_url,
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                            const FileSystemURL& dest_url,
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                            int64 size) {
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ProgressRecord record;
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  record.type = type;
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  record.source_url = source_url;
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  record.dest_url = dest_url;
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  record.size = size;
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  records->push_back(record);
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void RecordFileProgressCallback(std::vector<int64>* records,
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                int64 progress) {
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  records->push_back(progress);
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AssignAndQuit(base::RunLoop* run_loop,
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::File::Error* result_out,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::File::Error result) {
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  *result_out = result;
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  run_loop->Quit();
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class ScopedThreadStopper {
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public:
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedThreadStopper(base::Thread* thread) : thread_(thread) {
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ~ScopedThreadStopper() {
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (thread_) {
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // Give another chance for deleted streams to perform Close.
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::RunLoop run_loop;
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      thread_->message_loop_proxy()->PostTaskAndReply(
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          FROM_HERE, base::Bind(&base::DoNothing), run_loop.QuitClosure());
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      run_loop.Run();
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      thread_->Stop();
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool is_valid() const { return thread_; }
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private:
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::Thread* thread_;
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedThreadStopper);
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CopyOrMoveOperationTestHelper {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CopyOrMoveOperationTestHelper(const GURL& origin,
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                storage::FileSystemType src_type,
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                storage::FileSystemType dest_type)
1706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      : origin_(origin), src_type_(src_type), dest_type_(dest_type) {}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ~CopyOrMoveOperationTestHelper() {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_context_ = NULL;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    quota_manager_proxy_->SimulateQuotaManagerDestroyed();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    quota_manager_ = NULL;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    quota_manager_proxy_ = NULL;
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetUp() {
181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetUp(true, true);
182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void SetUpNoValidator() {
185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetUp(true, false);
186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  void SetUp(bool require_copy_or_move_validator,
189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)             bool init_copy_or_move_validator) {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(base_.CreateUniqueTempDir());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath base_dir = base_.path();
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    quota_manager_ =
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        new MockQuotaManager(false /* is_incognito */,
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    base_dir,
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    base::MessageLoopProxy::current().get(),
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    base::MessageLoopProxy::current().get(),
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                    NULL /* special storage policy */);
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    quota_manager_proxy_ = new MockQuotaManagerProxy(
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        quota_manager_.get(), base::MessageLoopProxy::current().get());
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    file_system_context_ =
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        CreateFileSystemContextForTesting(quota_manager_proxy_.get(), base_dir);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Prepare the origin's root directory.
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemBackend* backend =
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        file_system_context_->GetFileSystemBackend(src_type_);
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    backend->ResolveURL(
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        FileSystemURL::CreateForTest(origin_, src_type_, base::FilePath()),
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ExpectOk));
21058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch    backend = file_system_context_->GetFileSystemBackend(dest_type_);
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (dest_type_ == storage::kFileSystemTypeTest) {
21258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch      TestFileSystemBackend* test_backend =
21358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch          static_cast<TestFileSystemBackend*>(backend);
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      scoped_ptr<storage::CopyOrMoveFileValidatorFactory> factory(
215a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          new TestValidatorFactory);
216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      test_backend->set_require_copy_or_move_validator(
217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          require_copy_or_move_validator);
218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (init_copy_or_move_validator)
219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        test_backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
220a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    backend->ResolveURL(
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        FileSystemURL::CreateForTest(origin_, dest_type_, base::FilePath()),
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&ExpectOk));
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    base::RunLoop().RunUntilIdle();
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Grant relatively big quota initially.
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    quota_manager_->SetQuota(
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        origin_,
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::FileSystemTypeToQuotaStorageType(src_type_),
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        1024 * 1024);
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    quota_manager_->SetQuota(
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        origin_,
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::FileSystemTypeToQuotaStorageType(dest_type_),
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        1024 * 1024);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 GetSourceUsage() {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 usage = 0;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetUsageAndQuota(src_type_, &usage, NULL);
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return usage;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 GetDestUsage() {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 usage = 0;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetUsageAndQuota(dest_type_, &usage, NULL);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return usage;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL SourceURL(const std::string& path) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return file_system_context_->CreateCrackedFileSystemURL(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        origin_, src_type_, base::FilePath::FromUTF8Unsafe(path));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL DestURL(const std::string& path) {
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return file_system_context_->CreateCrackedFileSystemURL(
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        origin_, dest_type_, base::FilePath::FromUTF8Unsafe(path));
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error Copy(const FileSystemURL& src,
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         const FileSystemURL& dest) {
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AsyncFileTestHelper::Copy(file_system_context_.get(), src, dest);
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error CopyWithProgress(
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const FileSystemURL& src,
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const FileSystemURL& dest,
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const AsyncFileTestHelper::CopyProgressCallback& progress_callback) {
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return AsyncFileTestHelper::CopyWithProgress(
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        file_system_context_.get(), src, dest, progress_callback);
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error Move(const FileSystemURL& src,
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         const FileSystemURL& dest) {
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AsyncFileTestHelper::Move(file_system_context_.get(), src, dest);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error SetUpTestCaseFiles(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const FileSystemURL& root,
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const FileSystemTestCaseRecord* const test_cases,
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t test_case_size) {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result = base::File::FILE_ERROR_FAILED;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < test_case_size; ++i) {
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const FileSystemTestCaseRecord& test_case = test_cases[i];
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          root.origin(),
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          root.mount_type(),
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          root.virtual_path().Append(test_case.path));
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (test_case.is_directory)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = CreateDirectory(url);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      else
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result = CreateFile(url, test_case.data_file_size);
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(base::File::FILE_OK, result) << url.DebugString();
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (result != base::File::FILE_OK)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return result;
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return result;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyTestCaseFiles(
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const FileSystemURL& root,
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const FileSystemTestCaseRecord* const test_cases,
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t test_case_size) {
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::map<base::FilePath, const FileSystemTestCaseRecord*> test_case_map;
305a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    for (size_t i = 0; i < test_case_size; ++i) {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_case_map[
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::FilePath(test_cases[i].path).NormalizePathSeparators()] =
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              &test_cases[i];
309a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::queue<FileSystemURL> directories;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FileEntryList entries;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    directories.push(root);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (!directories.empty()) {
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FileSystemURL dir = directories.front();
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      directories.pop();
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_EQ(base::File::FILE_OK, ReadDirectory(dir, &entries));
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (size_t i = 0; i < entries.size(); ++i) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL(
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            dir.origin(),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            dir.mount_type(),
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            dir.virtual_path().Append(entries[i].name));
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath relative;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        root.virtual_path().AppendRelativePath(url.virtual_path(), &relative);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        relative = relative.NormalizePathSeparators();
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ASSERT_TRUE(ContainsKey(test_case_map, relative));
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (entries[i].is_directory) {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(test_case_map[relative]->is_directory);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          directories.push(url);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_FALSE(test_case_map[relative]->is_directory);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          EXPECT_TRUE(FileExists(url, test_case_map[relative]->data_file_size));
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        test_case_map.erase(relative);
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(test_case_map.empty());
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::map<base::FilePath,
339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        const FileSystemTestCaseRecord*>::const_iterator it;
340a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    for (it = test_case_map.begin(); it != test_case_map.end(); ++it) {
341a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      LOG(ERROR) << "Extra entry: " << it->first.LossyDisplayName();
342a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error ReadDirectory(const FileSystemURL& url,
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  FileEntryList* entries) {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return AsyncFileTestHelper::ReadDirectory(
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_context_.get(), url, entries);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error CreateDirectory(const FileSystemURL& url) {
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                url);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error CreateFile(const FileSystemURL& url, size_t size) {
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error result =
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (result != base::File::FILE_OK)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return result;
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AsyncFileTestHelper::TruncateFile(
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_context_.get(), url, size);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool FileExists(const FileSystemURL& url, int64 expected_size) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return AsyncFileTestHelper::FileExists(
367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        file_system_context_.get(), url, expected_size);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool DirectoryExists(const FileSystemURL& url) {
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AsyncFileTestHelper::DirectoryExists(file_system_context_.get(),
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                                url);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void GetUsageAndQuota(storage::FileSystemType type,
3776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        int64* usage,
3786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        int64* quota) {
37903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaStatusCode status = AsyncFileTestHelper::GetUsageAndQuota(
380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        quota_manager_.get(), origin_, type, usage, quota);
38103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ASSERT_EQ(storage::kQuotaStatusOk, status);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir base_;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL origin_;
38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const storage::FileSystemType src_type_;
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const storage::FileSystemType dest_type_;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoopForIO message_loop_;
39203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context_;
393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_refptr<MockQuotaManager> quota_manager_;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationTestHelper);
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFile) {
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source file.
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy it.
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.FileExists(src, 10));
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.FileExists(dest, 10));
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleFile) {
429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source file.
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it.
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(helper.FileExists(src, AsyncFileTestHelper::kDontCheckSize));
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.FileExists(dest, 10));
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage, src_new_usage);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleDirectory) {
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source directory.
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy it.
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.Copy(src, dest));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(src));
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(dest));
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, MoveSingleDirectory) {
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
48903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source directory.
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it.
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(helper.DirectoryExists(src));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(dest));
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage, src_new_usage);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
516868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
51703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
51803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source directory.
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            helper.SetUpTestCaseFiles(src,
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCases,
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCaseSize));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copy it.
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            helper.CopyWithProgress(
537d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                src, dest,
538d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                AsyncFileTestHelper::CopyProgressCallback()));
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(src));
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(dest));
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.VerifyTestCaseFiles(dest,
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             kRegularFileSystemTestCases,
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             kRegularFileSystemTestCaseSize);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage + src_increase, src_new_usage);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, MoveDirectory) {
556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
55703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
55803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.SetUp();
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_initial_usage = helper.GetSourceUsage();
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_initial_usage = helper.GetDestUsage();
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set up a source directory.
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            helper.SetUpTestCaseFiles(src,
570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCases,
571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCaseSize));
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it.
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.Move(src, dest));
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify.
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(helper.DirectoryExists(src));
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(helper.DirectoryExists(dest));
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  helper.VerifyTestCaseFiles(dest,
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             kRegularFileSystemTestCases,
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             kRegularFileSystemTestCaseSize);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 src_new_usage = helper.GetSourceUsage();
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_initial_usage, src_new_usage);
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 dest_increase = helper.GetDestUsage() - dest_initial_usage;
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(src_increase, dest_increase);
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a3f7b4e666c476898878fa745f637129375cd889Ben MurdochTEST(LocalFileSystemCopyOrMoveOperationTest,
593a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch     MoveDirectoryFailPostWriteValidation) {
594a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTest);
597a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  helper.SetUp();
598a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
599a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  FileSystemURL src = helper.SourceURL("a");
600a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  FileSystemURL dest = helper.DestURL("b");
601a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
602a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Set up a source directory.
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
605a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch            helper.SetUpTestCaseFiles(src,
606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCases,
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCaseSize));
608a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
609a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Move it.
610a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  helper.Move(src, dest);
611a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
612a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Verify.
613a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ASSERT_TRUE(helper.DirectoryExists(src));
614a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ASSERT_TRUE(helper.DirectoryExists(dest));
615a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FileSystemTestCaseRecord kMoveDirResultCases[] = {
617a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    {false, FILE_PATH_LITERAL("file 0"), 38},
618a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    {false, FILE_PATH_LITERAL("file 3"), 0},
619a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  };
620a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
621a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  helper.VerifyTestCaseFiles(dest,
622a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                             kMoveDirResultCases,
623a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                             arraysize(kMoveDirResultCases));
624a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
625a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFileNoValidator) {
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
62803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
62903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTest);
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  helper.SetUpNoValidator();
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Set up a source file.
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateFile(src, 10));
637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The copy attempt should fail with a security error -- getting
639a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // the factory returns a security error, and the copy operation must
640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // respect that.
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_ERROR_SECURITY, helper.Copy(src, dest));
642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
644d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) {
645d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
64603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypeTemporary,
64703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::kFileSystemTypePersistent);
648d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  helper.SetUp();
649d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
650d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FileSystemURL src = helper.SourceURL("a");
651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FileSystemURL dest = helper.DestURL("b");
652d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
653d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Set up a source directory.
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK, helper.CreateDirectory(src));
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
656d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            helper.SetUpTestCaseFiles(src,
657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCases,
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      kRegularFileSystemTestCaseSize));
659d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
660d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::vector<ProgressRecord> records;
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(base::File::FILE_OK,
662d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            helper.CopyWithProgress(src, dest,
663d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                    base::Bind(&RecordProgressCallback,
664d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                               base::Unretained(&records))));
665d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
666d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Verify progress callback.
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < kRegularFileSystemTestCaseSize; ++i) {
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const FileSystemTestCaseRecord& test_case = kRegularFileSystemTestCases[i];
669d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
67068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    FileSystemURL src_url = helper.SourceURL(
67168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        std::string("a/") + base::FilePath(test_case.path).AsUTF8Unsafe());
67268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    FileSystemURL dest_url = helper.DestURL(
67368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        std::string("b/") + base::FilePath(test_case.path).AsUTF8Unsafe());
674d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
675d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Find the first and last progress record.
676d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    size_t begin_index = records.size();
677d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    size_t end_index = records.size();
678d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    for (size_t j = 0; j < records.size(); ++j) {
67968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (records[j].source_url == src_url) {
680d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        if (begin_index == records.size())
681d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          begin_index = j;
682d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        end_index = j;
683d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
684d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
685d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The record should be found.
687d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_NE(begin_index, records.size());
688d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_NE(end_index, records.size());
689d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ASSERT_NE(begin_index, end_index);
690d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
691d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(FileSystemOperation::BEGIN_COPY_ENTRY,
692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)              records[begin_index].type);
69368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(records[begin_index].dest_url.is_valid());
694d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    EXPECT_EQ(FileSystemOperation::END_COPY_ENTRY, records[end_index].type);
69568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_EQ(dest_url, records[end_index].dest_url);
696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (test_case.is_directory) {
698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // For directory copy, the progress shouldn't be interlaced.
699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      EXPECT_EQ(begin_index + 1, end_index);
700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // PROGRESS event's size should be assending order.
702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      int64 current_size = 0;
703d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      for (size_t j = begin_index + 1; j < end_index; ++j) {
70468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        if (records[j].source_url == src_url) {
705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type);
70668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          EXPECT_FALSE(records[j].dest_url.is_valid());
707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          EXPECT_GE(records[j].size, current_size);
708d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          current_size = records[j].size;
709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        }
710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
714d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
71568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper) {
71668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::ScopedTempDir temp_dir;
71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
71868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::FilePath source_path = temp_dir.path().AppendASCII("source");
71923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::FilePath dest_path = temp_dir.path().AppendASCII("dest");
72068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
721a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WriteFile(source_path, kTestData,
722a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
72368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoopForIO message_loop;
72568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::Thread file_thread("file_thread");
72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_TRUE(file_thread.Start());
72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedThreadStopper thread_stopper(&file_thread);
72868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_TRUE(thread_stopper.is_valid());
72968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
73068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> task_runner =
73168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      file_thread.message_loop_proxy();
73268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
73303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::FileStreamReader> reader(
73403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileStreamReader::CreateForLocalFile(
73568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          task_runner.get(), source_path, 0, base::Time()));
73668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
73723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
73823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
73968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
74068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::vector<int64> progress;
74168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
74268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      reader.Pass(), writer.Pass(),
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      false,  // don't need flush
7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      10,  // buffer size
7455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
7465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::TimeDelta());  // For testing, we need all the progress.
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_ERROR_FAILED;
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop run_loop;
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  run_loop.Run();
7525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, error);
7545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(5U, progress.size());
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0, progress[0]);
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(10, progress[1]);
7575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(20, progress[2]);
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(30, progress[3]);
7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(36, progress[4]);
7605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string content;
7625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(dest_path, &content));
7635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(kTestData, content);
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelperWithFlush) {
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Testing the same configuration as StreamCopyHelper, but with |need_flush|
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // parameter set to true. Since it is hard to test that the flush is indeed
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // taking place, this test just only verifies that the file is correctly
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // written with or without the flag.
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ScopedTempDir temp_dir;
7725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath source_path = temp_dir.path().AppendASCII("source");
77423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::FilePath dest_path = temp_dir.path().AppendASCII("dest");
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WriteFile(source_path, kTestData,
777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForIO message_loop;
7815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Thread file_thread("file_thread");
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(file_thread.Start());
7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedThreadStopper thread_stopper(&file_thread);
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(thread_stopper.is_valid());
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> task_runner =
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_thread.message_loop_proxy();
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::FileStreamReader> reader(
79003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileStreamReader::CreateForLocalFile(
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          task_runner.get(), source_path, 0, base::Time()));
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
79323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
79423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<int64> progress;
7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      reader.Pass(), writer.Pass(),
7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      true,  // need flush
80068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      10,  // buffer size
80168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
80268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      base::TimeDelta());  // For testing, we need all the progress.
80368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_ERROR_FAILED;
80568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::RunLoop run_loop;
80668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
80768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  run_loop.Run();
80868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_OK, error);
81068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_EQ(5U, progress.size());
81168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(0, progress[0]);
81268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(10, progress[1]);
81368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(20, progress[2]);
81468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(30, progress[3]);
81568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(36, progress[4]);
81668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
81768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string content;
81868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ASSERT_TRUE(base::ReadFileToString(dest_path, &content));
81968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(kTestData, content);
82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
82168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(LocalFileSystemCopyOrMoveOperationTest, StreamCopyHelper_Cancel) {
8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ScopedTempDir temp_dir;
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath source_path = temp_dir.path().AppendASCII("source");
82623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::FilePath dest_path = temp_dir.path().AppendASCII("dest");
8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const char kTestData[] = "abcdefghijklmnopqrstuvwxyz0123456789";
828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::WriteFile(source_path, kTestData,
829a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  arraysize(kTestData) - 1);  // Exclude trailing '\0'.
8304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoopForIO message_loop;
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::Thread file_thread("file_thread");
8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(file_thread.Start());
8344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedThreadStopper thread_stopper(&file_thread);
8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(thread_stopper.is_valid());
8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> task_runner =
8384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      file_thread.message_loop_proxy();
8394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
84003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<storage::FileStreamReader> reader(
84103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileStreamReader::CreateForLocalFile(
8424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          task_runner.get(), source_path, 0, base::Time()));
8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
84423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<FileStreamWriter> writer(FileStreamWriter::CreateForLocalFile(
84523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      task_runner.get(), dest_path, 0, FileStreamWriter::CREATE_NEW_FILE));
8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<int64> progress;
8484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CopyOrMoveOperationDelegate::StreamCopyHelper helper(
8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      reader.Pass(), writer.Pass(),
8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      false,  // need_flush
8514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      10,  // buffer size
8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&RecordFileProgressCallback, base::Unretained(&progress)),
8534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::TimeDelta());  // For testing, we need all the progress.
8544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Call Cancel() later.
8564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoopProxy::current()->PostTask(
8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      FROM_HERE,
8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&CopyOrMoveOperationDelegate::StreamCopyHelper::Cancel,
8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 base::Unretained(&helper)));
8604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_ERROR_FAILED;
8624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::RunLoop run_loop;
8634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  helper.Run(base::Bind(&AssignAndQuit, &run_loop, &error));
8644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  run_loop.Run();
8654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(base::File::FILE_ERROR_ABORT, error);
8674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
870