1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/fileapi/mock_file_change_observer.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/quota/mock_quota_manager.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/mock_blob_url_request_context.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_backend.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_context.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job_factory_impl.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_storage_context.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/blob_url_request_job.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_file_util.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/local_file_util.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/blob_data.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperation; 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationRunner; 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::MockBlobURLRequestContext; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::ScopedTextBlob; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const GURL kOrigin("http://example.com"); 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const storage::FileSystemType kFileSystemType = storage::kFileSystemTypeTest; 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AssertStatusEq(base::File::Error expected, 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error actual) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(expected, actual); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class FileSystemOperationImplWriteTest 54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : public testing::Test { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FileSystemOperationImplWriteTest() 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : status_(base::File::FILE_OK), 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cancel_status_(base::File::FILE_ERROR_FAILED), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_written_(0), 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch complete_(false), 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_factory_(this) { 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) change_observers_ = 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::MockFileChangeObserver::CreateList(&change_observer_); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(dir_.CreateUniqueTempDir()); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) quota_manager_ = 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new MockQuotaManager(false /* is_incognito */, 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dir_.path(), 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::MessageLoopProxy::current().get(), 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::MessageLoopProxy::current().get(), 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NULL /* special storage policy */); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual_path_ = base::FilePath(FILE_PATH_LITERAL("temporary file")); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_system_context_ = CreateFileSystemContextForTesting( 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quota_manager_->proxy(), dir_.path()); 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) url_request_context_.reset( 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new MockBlobURLRequestContext(file_system_context_.get())); 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->CreateFile( 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLForPath(virtual_path_), true /* exclusive */, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&AssertStatusEq, base::File::FILE_OK)); 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch static_cast<TestFileSystemBackend*>( 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch file_system_context_->GetFileSystemBackend(kFileSystemType)) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ->AddFileChangeObserver(change_observer()); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void TearDown() { 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) quota_manager_ = NULL; 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_system_context_ = NULL; 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status() const { return status_; } 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status() const { return cancel_status_; } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void add_bytes_written(int64 bytes, bool complete) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_written_ += bytes; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(complete_); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) complete_ = complete; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 bytes_written() const { return bytes_written_; } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool complete() const { return complete_; } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::ChangeObserverList& change_observers() const { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return change_observers_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::MockFileChangeObserver* change_observer() { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &change_observer_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemURL URLForPath(const base::FilePath& path) const { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return file_system_context_->CreateCrackedFileSystemURL( 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kOrigin, kFileSystemType, path); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback function for recording test results. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemOperation::WriteCallback RecordWriteCallback() { 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return base::Bind(&FileSystemOperationImplWriteTest::DidWrite, 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_factory_.GetWeakPtr()); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileSystemOperation::StatusCallback RecordCancelCallback() { 128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return base::Bind(&FileSystemOperationImplWriteTest::DidCancel, 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_factory_.GetWeakPtr()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DidWrite(base::File::Error status, int64 bytes, bool complete) { 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (status == base::File::FILE_OK) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_bytes_written(bytes, complete); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (complete) 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(complete_); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(status_, base::File::FILE_OK); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) complete_ = true; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status_ = status; 142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (base::MessageLoop::current()->is_running()) 143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DidCancel(base::File::Error status) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancel_status_ = status; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const MockBlobURLRequestContext& url_request_context() const { 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return *url_request_context_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::FileSystemContext> file_system_context_; 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<MockQuotaManager> quota_manager_; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::MessageLoopForIO loop_; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ScopedTempDir dir_; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath virtual_path_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For post-operation status. 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status_; 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status_; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 bytes_written_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool complete_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<MockBlobURLRequestContext> url_request_context_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::MockFileChangeObserver change_observer_; 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::ChangeObserverList change_observers_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::WeakPtrFactory<FileSystemOperationImplWriteTest> weak_factory_; 175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplWriteTest); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteSuccess) { 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "blob-id:success", 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "Hello, world!\n"); 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &url_request_context(), URLForPath(virtual_path_), 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, RecordWriteCallback()); 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(14, bytes_written()); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, status()); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteZero) { 19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob_id:zero", ""); 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &url_request_context(), URLForPath(virtual_path_), 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, status()); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidBlobUrl) { 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::BlobDataHandle> null_handle; 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &url_request_context(), URLForPath(virtual_path_), 21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) null_handle.Pass(), 0, RecordWriteCallback()); 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_ERROR_FAILED, status()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteInvalidFile) { 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob_id:writeinvalidfile", 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "It\'ll not be written."); 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &url_request_context(), 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteDir) { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath virtual_dir_path(FILE_PATH_LITERAL("d")); 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->CreateDirectory( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLForPath(virtual_dir_path), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true /* exclusive */, false /* recursive */, 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&AssertStatusEq, base::File::FILE_OK)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob:writedir", 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "It\'ll not be written, too."); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &url_request_context(), URLForPath(virtual_dir_path), 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kinuko): This error code is platform- or fileutil- dependent 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // right now. Make it return File::FILE_ERROR_NOT_A_FILE in every case. 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(status() == base::File::FILE_ERROR_NOT_A_FILE || 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status() == base::File::FILE_ERROR_ACCESS_DENIED || 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status() == base::File::FILE_ERROR_FAILED); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestWriteFailureByQuota) { 26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob:success", 26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "Hello, world!\n"); 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quota_manager_->SetQuota( 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kOrigin, FileSystemTypeToQuotaStorageType(kFileSystemType), 10); 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &url_request_context(), URLForPath(virtual_path_), 27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->Run(); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(10, bytes_written()); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, status()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelSuccessfulWrite) { 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob:success", 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "Hello, world!\n"); 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemOperationRunner::OperationID id = 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &url_request_context(), URLForPath(virtual_path_), 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use RunAllPendings() instead of Run() here, because we won't dispatch 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks after Cancel() is issued (so no chance to Quit) nor do we need 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to run another write cycle. 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issued Cancel() before receiving any response from Write(), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so nothing should have happen. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_ERROR_ABORT, status()); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, cancel_status()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(FileSystemOperationImplWriteTest, TestImmediateCancelFailingWrite) { 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ScopedTextBlob blob(url_request_context(), "blob:writeinvalidfile", 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "It\'ll not be written."); 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FileSystemOperationRunner::OperationID id = 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Write( 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &url_request_context(), 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) URLForPath(base::FilePath(FILE_PATH_LITERAL("nonexist"))), 31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) blob.GetBlobDataHandle(), 0, RecordWriteCallback()); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file_system_context_->operation_runner()->Cancel(id, RecordCancelCallback()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We use RunAllPendings() instead of Run() here, because we won't dispatch 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks after Cancel() is issued (so no chance to Quit) nor do we need 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to run another write cycle. 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Issued Cancel() before receiving any response from Write(), 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so nothing should have happen. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, bytes_written()); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_ERROR_ABORT, status()); 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(base::File::FILE_OK, cancel_status()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(complete()); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, change_observer()->get_and_reset_modify_file_count()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(ericu,dmikurube,kinuko): Add more tests for cancel cases. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 333