diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-24 06:43:54 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-24 06:43:54 +0000 |
commit | 03616ddad3438ddde91cbc2c405444346fb341f3 (patch) | |
tree | a066572f84529202cb6a18698be0976aa4a9f259 /webkit | |
parent | 8280427e3d67fd90c0d2744ed59993ecfb705082 (diff) | |
download | chromium_src-03616ddad3438ddde91cbc2c405444346fb341f3.zip chromium_src-03616ddad3438ddde91cbc2c405444346fb341f3.tar.gz chromium_src-03616ddad3438ddde91cbc2c405444346fb341f3.tar.bz2 |
Notify read access to the QuotaManager in FileSystemOperation
BUG=none
TEST=FileSystemOperationTest.*
Review URL: http://codereview.chromium.org/7054012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86400 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/fileapi/file_system_operation.cc | 17 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation_unittest.cc | 180 | ||||
-rw-r--r-- | webkit/fileapi/file_system_test_helper.h | 5 |
3 files changed, 153 insertions, 49 deletions
diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc index 9692cb3..e994f21 100644 --- a/webkit/fileapi/file_system_operation.cc +++ b/webkit/fileapi/file_system_operation.cc @@ -13,6 +13,7 @@ #include "webkit/fileapi/file_system_file_util_proxy.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_path_manager.h" +#include "webkit/fileapi/file_system_quota_util.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/fileapi/file_system_util.h" #include "webkit/fileapi/file_writer_delegate.h" @@ -36,9 +37,6 @@ FileSystemOperation::FileSystemOperation( #ifndef NDEBUG pending_operation_ = kOperationNone; #endif - // TODO(dmikurube): Read and set available bytes from the Quota Manager. - file_system_operation_context_.set_allowed_bytes_growth( - QuotaFileUtil::kNoLimit); } FileSystemOperation::~FileSystemOperation() { @@ -656,8 +654,9 @@ void FileSystemOperation::DidEnsureFileExistsExclusive( if (rv == base::PLATFORM_FILE_OK && !created) { dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_EXISTS); delete this; - } else + } else { DidFinishFileOperation(rv); + } } void FileSystemOperation::DidEnsureFileExistsNonExclusive( @@ -818,6 +817,16 @@ bool FileSystemOperation::VerifyFileSystemPathForRead( file_system_context()->path_manager()->GetFileSystemFileUtil(*type); DCHECK(*file_system_file_util); + // We notify this read access whether the read access succeeds or not. + // This must be ok since this is used to let the QM's eviction logic know + // someone is interested in reading the origin data and therefore to indicate + // that evicting this origin may not be a good idea. + file_system_context()->GetQuotaUtil(*type)-> + NotifyOriginWasAccessedOnIOThread( + file_system_context()->quota_manager_proxy(), + *origin_url, + *type); + return true; } diff --git a/webkit/fileapi/file_system_operation_unittest.cc b/webkit/fileapi/file_system_operation_unittest.cc index 3e349d6..9e4844d 100644 --- a/webkit/fileapi/file_system_operation_unittest.cc +++ b/webkit/fileapi/file_system_operation_unittest.cc @@ -9,59 +9,121 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/scoped_temp_dir.h" -#include "base/sys_string_conversions.h" -#include "base/utf_string_conversions.h" +#include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/fileapi/file_system_callback_dispatcher.h" #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_file_util.h" #include "webkit/fileapi/file_system_mount_point_provider.h" #include "webkit/fileapi/file_system_operation.h" +#include "webkit/fileapi/file_system_quota_util.h" #include "webkit/fileapi/file_system_test_helper.h" #include "webkit/fileapi/file_system_util.h" #include "webkit/fileapi/local_file_system_file_util.h" #include "webkit/fileapi/quota_file_util.h" #include "webkit/quota/quota_manager.h" +using quota::QuotaClient; using quota::QuotaManager; +using quota::QuotaManagerProxy; +using quota::StorageType; namespace fileapi { -const int kFileOperationStatusNotSet = 1; - namespace { +const int kFileOperationStatusNotSet = 1; + class MockQuotaManager : public QuotaManager { public: - MockQuotaManager(const FilePath& base_dir) - : QuotaManager(false /* is_incognito */, base_dir, - base::MessageLoopProxy::CreateForCurrentThread(), - base::MessageLoopProxy::CreateForCurrentThread()), - usage_(0), - quota_(QuotaFileUtil::kNoLimit) {} - - virtual void GetUsageAndQuota(const GURL& origin, quota::StorageType type, - GetUsageAndQuotaCallback* callback) { + MockQuotaManager(const FilePath& base_dir, + const GURL& origin, + StorageType type) + : QuotaManager(false /* is_incognito */, base_dir, + base::MessageLoopProxy::CreateForCurrentThread(), + base::MessageLoopProxy::CreateForCurrentThread()), + origin_(origin), + type_(type), + usage_(0), + quota_(QuotaFileUtil::kNoLimit), + accessed_(0) {} + + virtual void GetUsageAndQuota( + const GURL& origin, quota::StorageType type, + GetUsageAndQuotaCallback* callback) { + EXPECT_EQ(origin_, origin); + EXPECT_EQ(type_, type); callback->Run(quota::kQuotaStatusOk, usage_, quota_); delete callback; } - void set_usage(int64 usage) { usage_ = usage; } - void set_quota(int64 quota) { quota_ = quota; } - private: + friend class MockQuotaManagerProxy; + void SetQuota(const GURL& origin, StorageType type, int64 quota) { + EXPECT_EQ(origin_, origin); + EXPECT_EQ(type_, type); + quota_ = quota; + } + + void RecordStorageAccessed(const GURL& origin, StorageType type) { + EXPECT_EQ(origin_, origin); + EXPECT_EQ(type_, type); + ++accessed_; + } + + void UpdateUsage(const GURL& origin, StorageType type, int64 delta) { + EXPECT_EQ(origin_, origin); + EXPECT_EQ(type_, type); + usage_ += delta; + } + + const GURL& origin_; + const StorageType type_; int64 usage_; int64 quota_; + int accessed_; +}; + +class MockQuotaManagerProxy : public QuotaManagerProxy { + public: + explicit MockQuotaManagerProxy(QuotaManager* quota_manager) + : QuotaManagerProxy(quota_manager, + base::MessageLoopProxy::CreateForCurrentThread()) {} + + // We don't mock them. + virtual void RegisterClient(QuotaClient* client) OVERRIDE {} + virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {} + virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {} + + virtual void NotifyStorageAccessed(QuotaClient::ID client_id, + const GURL& origin, + StorageType type) OVERRIDE { + mock_manager()->RecordStorageAccessed(origin, type); + } + + virtual void NotifyStorageModified(QuotaClient::ID client_id, + const GURL& origin, + StorageType type, + int64 delta) OVERRIDE { + mock_manager()->UpdateUsage(origin, type, delta); + } + + int storage_accessed_count() const { + return mock_manager()->accessed_; + } + + void SetQuota(const GURL& origin, StorageType type, int64 quota) { + mock_manager()->SetQuota(origin, type, quota); + } + + private: + MockQuotaManager* mock_manager() const { + return static_cast<MockQuotaManager*>(quota_manager()); + } }; -FilePath UTF8ToFilePath(const std::string& str) { - FilePath::StringType result; -#if defined(OS_POSIX) - result = base::SysWideToNativeMB(UTF8ToWide(str)); -#elif defined(OS_WIN) - result = UTF8ToUTF16(str); -#endif - return FilePath(result); +FilePath ASCIIToFilePath(const std::string& str) { + return FilePath().AppendASCII(str); } } // namespace (anonymous) @@ -77,8 +139,6 @@ class FileSystemOperationTest : public testing::Test { FileSystemOperation* operation(); - void set_local_path(const FilePath& path) { local_path_ = path; } - const FilePath& local_path() const { return local_path_; } void set_status(int status) { status_ = status; } int status() const { return status_; } void set_info(const base::PlatformFileInfo& info) { info_ = info; } @@ -99,29 +159,29 @@ class FileSystemOperationTest : public testing::Test { // Common temp base for nondestructive uses. ScopedTempDir base_; - MockQuotaManager* quota_manager() { - return static_cast<MockQuotaManager*>(quota_manager_.get()); + MockQuotaManagerProxy* quota_manager_proxy() { + return static_cast<MockQuotaManagerProxy*>(quota_manager_proxy_.get()); } GURL URLForPath(const FilePath& path) const { return test_helper_.GetURLForPath(path); } - FilePath PlatformPath(FilePath virtual_path) { + FilePath PlatformPath(const FilePath& virtual_path) { return test_helper_.GetLocalPath(virtual_path); } - bool VirtualFileExists(FilePath virtual_path) { + bool VirtualFileExists(const FilePath& virtual_path) { return file_util::PathExists(PlatformPath(virtual_path)) && !file_util::DirectoryExists(PlatformPath(virtual_path)); } - bool VirtualDirectoryExists(FilePath virtual_path) { + bool VirtualDirectoryExists(const FilePath& virtual_path) { return file_util::DirectoryExists(PlatformPath(virtual_path)); } FilePath CreateVirtualDirectory(const char* virtual_path_string) { - FilePath virtual_path(UTF8ToFilePath(virtual_path_string)); + FilePath virtual_path(ASCIIToFilePath(virtual_path_string)); file_util::CreateDirectory(PlatformPath(virtual_path)); return virtual_path; } @@ -164,11 +224,11 @@ class FileSystemOperationTest : public testing::Test { int status_; base::PlatformFileInfo info_; FilePath path_; - FilePath local_path_; std::vector<base::FileUtilProxy::Entry> entries_; private: scoped_refptr<QuotaManager> quota_manager_; + scoped_refptr<QuotaManagerProxy> quota_manager_proxy_; DISALLOW_COPY_AND_ASSIGN(FileSystemOperationTest); }; @@ -176,7 +236,7 @@ namespace { class MockDispatcher : public FileSystemCallbackDispatcher { public: - MockDispatcher(FileSystemOperationTest* test) : test_(test) { } + explicit MockDispatcher(FileSystemOperationTest* test) : test_(test) { } virtual void DidFail(base::PlatformFileError status) { test_->set_status(status); @@ -216,16 +276,19 @@ class MockDispatcher : public FileSystemCallbackDispatcher { void FileSystemOperationTest::SetUp() { FilePath base_dir = base_.path().AppendASCII("filesystem"); - quota_manager_ = new MockQuotaManager(base_dir); + quota_manager_ = new MockQuotaManager( + base_dir, test_helper_.origin(), test_helper_.storage_type()); + quota_manager_proxy_ = new MockQuotaManagerProxy(quota_manager_.get()); test_helper_.SetUp(base_dir, false /* incognito */, false /* unlimited quota */, - quota_manager_->proxy(), + quota_manager_proxy_.get(), LocalFileSystemFileUtil::GetInstance()); } void FileSystemOperationTest::TearDown() { quota_manager_ = NULL; + quota_manager_proxy_ = NULL; test_helper_.TearDown(); } @@ -303,6 +366,10 @@ TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualFileExists(dest_file_path)); + + // Move is considered 'write' access (for both side), and won't be counted + // as read access. + EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndNew) { @@ -433,7 +500,9 @@ TEST_F(FileSystemOperationTest, TestCopyFailureByQuota) { FilePath dest_dir_path(CreateVirtualTemporaryDir()); FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile"))); - quota_manager()->set_quota(11); + quota_manager_proxy()->SetQuota(test_helper_.origin(), + test_helper_.storage_type(), + 11); operation()->Truncate(URLForPath(src_file_path), 6); MessageLoop::current()->RunAllPending(); @@ -442,8 +511,6 @@ TEST_F(FileSystemOperationTest, TestCopyFailureByQuota) { EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(src_file_path), &info)); EXPECT_EQ(6, info.size); - quota_manager()->set_usage(6); - operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path)); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); @@ -460,6 +527,7 @@ TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualFileExists(dest_file_path)); + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndNew) { @@ -472,6 +540,7 @@ TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndNew) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualFileExists(dest_file_path)); + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) { @@ -486,6 +555,7 @@ TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) { EXPECT_TRUE(VirtualDirectoryExists(dest_dir_path)); EXPECT_FALSE(VirtualDirectoryExists( dest_dir_path.Append(src_dir_path.BaseName()))); + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndNew) { @@ -498,6 +568,7 @@ TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndNew) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualDirectoryExists(dest_child_dir_path)); + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirRecursive) { @@ -516,6 +587,7 @@ TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirRecursive) { EXPECT_TRUE(VirtualFileExists(dest_dir_path.Append( child_dir_path.BaseName()).Append( grandchild_file_path.BaseName()))); + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestCreateFileFailure) { @@ -563,7 +635,8 @@ TEST_F(FileSystemOperationTest, FILE_PATH_LITERAL("DirDoesntExist"))); FilePath nonexisting_file_path(nonexisting_path.Append( FILE_PATH_LITERAL("FileDoesntExist"))); - operation()->CreateDirectory(URLForPath(nonexisting_file_path), false, false); + operation()->CreateDirectory( + URLForPath(nonexisting_file_path), false, false); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status()); } @@ -595,7 +668,8 @@ TEST_F(FileSystemOperationTest, TestCreateDirSuccess) { // Dir doesn't exist. FilePath nonexisting_dir_path(FilePath( FILE_PATH_LITERAL("nonexistingdir"))); - operation()->CreateDirectory(URLForPath(nonexisting_dir_path), false, false); + operation()->CreateDirectory( + URLForPath(nonexisting_dir_path), false, false); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualDirectoryExists(nonexisting_dir_path)); @@ -606,7 +680,8 @@ TEST_F(FileSystemOperationTest, TestCreateDirSuccessExclusive) { FilePath nonexisting_dir_path(FilePath( FILE_PATH_LITERAL("nonexistingdir"))); - operation()->CreateDirectory(URLForPath(nonexisting_dir_path), true, false); + operation()->CreateDirectory( + URLForPath(nonexisting_dir_path), true, false); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(VirtualDirectoryExists(nonexisting_dir_path)); @@ -631,27 +706,34 @@ TEST_F(FileSystemOperationTest, TestExistsAndMetadataFailure) { TEST_F(FileSystemOperationTest, TestExistsAndMetadataSuccess) { FilePath dir_path(CreateVirtualTemporaryDir()); + int read_access = 0; operation()->DirectoryExists(URLForPath(dir_path)); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); + ++read_access; operation()->GetMetadata(URLForPath(dir_path)); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_TRUE(info().is_directory); EXPECT_EQ(PlatformPath(dir_path), path()); + ++read_access; FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path)); operation()->FileExists(URLForPath(file_path)); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); + ++read_access; operation()->GetMetadata(URLForPath(file_path)); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_FALSE(info().is_directory); EXPECT_EQ(PlatformPath(file_path), path()); + ++read_access; + + EXPECT_EQ(read_access, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestTypeMismatchErrors) { @@ -709,6 +791,7 @@ TEST_F(FileSystemOperationTest, TestReadDirSuccess) { entries()[i].name); } } + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestRemoveFailure) { @@ -761,6 +844,9 @@ TEST_F(FileSystemOperationTest, TestRemoveSuccess) { MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_OK, status()); EXPECT_FALSE(VirtualDirectoryExists(parent_dir_path)); + + // Remove is not a 'read' access. + EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestTruncate) { @@ -813,6 +899,10 @@ TEST_F(FileSystemOperationTest, TestTruncate) { EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length)); for (int i = 0; i < length; ++i) EXPECT_EQ(test_data[i], data[i]); + + // Truncate is not a 'read' access. (Here expected access count is 1 + // since we made 1 read access for GetMetadata.) + EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count()); } TEST_F(FileSystemOperationTest, TestTruncateFailureByQuota) { @@ -821,7 +911,9 @@ TEST_F(FileSystemOperationTest, TestTruncateFailureByQuota) { FilePath dir_path(CreateVirtualTemporaryDir()); FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path)); - quota_manager()->set_quota(10); + quota_manager_proxy()->SetQuota(test_helper_.origin(), + test_helper_.storage_type(), + 10); operation()->Truncate(URLForPath(file_path), 10); MessageLoop::current()->RunAllPending(); @@ -830,8 +922,6 @@ TEST_F(FileSystemOperationTest, TestTruncateFailureByQuota) { EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info)); EXPECT_EQ(10, info.size); - quota_manager()->set_usage(10); - operation()->Truncate(URLForPath(file_path), 11); MessageLoop::current()->RunAllPending(); EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status()); diff --git a/webkit/fileapi/file_system_test_helper.h b/webkit/fileapi/file_system_test_helper.h index 53deba2..2cf8ebb 100644 --- a/webkit/fileapi/file_system_test_helper.h +++ b/webkit/fileapi/file_system_test_helper.h @@ -13,6 +13,8 @@ #include "base/memory/scoped_ptr.h" #include "googleurl/src/gurl.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/file_system_util.h" +#include "webkit/quota/quota_types.h" namespace quota { class QuotaManagerProxy; @@ -61,6 +63,9 @@ class FileSystemTestOriginHelper { const GURL& origin() const { return origin_; } FileSystemType type() const { return type_; } + quota::StorageType storage_type() const { + return FileSystemTypeToQuotaStorageType(type_); + } FileSystemFileUtil* file_util() { return file_util_; } private: |