158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file. 458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h" 658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/file_path.h" 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/test/test_file_system_context.h" 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h" 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_runner.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using fileapi::FileSystemContext; 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using fileapi::FileSystemOperationRunner; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using fileapi::FileSystemType; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using fileapi::FileSystemURL; 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void GetStatus(bool* done, 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error *status_out, 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status) { 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(*done); 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *done = true; 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *status_out = status; 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void GetCancelStatus(bool* operation_done, 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool* cancel_done, 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error *status_out, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status) { 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Cancel callback must be always called after the operation's callback. 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(*operation_done); 3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(*cancel_done); 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *cancel_done = true; 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *status_out = status; 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class FileSystemOperationRunnerTest : public testing::Test { 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected: 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunnerTest() {} 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~FileSystemOperationRunnerTest() {} 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void SetUp() OVERRIDE { 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(base_.CreateUniqueTempDir()); 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::FilePath base_dir = base_.path(); 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) file_system_context_ = 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CreateFileSystemContextForTesting(NULL, base_dir); 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void TearDown() OVERRIDE { 5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) file_system_context_ = NULL; 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemURL URL(const std::string& path) { 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return file_system_context_->CreateCrackedFileSystemURL( 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL("http://example.com"), fileapi::kFileSystemTypeTemporary, 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::FilePath::FromUTF8Unsafe(path)); 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner() { 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return file_system_context_->operation_runner(); 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::ScopedTempDir base_; 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::MessageLoop message_loop_; 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<FileSystemContext> file_system_context_; 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunnerTest); 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundError) { 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Regular NOT_FOUND error, which is called asynchronously. 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(URL("foo"), 0, 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status); 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLError) { 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Invalid URL error, which calls DidFinish synchronously. 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(FileSystemURL(), 0, 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The error call back shouldn't be fired synchronously. 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status); 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundErrorAndCancel) { 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool cancel_done = false; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Call Truncate with non-existent URL, and try to cancel it immediately 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // after that (before its callback is fired). 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner::OperationID id = 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(URL("foo"), 0, 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Cancel(id, base::Bind(&GetCancelStatus, 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &done, &cancel_done, 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &cancel_status)); 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(cancel_done); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLErrorAndCancel) { 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool cancel_done = false; 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Call Truncate with invalid URL, and try to cancel it immediately 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // after that (before its callback is fired). 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner::OperationID id = 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(FileSystemURL(), 0, 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Cancel(id, base::Bind(&GetCancelStatus, 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &done, &cancel_done, 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &cancel_status)); 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(cancel_done); 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, CancelWithInvalidId) { 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemOperationRunner::OperationID kInvalidId = -1; 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool done = true; // The operation is not running. 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool cancel_done = false; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation_runner()->Cancel(kInvalidId, base::Bind(&GetCancelStatus, 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &done, &cancel_done, 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &cancel_status)); 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 167