blob: 16e99a122b5185e4624d7541bb1868c4c823e1dd [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webkit/fileapi/quota_file_util.h"
#include <string>
#include "base/file_path.h"
#include "base/message_loop_proxy.h"
#include "base/platform_file.h"
#include "base/scoped_temp_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_test_helper.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_usage_cache.h"
#include "webkit/fileapi/file_util_helper.h"
namespace fileapi {
class QuotaFileUtilTest : public testing::Test {
public:
QuotaFileUtilTest() {}
void SetUp() {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
quota_file_util_.reset(QuotaFileUtil::CreateDefault());
quota_test_helper_.SetUp(data_dir_.path(), quota_file_util_.get());
base_dir_ = quota_test_helper_.GetOriginRootPath();
}
void TearDown() {
quota_test_helper_.TearDown();
}
protected:
FileSystemOperationContext* NewContext() {
return quota_test_helper_.NewOperationContext();
}
FileSystemPath Path(const std::string& file_name) {
return quota_test_helper_.CreatePath(base_dir_.AppendASCII(file_name));
}
base::PlatformFileError CreateFile(const char* file_name,
base::PlatformFile* file_handle, bool* created) {
int file_flags = base::PLATFORM_FILE_CREATE |
base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_ASYNC;
scoped_ptr<FileSystemOperationContext> context(NewContext());
return quota_file_util()->CreateOrOpen(
context.get(), Path(file_name), file_flags, file_handle, created);
}
base::PlatformFileError EnsureFileExists(
const char* file_name, bool* created) {
scoped_ptr<FileSystemOperationContext> context(NewContext());
return quota_file_util_->EnsureFileExists(
context.get(), Path(file_name), created);
}
QuotaFileUtil* quota_file_util() const {
return quota_file_util_.get();
}
const FileSystemTestOriginHelper& quota_test_helper() const {
return quota_test_helper_;
}
private:
ScopedTempDir data_dir_;
FilePath base_dir_;
FileSystemTestOriginHelper quota_test_helper_;
scoped_ptr<QuotaFileUtil> quota_file_util_;
DISALLOW_COPY_AND_ASSIGN(QuotaFileUtilTest);
};
TEST_F(QuotaFileUtilTest, CreateAndClose) {
const char *file_name = "test_file";
base::PlatformFile file_handle;
bool created;
ASSERT_EQ(base::PLATFORM_FILE_OK,
CreateFile(file_name, &file_handle, &created));
ASSERT_TRUE(created);
scoped_ptr<FileSystemOperationContext> context(NewContext());
EXPECT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->Close(context.get(), file_handle));
}
TEST_F(QuotaFileUtilTest, CopyFile) {
const char *from_file = "fromfile";
const char *obstacle_file = "obstaclefile";
const char *to_file1 = "tofile1";
const char *to_file2 = "tofile2";
bool created;
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(obstacle_file, &created));
ASSERT_TRUE(created);
scoped_ptr<FileSystemOperationContext> context;
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1020));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(obstacle_file), 1));
ASSERT_EQ(1021, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1020);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_file),
Path(to_file1)));
ASSERT_EQ(2041, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1019);
ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_file),
Path(to_file2)));
ASSERT_EQ(2041, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1019);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_file),
Path(obstacle_file)));
ASSERT_EQ(3060, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1019));
ASSERT_EQ(3059, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(-2); // quota exceeded
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_file),
Path(obstacle_file)));
ASSERT_EQ(3058, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
}
TEST_F(QuotaFileUtilTest, CopyDirectory) {
const char *from_dir = "fromdir";
const char *from_file1 = "fromdir/fromfile1";
const char *from_file2 = "fromdir/fromfile2";
const char *to_dir1 = "todir1";
const char *to_dir2 = "todir2";
bool created;
scoped_ptr<FileSystemOperationContext> context;
context.reset(NewContext());
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->CreateDirectory(context.get(),
Path(from_dir),
false, false));
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file1, &created));
ASSERT_TRUE(created);
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file2, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file1), 520));
ASSERT_EQ(520, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file2), 500));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1020);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_dir),
Path(to_dir1)));
ASSERT_EQ(2040, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1019);
EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
quota_test_helper().SameFileUtilCopy(
context.get(),
Path(from_dir),
Path(to_dir2)));
ASSERT_TRUE(2540 == quota_test_helper().GetCachedOriginUsage() ||
2560 == quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
}
TEST_F(QuotaFileUtilTest, MoveFile) {
const char *from_file = "fromfile";
const char *obstacle_file = "obstaclefile";
const char *to_file = "tofile";
bool created;
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
scoped_ptr<FileSystemOperationContext> context;
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1020));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(0);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilMove(
context.get(),
Path(from_file),
Path(to_file)));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(obstacle_file, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1020));
ASSERT_EQ(2040, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(obstacle_file), 1));
ASSERT_EQ(2041, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(0);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilMove(
context.get(),
Path(from_file),
Path(obstacle_file)));
ASSERT_EQ(2040, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 10));
ASSERT_EQ(2050, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(-1020 - 1); // quota exceeded, after
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilMove(
context.get(),
Path(from_file),
Path(obstacle_file)));
ASSERT_EQ(1030, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
}
TEST_F(QuotaFileUtilTest, MoveDirectory) {
const char *from_dir = "fromdir";
const char *from_file = "fromdir/fromfile";
const char *to_dir1 = "todir1";
const char *to_dir2 = "todir2";
bool created;
scoped_ptr<FileSystemOperationContext> context;
context.reset(NewContext());
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->CreateDirectory(context.get(),
Path(from_dir),
false, false));
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1020));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1020);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilMove(
context.get(),
Path(from_dir),
Path(to_dir1)));
ASSERT_EQ(1020, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->CreateDirectory(context.get(),
Path(from_dir),
false, false));
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(from_file, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(from_file), 1020));
ASSERT_EQ(2040, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(1019);
EXPECT_EQ(base::PLATFORM_FILE_OK,
quota_test_helper().SameFileUtilMove(
context.get(),
Path(from_dir),
Path(to_dir2)));
ASSERT_EQ(2040, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
}
TEST_F(QuotaFileUtilTest, Remove) {
const char *dir = "dir";
const char *file = "file";
const char *dfile1 = "dir/dfile1";
const char *dfile2 = "dir/dfile2";
bool created;
scoped_ptr<FileSystemOperationContext> context;
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(file, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->CreateDirectory(context.get(),
Path(dir),
false, false));
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(dfile1, &created));
ASSERT_TRUE(created);
ASSERT_EQ(base::PLATFORM_FILE_OK, EnsureFileExists(dfile2, &created));
ASSERT_TRUE(created);
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(file), 340));
ASSERT_EQ(340, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(dfile1), 1020));
ASSERT_EQ(1360, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
quota_file_util()->TruncateInternal(
context.get(), Path(dfile2), 120));
ASSERT_EQ(1480, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
FileUtilHelper::Delete(context.get(), quota_file_util(),
Path(file), false));
ASSERT_EQ(1140, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
context.reset(NewContext());
context->set_allowed_bytes_growth(QuotaFileUtil::kNoLimit);
ASSERT_EQ(base::PLATFORM_FILE_OK,
FileUtilHelper::Delete(context.get(), quota_file_util(),
Path(dir), true));
ASSERT_EQ(0, quota_test_helper().GetCachedOriginUsage());
ASSERT_EQ(quota_test_helper().ComputeCurrentOriginUsage(),
quota_test_helper().GetCachedOriginUsage());
}
} // namespace fileapi