1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/recursive_operation_delegate.h" 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <vector> 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/basictypes.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/message_loop/message_loop.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/sandbox_file_system_test_helper.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_file_util.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemContext; 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationContext; 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace { 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class LoggingRecursiveOperation : public storage::RecursiveOperationDelegate { 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) struct LogEntry { 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) enum Type { 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PROCESS_FILE, 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) PROCESS_DIRECTORY, 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) POST_PROCESS_DIRECTORY 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Type type; 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL url; 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LoggingRecursiveOperation(FileSystemContext* file_system_context, 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& root, 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : storage::RecursiveOperationDelegate(file_system_context), 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) root_(root), 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback_(callback), 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) weak_factory_(this) {} 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~LoggingRecursiveOperation() {} 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const std::vector<LogEntry>& log_entries() const { return log_entries_; } 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // RecursiveOperationDelegate overrides. 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void Run() OVERRIDE { 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) NOTREACHED(); 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void RunRecursively() OVERRIDE { 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) StartRecursiveOperation(root_, callback_); 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void ProcessFile(const FileSystemURL& url, 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) OVERRIDE { 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RecordLogEntry(LogEntry::PROCESS_FILE, url); 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation_runner()->GetMetadata( 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) url, 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&LoggingRecursiveOperation::DidGetMetadata, 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void ProcessDirectory(const FileSystemURL& url, 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) OVERRIDE { 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RecordLogEntry(LogEntry::PROCESS_DIRECTORY, url); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void PostProcessDirectory(const FileSystemURL& url, 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) OVERRIDE { 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RecordLogEntry(LogEntry::POST_PROCESS_DIRECTORY, url); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RecordLogEntry(LogEntry::Type type, const FileSystemURL& url) { 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LogEntry entry; 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) entry.type = type; 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) entry.url = url; 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries_.push_back(entry); 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void DidGetMetadata(const StatusCallback& callback, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error result, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != base::File::FILE_OK) { 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(result); 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(file_info.is_directory ? 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FILE_ERROR_NOT_A_FILE : 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FILE_OK); 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL root_; 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) StatusCallback callback_; 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::vector<LogEntry> log_entries_; 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::WeakPtrFactory<LoggingRecursiveOperation> weak_factory_; 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LoggingRecursiveOperation); 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReportStatus(base::File::Error* out_error, 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(out_error); 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *out_error = error; 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// To test the Cancel() during operation, calls Cancel() of |operation| 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// after |counter| times message posting. 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void CallCancelLater(storage::RecursiveOperationDelegate* operation, 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int counter) { 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (counter > 0) { 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessageLoopProxy::current()->PostTask( 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&CallCancelLater, base::Unretained(operation), counter - 1)); 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->Cancel(); 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class RecursiveOperationDelegateTest : public testing::Test { 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected: 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void SetUp() OVERRIDE { 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(base_.CreateUniqueTempDir()); 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sandbox_file_system_.SetUp(base_.path().AppendASCII("filesystem")); 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void TearDown() OVERRIDE { 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sandbox_file_system_.TearDown(); 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<FileSystemOperationContext> NewContext() { 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemOperationContext* context = 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) sandbox_file_system_.NewOperationContext(); 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Grant enough quota for all test cases. 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) context->set_allowed_bytes_growth(1000000); 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return make_scoped_ptr(context); 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemFileUtil* file_util() { 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return sandbox_file_system_.file_util(); 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL URLForPath(const std::string& path) const { 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return sandbox_file_system_.CreateURLFromUTF8(path); 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL CreateFile(const std::string& path) { 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL url = URLForPath(path); 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool created = false; 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_util()->EnsureFileExists(NewContext().get(), 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) url, &created)); 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE(created); 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return url; 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL CreateDirectory(const std::string& path) { 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL url = URLForPath(path); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_util()->CreateDirectory(NewContext().get(), url, 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) false /* exclusive */, true)); 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return url; 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::MessageLoop message_loop_; 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Common temp base for nondestructive uses. 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::ScopedTempDir base_; 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SandboxFileSystemTestHelper sandbox_file_system_; 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RecursiveOperationDelegateTest, RootIsFile) { 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file(CreateFile("src")); 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error = base::File::FILE_ERROR_FAILED; 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<FileSystemOperationContext> context = NewContext(); 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LoggingRecursiveOperation> operation( 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new LoggingRecursiveOperation( 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) context->file_system_context(), src_file, 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ReportStatus, &error))); 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->RunRecursively(); 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_OK, error); 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries = 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->log_entries(); 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(1U, log_entries.size()); 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const LoggingRecursiveOperation::LogEntry& entry = log_entries[0]; 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, entry.type); 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_file, entry.url); 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RecursiveOperationDelegateTest, RootIsDirectory) { 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_root(CreateDirectory("src")); 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_dir1(CreateDirectory("src/dir1")); 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file1(CreateFile("src/file1")); 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file2(CreateFile("src/dir1/file2")); 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file3(CreateFile("src/dir1/file3")); 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error = base::File::FILE_ERROR_FAILED; 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<FileSystemOperationContext> context = NewContext(); 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LoggingRecursiveOperation> operation( 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new LoggingRecursiveOperation( 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) context->file_system_context(), src_root, 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ReportStatus, &error))); 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->RunRecursively(); 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_OK, error); 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const std::vector<LoggingRecursiveOperation::LogEntry>& log_entries = 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->log_entries(); 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(8U, log_entries.size()); 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[0].type); 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_root, log_entries[0].url); 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY, 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[1].type); 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_root, log_entries[1].url); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[2].type); 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_file1, log_entries[2].url); 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_DIRECTORY, 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[3].type); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_dir1, log_entries[3].url); 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The order of src/dir1/file2 and src/dir1/file3 depends on the file system 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // implementation (can be swapped). 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[4].type); 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::PROCESS_FILE, 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[5].type); 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_TRUE((src_file2 == log_entries[4].url && 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) src_file3 == log_entries[5].url) || 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) (src_file3 == log_entries[4].url && 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) src_file2 == log_entries[5].url)); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY, 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[6].type); 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_dir1, log_entries[6].url); 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(LoggingRecursiveOperation::LogEntry::POST_PROCESS_DIRECTORY, 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) log_entries[7].type); 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(src_root, log_entries[7].url); 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RecursiveOperationDelegateTest, Cancel) { 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_root(CreateDirectory("src")); 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_dir1(CreateDirectory("src/dir1")); 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file1(CreateFile("src/file1")); 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemURL src_file2(CreateFile("src/dir1/file2")); 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error = base::File::FILE_ERROR_FAILED; 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<FileSystemOperationContext> context = NewContext(); 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LoggingRecursiveOperation> operation( 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new LoggingRecursiveOperation( 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) context->file_system_context(), src_root, 275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&ReportStatus, &error))); 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation->RunRecursively(); 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Invoke Cancel(), after 5 times message posting. 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CallCancelLater(operation.get(), 5); 280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_ABORT, error); 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 285