This source file includes following definitions.
- SetUp
- RenameCacheFilesToNewFormat
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "chrome/browser/chromeos/drive/file_cache.h"
#include <string>
#include <vector>
#include "base/callback_helpers.h"
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/files/scoped_temp_dir.h"
#include "base/md5.h"
#include "base/path_service.h"
#include "chrome/browser/chromeos/drive/drive.pb.h"
#include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
#include "chrome/browser/chromeos/drive/test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace drive {
namespace internal {
namespace {
const char kCacheFileDirectory[] = "files";
}
class FileCacheTest : public testing::Test {
protected:
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta");
cache_files_dir_ = temp_dir_.path().AppendASCII(kCacheFileDirectory);
ASSERT_TRUE(base::CreateDirectory(metadata_dir));
ASSERT_TRUE(base::CreateDirectory(cache_files_dir_));
fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
metadata_storage_.reset(new ResourceMetadataStorage(
metadata_dir,
base::MessageLoopProxy::current().get()));
ASSERT_TRUE(metadata_storage_->Initialize());
cache_.reset(new FileCache(
metadata_storage_.get(),
cache_files_dir_,
base::MessageLoopProxy::current().get(),
fake_free_disk_space_getter_.get()));
ASSERT_TRUE(cache_->Initialize());
}
static bool RenameCacheFilesToNewFormat(FileCache* cache) {
return cache->RenameCacheFilesToNewFormat();
}
content::TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir temp_dir_;
base::FilePath cache_files_dir_;
scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
metadata_storage_;
scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
scoped_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
};
TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) {
base::FilePath dir_source_root;
EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
const base::FilePath src_path =
dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png");
EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path,
FileCache::FILE_OPERATION_COPY));
const base::FilePath file_directory =
temp_dir_.path().AppendASCII(kCacheFileDirectory);
ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_bar")));
ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_baz")));
ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info;
recovered_cache_info["id_baz"].is_dirty = true;
recovered_cache_info["id_baz"].title = "baz.png";
const base::FilePath dest_directory = temp_dir_.path().AppendASCII("dest");
EXPECT_TRUE(cache_->RecoverFilesFromCacheDirectory(dest_directory,
recovered_cache_info));
EXPECT_TRUE(base::PathExists(dest_directory));
if (base::PathExists(dest_directory.AppendASCII("baz00000001.png"))) {
EXPECT_TRUE(base::ContentsEqual(
src_path,
dest_directory.AppendASCII("baz00000001.png")));
EXPECT_TRUE(base::ContentsEqual(
src_path,
dest_directory.AppendASCII("image00000002.png")));
} else {
EXPECT_TRUE(base::ContentsEqual(
src_path,
dest_directory.AppendASCII("image00000001.png")));
EXPECT_TRUE(base::ContentsEqual(
src_path,
dest_directory.AppendASCII("baz00000002.png")));
}
EXPECT_FALSE(base::PathExists(
dest_directory.AppendASCII("image00000003.png")));
}
TEST_F(FileCacheTest, Iterator) {
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
std::map<std::string, std::string> md5s;
md5s["id1"] = "md5-1";
md5s["id2"] = "md5-2";
md5s["id3"] = "md5-3";
md5s["id4"] = "md5-4";
for (std::map<std::string, std::string>::iterator it = md5s.begin();
it != md5s.end(); ++it) {
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
it->first, it->second, src_file, FileCache::FILE_OPERATION_COPY));
}
std::map<std::string, std::string> result;
scoped_ptr<FileCache::Iterator> it = cache_->GetIterator();
for (; !it->IsAtEnd(); it->Advance())
result[it->GetID()] = it->GetValue().md5();
EXPECT_EQ(md5s, result);
EXPECT_FALSE(it->HasError());
}
TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) {
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp";
ASSERT_EQ(FILE_ERROR_OK,
cache_->Store(id_tmp, md5_tmp, src_file,
FileCache::FILE_OPERATION_COPY));
base::FilePath tmp_path;
ASSERT_EQ(FILE_ERROR_OK, cache_->GetFile(id_tmp, &tmp_path));
const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned";
ASSERT_EQ(FILE_ERROR_OK,
cache_->Store(id_pinned, md5_pinned, src_file,
FileCache::FILE_OPERATION_COPY));
ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned));
base::FilePath pinned_path;
ASSERT_EQ(FILE_ERROR_OK, cache_->GetFile(id_pinned, &pinned_path));
fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
fake_free_disk_space_getter_->PushFakeValue(0);
const int64 kNeededBytes = 1;
EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
FileCacheEntry entry;
EXPECT_FALSE(cache_->GetCacheEntry(id_tmp, &entry));
EXPECT_FALSE(base::PathExists(tmp_path));
EXPECT_TRUE(cache_->GetCacheEntry(id_pinned, &entry));
EXPECT_TRUE(base::PathExists(pinned_path));
fake_free_disk_space_getter_->set_default_value(0);
EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
}
TEST_F(FileCacheTest, GetFile) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string src_contents = "test";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
src_contents));
std::string id("id1");
std::string md5(base::MD5String(src_contents));
const base::FilePath cache_file_directory =
temp_dir_.path().AppendASCII(kCacheFileDirectory);
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
FileCache::FILE_OPERATION_COPY));
base::FilePath cache_file_path;
EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
EXPECT_EQ(
cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
cache_file_path.value());
std::string contents;
EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
EXPECT_EQ(src_contents, contents);
id = "id2";
EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
FileCache::FILE_OPERATION_COPY));
EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
EXPECT_EQ(
cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
cache_file_path.value());
contents.clear();
EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
EXPECT_EQ(src_contents, contents);
}
TEST_F(FileCacheTest, Store) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string src_contents = "test";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
src_contents));
std::string id("id");
std::string md5(base::MD5String(src_contents));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
FileCacheEntry cache_entry;
EXPECT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_TRUE(cache_entry.is_present());
EXPECT_EQ(md5, cache_entry.md5());
base::FilePath cache_file_path;
EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path));
EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store(
id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"),
FileCache::FILE_OPERATION_COPY));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY));
EXPECT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_TRUE(cache_entry.is_present());
EXPECT_TRUE(cache_entry.md5().empty());
EXPECT_TRUE(cache_entry.is_dirty());
fake_free_disk_space_getter_->set_default_value(0);
EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store(
id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
}
TEST_F(FileCacheTest, PinAndUnpin) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string src_contents = "test";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
src_contents));
std::string id("id_present");
std::string md5(base::MD5String(src_contents));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
FileCacheEntry cache_entry;
EXPECT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_FALSE(cache_entry.is_pinned());
EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
EXPECT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_TRUE(cache_entry.is_pinned());
EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id));
EXPECT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_FALSE(cache_entry.is_pinned());
std::string id_non_present = "id_non_present";
EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present));
EXPECT_TRUE(cache_->GetCacheEntry(id_non_present, &cache_entry));
EXPECT_TRUE(cache_entry.is_pinned());
EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present));
EXPECT_FALSE(cache_->GetCacheEntry(id_non_present, &cache_entry));
EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent"));
}
TEST_F(FileCacheTest, MountUnmount) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string src_contents = "test";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
src_contents));
std::string id("id_present");
std::string md5(base::MD5String(src_contents));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
base::FilePath cache_file_path;
EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path));
EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id));
EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path));
EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
}
TEST_F(FileCacheTest, OpenForWrite) {
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
const std::string id = "id";
ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
FileCache::FILE_OPERATION_COPY));
EXPECT_FALSE(cache_->IsOpenedForWrite(id));
FileCacheEntry entry;
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_FALSE(entry.is_dirty());
scoped_ptr<base::ScopedClosureRunner> file_closer1;
EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1));
EXPECT_TRUE(cache_->IsOpenedForWrite(id));
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_TRUE(entry.is_dirty());
scoped_ptr<base::ScopedClosureRunner> file_closer2;
EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2));
EXPECT_TRUE(cache_->IsOpenedForWrite(id));
file_closer1.reset();
EXPECT_TRUE(cache_->IsOpenedForWrite(id));
file_closer2.reset();
EXPECT_FALSE(cache_->IsOpenedForWrite(id));
EXPECT_EQ(FILE_ERROR_NOT_FOUND,
cache_->OpenForWrite("nonexistent_id", &file_closer1));
}
TEST_F(FileCacheTest, UpdateMd5) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string contents_before = "before";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
contents_before));
std::string id("id1");
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before),
src_file_path,
FileCache::FILE_OPERATION_COPY));
scoped_ptr<base::ScopedClosureRunner> file_closer;
EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
base::FilePath cache_file_path;
EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
const std::string contents_after = "after";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(cache_file_path,
contents_after));
EXPECT_EQ(FILE_ERROR_IN_USE, cache_->UpdateMd5(id));
file_closer.reset();
FileCacheEntry entry;
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_TRUE(entry.md5().empty());
EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id));
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_EQ(base::MD5String(contents_after), entry.md5());
}
TEST_F(FileCacheTest, ClearDirty) {
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
const std::string id = "id";
ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
FileCache::FILE_OPERATION_COPY));
scoped_ptr<base::ScopedClosureRunner> file_closer;
EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
FileCacheEntry entry;
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_TRUE(entry.is_dirty());
EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id));
file_closer.reset();
EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id));
EXPECT_TRUE(cache_->GetCacheEntry(id, &entry));
EXPECT_FALSE(entry.is_dirty());
}
TEST_F(FileCacheTest, Remove) {
const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
const std::string src_contents = "test";
EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
src_contents));
std::string id("id");
std::string md5(base::MD5String(src_contents));
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
base::FilePath cache_file_path;
EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
EXPECT_FALSE(base::PathExists(cache_file_path));
}
TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) {
const base::FilePath file_directory =
temp_dir_.path().AppendASCII(kCacheFileDirectory);
ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
file_directory.AppendASCII("file:id_koo.md5"), "koo"));
ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)"));
ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
file_directory.AppendASCII("id_kyu.md5"), "kyu"));
EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
std::string contents;
EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
&contents));
EXPECT_EQ("koo", contents);
contents.clear();
EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
&contents));
EXPECT_EQ("kyu", contents);
EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
contents.clear();
EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
&contents));
EXPECT_EQ("koo", contents);
contents.clear();
EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
&contents));
EXPECT_EQ("kyu", contents);
}
TEST_F(FileCacheTest, ClearAll) {
const std::string id("pdf:1a2b");
const std::string md5("abcdef0123456789");
base::FilePath src_file;
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
ASSERT_EQ(FILE_ERROR_OK,
cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
FileCacheEntry cache_entry;
ASSERT_TRUE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_TRUE(cache_->ClearAll());
EXPECT_FALSE(cache_->GetCacheEntry(id, &cache_entry));
EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_));
}
}
}