Chromium Code Reviews| Index: components/drive/chromeos/file_cache_unittest.cc |
| diff --git a/components/drive/chromeos/file_cache_unittest.cc b/components/drive/chromeos/file_cache_unittest.cc |
| index 7fd7b5d489e9e1bab9479072908bda66f27ee8fe..43a431a365e3b8dfbba9751c4c196e48acc7a194 100644 |
| --- a/components/drive/chromeos/file_cache_unittest.cc |
| +++ b/components/drive/chromeos/file_cache_unittest.cc |
| @@ -4,10 +4,14 @@ |
| #include "components/drive/chromeos/file_cache.h" |
| +#include <fcntl.h> |
| +#include <linux/fs.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| +#include <sys/ioctl.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| +#include <sys/xattr.h> |
| #include <unistd.h> |
| #include <string> |
| @@ -20,6 +24,7 @@ |
| #include "base/md5.h" |
| #include "base/path_service.h" |
| #include "base/single_thread_task_runner.h" |
| +#include "base/stl_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/thread_task_runner_handle.h" |
| #include "base/time/time.h" |
| @@ -38,18 +43,16 @@ namespace { |
| const base::FilePath::CharType kCacheFileDirectory[] = |
| FILE_PATH_LITERAL("files"); |
| -const base::FilePath::CharType kNewCacheFileDirectory[] = |
| - FILE_PATH_LITERAL("blobs"); |
| -const base::FilePath::CharType kLinkDirectory[] = FILE_PATH_LITERAL("links"); |
| const int kTemporaryFileSizeInBytes = 10; |
| -int GetNumberOfLinks(const base::FilePath& file_path) { |
| - struct stat result; |
| - if (stat(file_path.AsUTF8Unsafe().c_str(), &result) != 0) { |
| - return -1; |
| - } |
| - return result.st_nlink; |
| +int64_t Lsattr(const base::FilePath& file_path) { |
|
hashimoto
2016/05/02 08:29:20
Please give this function a more readable name.
B
oka
2016/05/09 14:27:41
Done.
|
| + int fd = open(file_path.value().c_str(), O_RDONLY); |
|
hashimoto
2016/05/02 08:29:21
HANDLE_EINTR should be used.
oka
2016/05/09 14:27:41
Removed.
|
| + if (fd < 0) return -1; |
| + int64_t flags = 0; |
| + if (ioctl(fd, FS_IOC_GETFLAGS, &flags) < 0) return -1; |
|
hashimoto
2016/05/02 08:29:20
Please use base::File.
This line leaks fd.
oka
2016/05/09 14:27:41
Done.
|
| + close(fd); |
| + return flags; |
| } |
| } // namespace |
| @@ -75,7 +78,6 @@ class FileCacheTest : public testing::Test { |
| cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_, |
| base::ThreadTaskRunnerHandle::Get().get(), |
| fake_free_disk_space_getter_.get())); |
| - ASSERT_TRUE(cache_->Initialize()); |
| } |
| static bool RenameCacheFilesToNewFormat(FileCache* cache) { |
| @@ -114,6 +116,7 @@ class FileCacheTest : public testing::Test { |
| }; |
| TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) { |
| + ASSERT_TRUE(cache_->Initialize()); |
|
hashimoto
2016/05/02 08:29:20
Instead of calling Initialize() everywhere, how ab
oka
2016/05/09 14:27:40
Done. Given we run migration everytime, moving thi
|
| base::FilePath dir_source_root; |
| EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root)); |
| const base::FilePath src_path = |
| @@ -166,6 +169,7 @@ TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) { |
| } |
| TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| base::FilePath src_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| @@ -205,6 +209,7 @@ TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) { |
| } |
| TEST_F(FileCacheTest, EvictDriveCacheInLRU) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| // Create temporary file. |
| base::FilePath src_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| @@ -265,6 +270,7 @@ TEST_F(FileCacheTest, EvictDriveCacheInLRU) { |
| // Test case for deleting invalid cache files which don't have corresponding |
| // metadata. |
| TEST_F(FileCacheTest, EvictInvalidCacheFile) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| base::FilePath src_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| @@ -303,6 +309,7 @@ TEST_F(FileCacheTest, EvictInvalidCacheFile) { |
| } |
| TEST_F(FileCacheTest, TooManyCacheFiles) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| const size_t kMaxNumOfEvictedCacheFiles = 50; |
| cache_->SetMaxNumOfEvictedCacheFilesForTest(kMaxNumOfEvictedCacheFiles); |
| @@ -346,6 +353,7 @@ TEST_F(FileCacheTest, TooManyCacheFiles) { |
| } |
| TEST_F(FileCacheTest, GetFile) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| 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, |
| @@ -400,6 +408,7 @@ TEST_F(FileCacheTest, GetFile) { |
| } |
| TEST_F(FileCacheTest, Store) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| 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, |
| @@ -422,6 +431,11 @@ TEST_F(FileCacheTest, Store) { |
| EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); |
| EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path)); |
| + base::FilePath dest_file_path = cache_files_dir_.AppendASCII(id); |
|
hashimoto
2016/05/02 08:29:20
This path construction is an internal logic of Fil
oka
2016/05/09 14:27:40
Done.
|
| + int64_t flags = Lsattr(dest_file_path); |
| + EXPECT_GE(flags, 0); |
|
hashimoto
2016/05/02 08:29:21
What is the point of this check?
You want to see i
oka
2016/05/09 14:27:40
Done. Used ExpectIsRemovable.
|
| + EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); |
| + |
| // Store a non-existent file. |
| EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store( |
| id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"), |
| @@ -435,6 +449,8 @@ TEST_F(FileCacheTest, Store) { |
| EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); |
| EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| + flags &= ~FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file_path), flags); |
| // No free space available. |
| fake_free_disk_space_getter_->set_default_value(0); |
| @@ -444,6 +460,7 @@ TEST_F(FileCacheTest, Store) { |
| } |
| TEST_F(FileCacheTest, PinAndUnpin) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| 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, |
| @@ -458,20 +475,28 @@ TEST_F(FileCacheTest, PinAndUnpin) { |
| EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| + const base::FilePath dest_file_path = cache_files_dir_.AppendASCII(id); |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); |
| + int64_t flags = Lsattr(dest_file_path); |
| + ASSERT_GE(flags, 0); |
| + EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); |
| // Pin the existing file. |
| EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); |
| + flags &= ~FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file_path),flags); |
| // Unpin the file. |
| EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id)); |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); |
| + flags |= FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file_path), flags); |
| // Pin a non-present file. |
| std::string id_non_present = "id_non_present"; |
| @@ -494,6 +519,7 @@ TEST_F(FileCacheTest, PinAndUnpin) { |
| } |
| TEST_F(FileCacheTest, MountUnmount) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| 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, |
| @@ -523,6 +549,7 @@ TEST_F(FileCacheTest, MountUnmount) { |
| } |
| TEST_F(FileCacheTest, OpenForWrite) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| // Prepare a file. |
| base::FilePath src_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| @@ -540,6 +567,11 @@ TEST_F(FileCacheTest, OpenForWrite) { |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); |
| + const base::FilePath dest_file = cache_files_dir_.AppendASCII(id); |
| + int64_t flags = Lsattr(dest_file); |
| + ASSERT_GE(flags, 0); |
| + EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); |
| + |
| // Open (1). |
| std::unique_ptr<base::ScopedClosureRunner> file_closer1; |
| EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1)); |
| @@ -548,6 +580,8 @@ TEST_F(FileCacheTest, OpenForWrite) { |
| // Entry is dirty. |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| + flags &= ~FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file), flags); |
| // Open (2). |
| std::unique_ptr<base::ScopedClosureRunner> file_closer2; |
| @@ -574,6 +608,7 @@ TEST_F(FileCacheTest, OpenForWrite) { |
| } |
| TEST_F(FileCacheTest, UpdateMd5) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| // Store test data. |
| const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| const std::string contents_before = "before"; |
| @@ -615,6 +650,7 @@ TEST_F(FileCacheTest, UpdateMd5) { |
| } |
| TEST_F(FileCacheTest, ClearDirty) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| // Prepare a file. |
| base::FilePath src_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| @@ -626,6 +662,12 @@ TEST_F(FileCacheTest, ClearDirty) { |
| ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, |
| FileCache::FILE_OPERATION_COPY)); |
| + const base::FilePath dest_file = cache_files_dir_.AppendASCII(id); |
| + |
| + int64_t flags = Lsattr(dest_file); |
| + ASSERT_GE(flags, 0); |
| + EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); |
| + |
| // Open the file. |
| std::unique_ptr<base::ScopedClosureRunner> file_closer; |
| EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); |
| @@ -633,9 +675,12 @@ TEST_F(FileCacheTest, ClearDirty) { |
| // Entry is dirty. |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| + flags &= ~FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file), flags); |
| // Cannot clear the dirty bit of an opened entry. |
| EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id)); |
| + EXPECT_EQ(Lsattr(dest_file), flags); |
| // Close the file and clear the dirty bit. |
| file_closer.reset(); |
| @@ -645,9 +690,12 @@ TEST_F(FileCacheTest, ClearDirty) { |
| // Entry is not dirty. |
| EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); |
| + flags |= FS_NODUMP_FL; |
| + EXPECT_EQ(Lsattr(dest_file), flags); |
| } |
| TEST_F(FileCacheTest, Remove) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| 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, |
| @@ -673,6 +721,7 @@ TEST_F(FileCacheTest, Remove) { |
| } |
| TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| const base::FilePath file_directory = |
| temp_dir_.path().Append(kCacheFileDirectory); |
| @@ -711,159 +760,125 @@ TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) { |
| EXPECT_EQ("kyu", contents); |
| } |
| -// Test for migrating cache files from files to blobs. |
| +// Test for migrating cache files resolving inconsistency in metadata. |
| TEST_F(FileCacheTest, MigrateCacheFiles) { |
| // Create test files and metadata. |
| base::FilePath temp_file; |
| ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); |
| - const base::FilePath old_cache_dir = |
| - temp_dir_.path().Append(kCacheFileDirectory); |
| - const base::FilePath new_cache_dir = |
| - temp_dir_.path().Append(kNewCacheFileDirectory); |
| - const base::FilePath link_dir = temp_dir_.path().Append(kLinkDirectory); |
| - ASSERT_TRUE(base::CreateDirectory(old_cache_dir)); |
| - ASSERT_TRUE(base::CreateDirectory(new_cache_dir)); |
| - ASSERT_TRUE(base::CreateDirectory(link_dir)); |
| - |
| - // Entry A: cache file in old cache directory with metadata. |
| + // Entry A: pinned cache file. |
| const std::string id_a = "id_a"; |
| ResourceEntry entry_a; |
| entry_a.set_local_id(id_a); |
| - entry_a.mutable_file_specific_info()->mutable_cache_state()->set_is_present( |
| - true); |
| + FileCacheEntry* file_cache_entry_a = |
| + entry_a.mutable_file_specific_info()->mutable_cache_state(); |
| + file_cache_entry_a->set_is_present(true); |
| + file_cache_entry_a->set_is_pinned(true); |
| + file_cache_entry_a->set_is_dirty(false); |
| ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); |
| - const base::FilePath old_file_path_a = old_cache_dir.AppendASCII(id_a); |
| - const base::FilePath new_file_path_a = new_cache_dir.AppendASCII(id_a); |
| - ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_a)); |
| + const base::FilePath file_path_a = cache_files_dir_.AppendASCII(id_a); |
| + ASSERT_TRUE(base::CopyFile(temp_file, file_path_a)); |
| - // Entry B: cache file in old cache directory without metadata. |
| + // Entry B: dirty cache file. |
| const std::string id_b = "id_b"; |
| - const base::FilePath old_file_path_b = old_cache_dir.AppendASCII(id_b); |
| - ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_b)); |
| - |
| - // Entry C: already migrated cache file. |
| + ResourceEntry entry_b; |
| + entry_b.set_local_id(id_b); |
| + FileCacheEntry* file_cache_entry_b = |
| + entry_b.mutable_file_specific_info()->mutable_cache_state(); |
| + file_cache_entry_b->set_is_present(true); |
| + file_cache_entry_b->set_is_pinned(false); |
| + file_cache_entry_b->set_is_dirty(true); |
| + ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_b)); |
| + const base::FilePath file_path_b = cache_files_dir_.AppendASCII(id_b); |
| + ASSERT_TRUE(base::CopyFile(temp_file, file_path_b)); |
| + |
| + // Entry C: not pinned nor dirty cache file. |
| const std::string id_c = "id_c"; |
| ResourceEntry entry_c; |
| entry_c.set_local_id(id_c); |
| - entry_c.mutable_file_specific_info()->mutable_cache_state()->set_is_present( |
| - true); |
| + FileCacheEntry* file_cache_entry_c = |
| + entry_c.mutable_file_specific_info()->mutable_cache_state(); |
| + file_cache_entry_c->set_is_present(true); |
| + file_cache_entry_c->set_is_pinned(false); |
| + file_cache_entry_c->set_is_dirty(false); |
| ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c)); |
| - const base::FilePath new_file_path_c = new_cache_dir.AppendASCII(id_c); |
| - ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_c)); |
| + const base::FilePath file_path_c = cache_files_dir_.AppendASCII(id_c); |
| + ASSERT_TRUE(base::CopyFile(temp_file, file_path_c)); |
| - // Entry D: metadata entry without cache file. |
| + // Entry D: pinned cache file somehow having removable flag. |
| const std::string id_d = "id_d"; |
| ResourceEntry entry_d; |
| entry_d.set_local_id(id_d); |
| - entry_d.mutable_file_specific_info()->mutable_cache_state()->set_is_present( |
| - true); |
| + FileCacheEntry* file_cache_entry_d = |
| + entry_d.mutable_file_specific_info()->mutable_cache_state(); |
| + file_cache_entry_d->set_is_present(true); |
| + file_cache_entry_d->set_is_pinned(true); |
| + file_cache_entry_d->set_is_dirty(false); |
| ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); |
| - |
| - // Entry E: pinned cache file. |
| + const base::FilePath file_path_d = cache_files_dir_.AppendASCII(id_d); |
| + ASSERT_TRUE(base::CopyFile(temp_file, file_path_d)); |
| + |
| + // Set removable flag. |
|
hashimoto
2016/05/02 08:29:21
How about reusing the function in file_cache.cc?
(
oka
2016/05/09 14:27:41
This is the only usage of FS_IOC_SETFLAGS in this
|
| + int fd; |
| + ASSERT_GE(fd = open(file_path_d.value().c_str(), O_RDONLY), 0); |
| + int64_t flags; |
| + ASSERT_EQ(ioctl(fd, FS_IOC_GETFLAGS, &flags), 0); |
|
hashimoto
2016/05/02 08:29:20
Why aren't you using the lsattr function above?
oka
2016/05/09 14:27:41
Done.
|
| + flags |= FS_NODUMP_FL; |
| + ASSERT_EQ(ioctl(fd, FS_IOC_SETFLAGS, &flags), 0); |
| + close(fd); |
|
hashimoto
2016/05/02 08:29:21
Please use base::File (or base::ScopedFD) instead
oka
2016/05/09 14:27:41
Done.
|
| + |
| + // Entry E: there is no file; removed by cryptohome. |
| const std::string id_e = "id_e"; |
| ResourceEntry entry_e; |
| entry_e.set_local_id(id_e); |
| FileCacheEntry* file_cache_entry_e = |
| entry_e.mutable_file_specific_info()->mutable_cache_state(); |
| file_cache_entry_e->set_is_present(true); |
| - file_cache_entry_e->set_is_pinned(true); |
| + file_cache_entry_e->set_is_pinned(false); |
| file_cache_entry_e->set_is_dirty(false); |
| ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); |
| - const base::FilePath old_file_path_e = old_cache_dir.AppendASCII(id_e); |
| - const base::FilePath new_file_path_e = new_cache_dir.AppendASCII(id_e); |
| - const base::FilePath link_path_e = link_dir.AppendASCII(id_e); |
| - ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_e)); |
| - |
| - // Entry F: dirty cache file. |
| - const std::string id_f = "id_f"; |
| - ResourceEntry entry_f; |
| - entry_f.set_local_id(id_f); |
| - FileCacheEntry* file_cache_entry_f = |
| - entry_f.mutable_file_specific_info()->mutable_cache_state(); |
| - file_cache_entry_f->set_is_present(true); |
| - file_cache_entry_f->set_is_pinned(false); |
| - file_cache_entry_f->set_is_dirty(true); |
| - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f)); |
| - const base::FilePath old_file_path_f = old_cache_dir.AppendASCII(id_f); |
| - const base::FilePath new_file_path_f = new_cache_dir.AppendASCII(id_f); |
| - const base::FilePath link_path_f = link_dir.AppendASCII(id_f); |
| - ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_f)); |
| - |
| - // Entry G: partially migrated pinned cache file. |
| - const std::string id_g = "id_g"; |
| - ResourceEntry entry_g; |
| - entry_g.set_local_id(id_g); |
| - FileCacheEntry* file_cache_entry_g = |
| - entry_g.mutable_file_specific_info()->mutable_cache_state(); |
| - file_cache_entry_g->set_is_present(true); |
| - file_cache_entry_g->set_is_pinned(true); |
| - file_cache_entry_g->set_is_dirty(false); |
| - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_g)); |
| - const base::FilePath old_file_path_g = old_cache_dir.AppendASCII(id_g); |
| - const base::FilePath new_file_path_g = new_cache_dir.AppendASCII(id_g); |
| - const base::FilePath link_path_g = link_dir.AppendASCII(id_g); |
| - ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_g)); |
| - ASSERT_EQ(0, link(old_file_path_g.AsUTF8Unsafe().c_str(), |
| - link_path_g.AsUTF8Unsafe().c_str())); |
| - |
| - // Entry H: pinned entry without cache file. |
| - const std::string id_h = "id_h"; |
| - ResourceEntry entry_h; |
| - entry_h.set_local_id(id_h); |
| - FileCacheEntry* file_cache_entry_h = |
| - entry_h.mutable_file_specific_info()->mutable_cache_state(); |
| - file_cache_entry_h->set_is_present(true); |
| - file_cache_entry_h->set_is_pinned(true); |
| - file_cache_entry_h->set_is_dirty(false); |
| - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_h)); |
| - |
| - // Entry I: already migrated pinned cache file. |
| - const std::string id_i = "id_i"; |
| - ResourceEntry entry_i; |
| - entry_i.set_local_id(id_i); |
| - FileCacheEntry* file_cache_entry_i = |
| - entry_i.mutable_file_specific_info()->mutable_cache_state(); |
| - file_cache_entry_i->set_is_present(true); |
| - file_cache_entry_i->set_is_pinned(true); |
| - file_cache_entry_i->set_is_dirty(false); |
| - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_i)); |
| - const base::FilePath new_file_path_i = new_cache_dir.AppendASCII(id_i); |
| - const base::FilePath link_path_i = link_dir.AppendASCII(id_i); |
| - ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_i)); |
| - ASSERT_EQ(0, link(new_file_path_i.AsUTF8Unsafe().c_str(), |
| - link_path_i.AsUTF8Unsafe().c_str())); |
| - |
| - // Run migration. |
| - ASSERT_TRUE(FileCache::MigrateCacheFiles(old_cache_dir, new_cache_dir, |
| - link_dir, metadata_storage_.get())); |
| + const base::FilePath file_path_e = cache_files_dir_.AppendASCII(id_e); |
| + |
| + // Initialize resolves metadta inconsistency and invokes migration. |
| + ASSERT_TRUE(cache_->Initialize()); |
| // Check result. |
| - EXPECT_FALSE(base::PathExists(old_file_path_a)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_a)); |
| - EXPECT_EQ(1, GetNumberOfLinks(new_file_path_a)); |
| - // MigrateCacheFiles doesn't delete invalid cache file. |
| - EXPECT_TRUE(base::PathExists(old_file_path_b)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_c)); |
| - EXPECT_EQ(1, GetNumberOfLinks(new_file_path_c)); |
| - EXPECT_FALSE(base::PathExists(old_file_path_e)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_e)); |
| - EXPECT_TRUE(base::PathExists(link_path_e)); |
| - EXPECT_EQ(2, GetNumberOfLinks(new_file_path_e)); |
| - EXPECT_FALSE(base::PathExists(old_file_path_f)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_f)); |
| - EXPECT_TRUE(base::PathExists(link_path_f)); |
| - EXPECT_EQ(2, GetNumberOfLinks(new_file_path_f)); |
| - EXPECT_FALSE(base::PathExists(old_file_path_g)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_g)); |
| - EXPECT_TRUE(base::PathExists(link_path_g)); |
| - EXPECT_EQ(2, GetNumberOfLinks(new_file_path_g)); |
| - EXPECT_TRUE(base::PathExists(new_file_path_i)); |
| - EXPECT_TRUE(base::PathExists(link_path_i)); |
| - EXPECT_EQ(2, GetNumberOfLinks(new_file_path_i)); |
| + int64_t flags_a = Lsattr(file_path_a); |
| + int64_t flags_b = Lsattr(file_path_b); |
| + int64_t flags_c = Lsattr(file_path_c); |
| + int64_t flags_d = Lsattr(file_path_d); |
| + EXPECT_GE(flags_a, 0); |
|
hashimoto
2016/05/02 08:29:20
What is the point of these >=0 checks?
oka
2016/05/09 14:27:41
Replaced with ExpectIs*.
|
| + EXPECT_GE(flags_b, 0); |
| + EXPECT_GE(flags_c, 0); |
| + EXPECT_GE(flags_d, 0); |
| + EXPECT_EQ(flags_a & FS_NODUMP_FL, 0); |
|
hashimoto
2016/05/02 08:29:20
nit: Why not EXPECT_TRUE/EXPECT_FALSE?
oka
2016/05/09 14:27:40
Removed.
|
| + EXPECT_EQ(flags_b & FS_NODUMP_FL, 0); |
| + EXPECT_EQ(flags_c & FS_NODUMP_FL, FS_NODUMP_FL); |
| + EXPECT_EQ(flags_d & FS_NODUMP_FL, 0); |
| + |
| + EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_e, &entry_e)); |
| + EXPECT_FALSE(entry_e.file_specific_info().cache_state().is_present()); |
| + |
| + // Check the cache dir has appropriate attributes. |
| + int64_t flags_cache_dir = Lsattr(cache_files_dir_); |
| + EXPECT_GE(flags_cache_dir, 0); |
| + EXPECT_EQ(flags_cache_dir & FS_NODUMP_FL, FS_NODUMP_FL); |
| + |
| + std::string value = ""; |
| + value.resize(4); |
| + char* v = string_as_array(&value); |
| + ASSERT_EQ(getxattr(cache_files_dir_.value().c_str(), "user.GCacheFiles", v, |
| + 5), 5); |
| + EXPECT_STREQ(value.c_str(), "true"); |
| +} |
| + |
| +TEST_F(FileCacheTest, MigrationHappensOnlyOnce) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| + EXPECT_FALSE(cache_->ShouldStartDriveCacheMigration()); |
| } |
| TEST_F(FileCacheTest, ClearAll) { |
| + ASSERT_TRUE(cache_->Initialize()); |
| const std::string id("1a2b"); |
| const std::string md5("abcdef0123456789"); |