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" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemContext; 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOperationRunner; 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemType; 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::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( 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GURL("http://example.com"), 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::kFileSystemTypeTemporary, 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::FilePath::FromUTF8Unsafe(path)); 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner() { 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return file_system_context_->operation_runner(); 6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::ScopedTempDir base_; 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::MessageLoop message_loop_; 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<FileSystemContext> file_system_context_; 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FileSystemOperationRunnerTest); 7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundError) { 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Regular NOT_FOUND error, which is called asynchronously. 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(URL("foo"), 0, 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status); 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLError) { 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Invalid URL error, which calls DidFinish synchronously. 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(FileSystemURL(), 0, 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The error call back shouldn't be fired synchronously. 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status); 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, NotFoundErrorAndCancel) { 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool cancel_done = false; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Call Truncate with non-existent URL, and try to cancel it immediately 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // after that (before its callback is fired). 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner::OperationID id = 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(URL("foo"), 0, 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Cancel(id, base::Bind(&GetCancelStatus, 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &done, &cancel_done, 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &cancel_status)); 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(cancel_done); 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND, status); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, InvalidURLErrorAndCancel) { 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool done = false; 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool cancel_done = false; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error status = base::File::FILE_ERROR_FAILED; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Call Truncate with invalid URL, and try to cancel it immediately 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // after that (before its callback is fired). 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner::OperationID id = 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Truncate(FileSystemURL(), 0, 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&GetStatus, &done, &status)); 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner()->Cancel(id, base::Bind(&GetCancelStatus, 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &done, &cancel_done, 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &cancel_status)); 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(done); 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_FALSE(cancel_done); 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(done); 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_URL, status); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(FileSystemOperationRunnerTest, CancelWithInvalidId) { 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemOperationRunner::OperationID kInvalidId = -1; 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool done = true; // The operation is not running. 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool cancel_done = false; 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error cancel_status = base::File::FILE_ERROR_FAILED; 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation_runner()->Cancel(kInvalidId, base::Bind(&GetCancelStatus, 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &done, &cancel_done, 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &cancel_status)); 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE(cancel_done); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, cancel_status); 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 168