Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/drive/chromeos/file_cache.h" | 5 #include "components/drive/chromeos/file_cache.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | |
| 8 #include <linux/fs.h> | |
| 7 #include <stddef.h> | 9 #include <stddef.h> |
| 8 #include <stdint.h> | 10 #include <stdint.h> |
| 11 #include <sys/ioctl.h> | |
| 9 #include <sys/stat.h> | 12 #include <sys/stat.h> |
| 10 #include <sys/types.h> | 13 #include <sys/types.h> |
| 14 #include <sys/xattr.h> | |
| 11 #include <unistd.h> | 15 #include <unistd.h> |
| 12 | 16 |
| 13 #include <string> | 17 #include <string> |
| 14 #include <vector> | 18 #include <vector> |
| 15 | 19 |
| 16 #include "base/callback_helpers.h" | 20 #include "base/callback_helpers.h" |
| 17 #include "base/files/file_enumerator.h" | 21 #include "base/files/file_enumerator.h" |
| 18 #include "base/files/file_util.h" | 22 #include "base/files/file_util.h" |
| 19 #include "base/files/scoped_temp_dir.h" | 23 #include "base/files/scoped_temp_dir.h" |
| 20 #include "base/md5.h" | 24 #include "base/md5.h" |
| 21 #include "base/path_service.h" | 25 #include "base/path_service.h" |
| 22 #include "base/single_thread_task_runner.h" | 26 #include "base/single_thread_task_runner.h" |
| 27 #include "base/stl_util.h" | |
| 23 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 24 #include "base/thread_task_runner_handle.h" | 29 #include "base/thread_task_runner_handle.h" |
| 25 #include "base/time/time.h" | 30 #include "base/time/time.h" |
| 26 #include "components/drive/chromeos/drive_test_util.h" | 31 #include "components/drive/chromeos/drive_test_util.h" |
| 27 #include "components/drive/chromeos/fake_free_disk_space_getter.h" | 32 #include "components/drive/chromeos/fake_free_disk_space_getter.h" |
| 28 #include "components/drive/drive.pb.h" | 33 #include "components/drive/drive.pb.h" |
| 29 #include "components/drive/file_system_core_util.h" | 34 #include "components/drive/file_system_core_util.h" |
| 30 #include "components/drive/resource_metadata_storage.h" | 35 #include "components/drive/resource_metadata_storage.h" |
| 31 #include "content/public/test/test_browser_thread_bundle.h" | 36 #include "content/public/test/test_browser_thread_bundle.h" |
| 32 #include "google_apis/drive/test_util.h" | 37 #include "google_apis/drive/test_util.h" |
| 33 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 34 | 39 |
| 35 namespace drive { | 40 namespace drive { |
| 36 namespace internal { | 41 namespace internal { |
| 37 namespace { | 42 namespace { |
| 38 | 43 |
| 39 const base::FilePath::CharType kCacheFileDirectory[] = | 44 const base::FilePath::CharType kCacheFileDirectory[] = |
| 40 FILE_PATH_LITERAL("files"); | 45 FILE_PATH_LITERAL("files"); |
| 41 const base::FilePath::CharType kNewCacheFileDirectory[] = | |
| 42 FILE_PATH_LITERAL("blobs"); | |
| 43 const base::FilePath::CharType kLinkDirectory[] = FILE_PATH_LITERAL("links"); | |
| 44 | 46 |
| 45 const int kTemporaryFileSizeInBytes = 10; | 47 const int kTemporaryFileSizeInBytes = 10; |
| 46 | 48 |
| 47 int GetNumberOfLinks(const base::FilePath& file_path) { | 49 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.
| |
| 48 struct stat result; | 50 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.
| |
| 49 if (stat(file_path.AsUTF8Unsafe().c_str(), &result) != 0) { | 51 if (fd < 0) return -1; |
| 50 return -1; | 52 int64_t flags = 0; |
| 51 } | 53 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.
| |
| 52 return result.st_nlink; | 54 close(fd); |
| 55 return flags; | |
| 53 } | 56 } |
| 54 | 57 |
| 55 } // namespace | 58 } // namespace |
| 56 | 59 |
| 57 // Tests FileCache methods working with the blocking task runner. | 60 // Tests FileCache methods working with the blocking task runner. |
| 58 class FileCacheTest : public testing::Test { | 61 class FileCacheTest : public testing::Test { |
| 59 protected: | 62 protected: |
| 60 void SetUp() override { | 63 void SetUp() override { |
| 61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 64 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 62 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta"); | 65 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta"); |
| 63 cache_files_dir_ = temp_dir_.path().Append(kCacheFileDirectory); | 66 cache_files_dir_ = temp_dir_.path().Append(kCacheFileDirectory); |
| 64 | 67 |
| 65 ASSERT_TRUE(base::CreateDirectory(metadata_dir)); | 68 ASSERT_TRUE(base::CreateDirectory(metadata_dir)); |
| 66 ASSERT_TRUE(base::CreateDirectory(cache_files_dir_)); | 69 ASSERT_TRUE(base::CreateDirectory(cache_files_dir_)); |
| 67 | 70 |
| 68 fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter); | 71 fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter); |
| 69 | 72 |
| 70 metadata_storage_.reset(new ResourceMetadataStorage( | 73 metadata_storage_.reset(new ResourceMetadataStorage( |
| 71 metadata_dir, | 74 metadata_dir, |
| 72 base::ThreadTaskRunnerHandle::Get().get())); | 75 base::ThreadTaskRunnerHandle::Get().get())); |
| 73 ASSERT_TRUE(metadata_storage_->Initialize()); | 76 ASSERT_TRUE(metadata_storage_->Initialize()); |
| 74 | 77 |
| 75 cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_, | 78 cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_, |
| 76 base::ThreadTaskRunnerHandle::Get().get(), | 79 base::ThreadTaskRunnerHandle::Get().get(), |
| 77 fake_free_disk_space_getter_.get())); | 80 fake_free_disk_space_getter_.get())); |
| 78 ASSERT_TRUE(cache_->Initialize()); | |
| 79 } | 81 } |
| 80 | 82 |
| 81 static bool RenameCacheFilesToNewFormat(FileCache* cache) { | 83 static bool RenameCacheFilesToNewFormat(FileCache* cache) { |
| 82 return cache->RenameCacheFilesToNewFormat(); | 84 return cache->RenameCacheFilesToNewFormat(); |
| 83 } | 85 } |
| 84 | 86 |
| 85 base::FilePath AddTestEntry(const std::string id, | 87 base::FilePath AddTestEntry(const std::string id, |
| 86 const std::string md5, | 88 const std::string md5, |
| 87 const time_t last_accessed, | 89 const time_t last_accessed, |
| 88 const base::FilePath& src_file) { | 90 const base::FilePath& src_file) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 107 base::ScopedTempDir temp_dir_; | 109 base::ScopedTempDir temp_dir_; |
| 108 base::FilePath cache_files_dir_; | 110 base::FilePath cache_files_dir_; |
| 109 | 111 |
| 110 std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> | 112 std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> |
| 111 metadata_storage_; | 113 metadata_storage_; |
| 112 std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; | 114 std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; |
| 113 std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; | 115 std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; |
| 114 }; | 116 }; |
| 115 | 117 |
| 116 TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) { | 118 TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) { |
| 119 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
| |
| 117 base::FilePath dir_source_root; | 120 base::FilePath dir_source_root; |
| 118 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root)); | 121 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root)); |
| 119 const base::FilePath src_path = | 122 const base::FilePath src_path = |
| 120 dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png"); | 123 dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png"); |
| 121 | 124 |
| 122 // Store files. This file should not be moved. | 125 // Store files. This file should not be moved. |
| 123 ResourceEntry entry; | 126 ResourceEntry entry; |
| 124 entry.set_local_id("id_foo"); | 127 entry.set_local_id("id_foo"); |
| 125 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 128 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 126 EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path, | 129 EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 dest_directory.AppendASCII("image00000001.png"))); | 162 dest_directory.AppendASCII("image00000001.png"))); |
| 160 EXPECT_TRUE(base::ContentsEqual( | 163 EXPECT_TRUE(base::ContentsEqual( |
| 161 src_path, | 164 src_path, |
| 162 dest_directory.AppendASCII("baz00000002.png"))); | 165 dest_directory.AppendASCII("baz00000002.png"))); |
| 163 } | 166 } |
| 164 EXPECT_FALSE(base::PathExists( | 167 EXPECT_FALSE(base::PathExists( |
| 165 dest_directory.AppendASCII("image00000003.png"))); | 168 dest_directory.AppendASCII("image00000003.png"))); |
| 166 } | 169 } |
| 167 | 170 |
| 168 TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) { | 171 TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) { |
| 172 ASSERT_TRUE(cache_->Initialize()); | |
| 169 base::FilePath src_file; | 173 base::FilePath src_file; |
| 170 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 174 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 171 | 175 |
| 172 // Store a file as a 'temporary' file and remember the path. | 176 // Store a file as a 'temporary' file and remember the path. |
| 173 const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp"; | 177 const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp"; |
| 174 const time_t last_accessed_tmp = 1; | 178 const time_t last_accessed_tmp = 1; |
| 175 const base::FilePath& tmp_path = | 179 const base::FilePath& tmp_path = |
| 176 AddTestEntry(id_tmp, md5_tmp, last_accessed_tmp, src_file); | 180 AddTestEntry(id_tmp, md5_tmp, last_accessed_tmp, src_file); |
| 177 | 181 |
| 178 // Store a file as a pinned file and remember the path. | 182 // Store a file as a pinned file and remember the path. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 198 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry)); | 202 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry)); |
| 199 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); | 203 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| 200 EXPECT_TRUE(base::PathExists(pinned_path)); | 204 EXPECT_TRUE(base::PathExists(pinned_path)); |
| 201 | 205 |
| 202 // Returns false when disk space cannot be freed. | 206 // Returns false when disk space cannot be freed. |
| 203 fake_free_disk_space_getter_->set_default_value(0); | 207 fake_free_disk_space_getter_->set_default_value(0); |
| 204 EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); | 208 EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); |
| 205 } | 209 } |
| 206 | 210 |
| 207 TEST_F(FileCacheTest, EvictDriveCacheInLRU) { | 211 TEST_F(FileCacheTest, EvictDriveCacheInLRU) { |
| 212 ASSERT_TRUE(cache_->Initialize()); | |
| 208 // Create temporary file. | 213 // Create temporary file. |
| 209 base::FilePath src_file; | 214 base::FilePath src_file; |
| 210 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 215 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 211 ASSERT_EQ(kTemporaryFileSizeInBytes, | 216 ASSERT_EQ(kTemporaryFileSizeInBytes, |
| 212 base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); | 217 base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); |
| 213 | 218 |
| 214 // Add entries. | 219 // Add entries. |
| 215 const std::string id_a = "id_a", md5_a = "md5_a"; | 220 const std::string id_a = "id_a", md5_a = "md5_a"; |
| 216 const time_t last_accessed_a = 1; | 221 const time_t last_accessed_a = 1; |
| 217 const base::FilePath& a_path = | 222 const base::FilePath& a_path = |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 | 263 |
| 259 // Entry C should not be evicted. | 264 // Entry C should not be evicted. |
| 260 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_c, &entry)); | 265 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_c, &entry)); |
| 261 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); | 266 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| 262 EXPECT_TRUE(base::PathExists(c_path)); | 267 EXPECT_TRUE(base::PathExists(c_path)); |
| 263 } | 268 } |
| 264 | 269 |
| 265 // Test case for deleting invalid cache files which don't have corresponding | 270 // Test case for deleting invalid cache files which don't have corresponding |
| 266 // metadata. | 271 // metadata. |
| 267 TEST_F(FileCacheTest, EvictInvalidCacheFile) { | 272 TEST_F(FileCacheTest, EvictInvalidCacheFile) { |
| 273 ASSERT_TRUE(cache_->Initialize()); | |
| 268 base::FilePath src_file; | 274 base::FilePath src_file; |
| 269 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 275 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 270 | 276 |
| 271 // Add entries. | 277 // Add entries. |
| 272 const std::string id_a = "id_a", md5_a = "md5_a"; | 278 const std::string id_a = "id_a", md5_a = "md5_a"; |
| 273 const time_t last_accessed_a = 1; | 279 const time_t last_accessed_a = 1; |
| 274 const base::FilePath& a_path = | 280 const base::FilePath& a_path = |
| 275 AddTestEntry(id_a, md5_a, last_accessed_a, src_file); | 281 AddTestEntry(id_a, md5_a, last_accessed_a, src_file); |
| 276 | 282 |
| 277 const std::string id_b = "id_b", md5_b = "md5_b"; | 283 const std::string id_b = "id_b", md5_b = "md5_b"; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 296 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry)); | 302 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry)); |
| 297 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); | 303 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| 298 EXPECT_TRUE(base::PathExists(a_path)); | 304 EXPECT_TRUE(base::PathExists(a_path)); |
| 299 | 305 |
| 300 // Entry B is evicted. | 306 // Entry B is evicted. |
| 301 EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_storage_->GetEntry(id_b, &entry)); | 307 EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_storage_->GetEntry(id_b, &entry)); |
| 302 EXPECT_FALSE(base::PathExists(b_path)); | 308 EXPECT_FALSE(base::PathExists(b_path)); |
| 303 } | 309 } |
| 304 | 310 |
| 305 TEST_F(FileCacheTest, TooManyCacheFiles) { | 311 TEST_F(FileCacheTest, TooManyCacheFiles) { |
| 312 ASSERT_TRUE(cache_->Initialize()); | |
| 306 const size_t kMaxNumOfEvictedCacheFiles = 50; | 313 const size_t kMaxNumOfEvictedCacheFiles = 50; |
| 307 cache_->SetMaxNumOfEvictedCacheFilesForTest(kMaxNumOfEvictedCacheFiles); | 314 cache_->SetMaxNumOfEvictedCacheFilesForTest(kMaxNumOfEvictedCacheFiles); |
| 308 | 315 |
| 309 // Create temporary file. | 316 // Create temporary file. |
| 310 base::FilePath src_file; | 317 base::FilePath src_file; |
| 311 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 318 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 312 ASSERT_EQ(kTemporaryFileSizeInBytes, | 319 ASSERT_EQ(kTemporaryFileSizeInBytes, |
| 313 base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); | 320 base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); |
| 314 | 321 |
| 315 // Add kNumOfTestFiles=kMaxNumOfEvictedCacheFiles*2 entries. | 322 // Add kNumOfTestFiles=kMaxNumOfEvictedCacheFiles*2 entries. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 339 (kMaxNumOfEvictedCacheFiles * 3 / 2) * kTemporaryFileSizeInBytes; | 346 (kMaxNumOfEvictedCacheFiles * 3 / 2) * kTemporaryFileSizeInBytes; |
| 340 EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); | 347 EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); |
| 341 | 348 |
| 342 for (uint32_t i = 0; i < kNumOfTestFiles; ++i) { | 349 for (uint32_t i = 0; i < kNumOfTestFiles; ++i) { |
| 343 // Assert that only first kMaxNumOfEvictedCacheFiles exist. | 350 // Assert that only first kMaxNumOfEvictedCacheFiles exist. |
| 344 ASSERT_EQ(i < kMaxNumOfEvictedCacheFiles, base::PathExists(paths[i])); | 351 ASSERT_EQ(i < kMaxNumOfEvictedCacheFiles, base::PathExists(paths[i])); |
| 345 } | 352 } |
| 346 } | 353 } |
| 347 | 354 |
| 348 TEST_F(FileCacheTest, GetFile) { | 355 TEST_F(FileCacheTest, GetFile) { |
| 356 ASSERT_TRUE(cache_->Initialize()); | |
| 349 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 357 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 350 const std::string src_contents = "test"; | 358 const std::string src_contents = "test"; |
| 351 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 359 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 352 src_contents)); | 360 src_contents)); |
| 353 std::string id("id1"); | 361 std::string id("id1"); |
| 354 std::string md5(base::MD5String(src_contents)); | 362 std::string md5(base::MD5String(src_contents)); |
| 355 | 363 |
| 356 const base::FilePath cache_file_directory = | 364 const base::FilePath cache_file_directory = |
| 357 temp_dir_.path().Append(kCacheFileDirectory); | 365 temp_dir_.path().Append(kCacheFileDirectory); |
| 358 | 366 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 393 EXPECT_EQ( | 401 EXPECT_EQ( |
| 394 cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(), | 402 cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(), |
| 395 cache_file_path.value()); | 403 cache_file_path.value()); |
| 396 | 404 |
| 397 contents.clear(); | 405 contents.clear(); |
| 398 EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents)); | 406 EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents)); |
| 399 EXPECT_EQ(src_contents, contents); | 407 EXPECT_EQ(src_contents, contents); |
| 400 } | 408 } |
| 401 | 409 |
| 402 TEST_F(FileCacheTest, Store) { | 410 TEST_F(FileCacheTest, Store) { |
| 411 ASSERT_TRUE(cache_->Initialize()); | |
| 403 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 412 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 404 const std::string src_contents = "test"; | 413 const std::string src_contents = "test"; |
| 405 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 414 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 406 src_contents)); | 415 src_contents)); |
| 407 std::string id("id"); | 416 std::string id("id"); |
| 408 std::string md5(base::MD5String(src_contents)); | 417 std::string md5(base::MD5String(src_contents)); |
| 409 | 418 |
| 410 // Store a file. | 419 // Store a file. |
| 411 ResourceEntry entry; | 420 ResourceEntry entry; |
| 412 entry.set_local_id(id); | 421 entry.set_local_id(id); |
| 413 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 422 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 414 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( | 423 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| 415 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); | 424 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 416 | 425 |
| 417 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 426 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 418 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); | 427 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| 419 EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5()); | 428 EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5()); |
| 420 | 429 |
| 421 base::FilePath cache_file_path; | 430 base::FilePath cache_file_path; |
| 422 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); | 431 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); |
| 423 EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path)); | 432 EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path)); |
| 424 | 433 |
| 434 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.
| |
| 435 int64_t flags = Lsattr(dest_file_path); | |
| 436 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.
| |
| 437 EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); | |
| 438 | |
| 425 // Store a non-existent file. | 439 // Store a non-existent file. |
| 426 EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store( | 440 EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store( |
| 427 id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"), | 441 id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"), |
| 428 FileCache::FILE_OPERATION_COPY)); | 442 FileCache::FILE_OPERATION_COPY)); |
| 429 | 443 |
| 430 // Passing empty MD5 marks the entry as dirty. | 444 // Passing empty MD5 marks the entry as dirty. |
| 431 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( | 445 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| 432 id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY)); | 446 id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 433 | 447 |
| 434 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 448 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 435 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); | 449 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); |
| 436 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); | 450 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); |
| 437 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); | 451 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| 452 flags &= ~FS_NODUMP_FL; | |
| 453 EXPECT_EQ(Lsattr(dest_file_path), flags); | |
| 438 | 454 |
| 439 // No free space available. | 455 // No free space available. |
| 440 fake_free_disk_space_getter_->set_default_value(0); | 456 fake_free_disk_space_getter_->set_default_value(0); |
| 441 | 457 |
| 442 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store( | 458 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store( |
| 443 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); | 459 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 444 } | 460 } |
| 445 | 461 |
| 446 TEST_F(FileCacheTest, PinAndUnpin) { | 462 TEST_F(FileCacheTest, PinAndUnpin) { |
| 463 ASSERT_TRUE(cache_->Initialize()); | |
| 447 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 464 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 448 const std::string src_contents = "test"; | 465 const std::string src_contents = "test"; |
| 449 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 466 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 450 src_contents)); | 467 src_contents)); |
| 451 std::string id("id_present"); | 468 std::string id("id_present"); |
| 452 std::string md5(base::MD5String(src_contents)); | 469 std::string md5(base::MD5String(src_contents)); |
| 453 | 470 |
| 454 // Store a file. | 471 // Store a file. |
| 455 ResourceEntry entry; | 472 ResourceEntry entry; |
| 456 entry.set_local_id(id); | 473 entry.set_local_id(id); |
| 457 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 474 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 458 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( | 475 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| 459 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); | 476 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 460 | 477 |
| 478 const base::FilePath dest_file_path = cache_files_dir_.AppendASCII(id); | |
| 461 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 479 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 462 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); | 480 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); |
| 481 int64_t flags = Lsattr(dest_file_path); | |
| 482 ASSERT_GE(flags, 0); | |
| 483 EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); | |
| 463 | 484 |
| 464 // Pin the existing file. | 485 // Pin the existing file. |
| 465 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); | 486 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); |
| 466 | 487 |
| 467 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 488 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 468 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); | 489 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); |
| 490 flags &= ~FS_NODUMP_FL; | |
| 491 EXPECT_EQ(Lsattr(dest_file_path),flags); | |
| 469 | 492 |
| 470 // Unpin the file. | 493 // Unpin the file. |
| 471 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id)); | 494 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id)); |
| 472 | 495 |
| 473 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 496 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 474 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); | 497 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); |
| 498 flags |= FS_NODUMP_FL; | |
| 499 EXPECT_EQ(Lsattr(dest_file_path), flags); | |
| 475 | 500 |
| 476 // Pin a non-present file. | 501 // Pin a non-present file. |
| 477 std::string id_non_present = "id_non_present"; | 502 std::string id_non_present = "id_non_present"; |
| 478 entry.Clear(); | 503 entry.Clear(); |
| 479 entry.set_local_id(id_non_present); | 504 entry.set_local_id(id_non_present); |
| 480 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 505 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 481 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present)); | 506 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present)); |
| 482 | 507 |
| 483 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); | 508 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); |
| 484 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); | 509 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); |
| 485 | 510 |
| 486 // Unpin the previously pinned non-existent file. | 511 // Unpin the previously pinned non-existent file. |
| 487 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present)); | 512 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present)); |
| 488 | 513 |
| 489 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); | 514 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); |
| 490 EXPECT_FALSE(entry.file_specific_info().has_cache_state()); | 515 EXPECT_FALSE(entry.file_specific_info().has_cache_state()); |
| 491 | 516 |
| 492 // Unpin a file that doesn't exist in cache and is not pinned. | 517 // Unpin a file that doesn't exist in cache and is not pinned. |
| 493 EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent")); | 518 EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent")); |
| 494 } | 519 } |
| 495 | 520 |
| 496 TEST_F(FileCacheTest, MountUnmount) { | 521 TEST_F(FileCacheTest, MountUnmount) { |
| 522 ASSERT_TRUE(cache_->Initialize()); | |
| 497 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 523 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 498 const std::string src_contents = "test"; | 524 const std::string src_contents = "test"; |
| 499 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 525 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 500 src_contents)); | 526 src_contents)); |
| 501 std::string id("id_present"); | 527 std::string id("id_present"); |
| 502 std::string md5(base::MD5String(src_contents)); | 528 std::string md5(base::MD5String(src_contents)); |
| 503 | 529 |
| 504 // Store a file. | 530 // Store a file. |
| 505 ResourceEntry entry; | 531 ResourceEntry entry; |
| 506 entry.set_local_id(id); | 532 entry.set_local_id(id); |
| 507 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 533 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 508 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( | 534 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| 509 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); | 535 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 510 | 536 |
| 511 // Mark the file mounted. | 537 // Mark the file mounted. |
| 512 base::FilePath cache_file_path; | 538 base::FilePath cache_file_path; |
| 513 EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path)); | 539 EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path)); |
| 514 | 540 |
| 515 // Try to remove it. | 541 // Try to remove it. |
| 516 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id)); | 542 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id)); |
| 517 | 543 |
| 518 // Clear mounted state of the file. | 544 // Clear mounted state of the file. |
| 519 EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path)); | 545 EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path)); |
| 520 | 546 |
| 521 // Try to remove again. | 547 // Try to remove again. |
| 522 EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); | 548 EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); |
| 523 } | 549 } |
| 524 | 550 |
| 525 TEST_F(FileCacheTest, OpenForWrite) { | 551 TEST_F(FileCacheTest, OpenForWrite) { |
| 552 ASSERT_TRUE(cache_->Initialize()); | |
| 526 // Prepare a file. | 553 // Prepare a file. |
| 527 base::FilePath src_file; | 554 base::FilePath src_file; |
| 528 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 555 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 529 | 556 |
| 530 const std::string id = "id"; | 557 const std::string id = "id"; |
| 531 ResourceEntry entry; | 558 ResourceEntry entry; |
| 532 entry.set_local_id(id); | 559 entry.set_local_id(id); |
| 533 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 560 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 534 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, | 561 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, |
| 535 FileCache::FILE_OPERATION_COPY)); | 562 FileCache::FILE_OPERATION_COPY)); |
| 536 EXPECT_EQ(0, entry.file_info().last_modified()); | 563 EXPECT_EQ(0, entry.file_info().last_modified()); |
| 537 | 564 |
| 538 // Entry is not dirty nor opened. | 565 // Entry is not dirty nor opened. |
| 539 EXPECT_FALSE(cache_->IsOpenedForWrite(id)); | 566 EXPECT_FALSE(cache_->IsOpenedForWrite(id)); |
| 540 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 567 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 541 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); | 568 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); |
| 542 | 569 |
| 570 const base::FilePath dest_file = cache_files_dir_.AppendASCII(id); | |
| 571 int64_t flags = Lsattr(dest_file); | |
| 572 ASSERT_GE(flags, 0); | |
| 573 EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); | |
| 574 | |
| 543 // Open (1). | 575 // Open (1). |
| 544 std::unique_ptr<base::ScopedClosureRunner> file_closer1; | 576 std::unique_ptr<base::ScopedClosureRunner> file_closer1; |
| 545 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1)); | 577 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1)); |
| 546 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); | 578 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); |
| 547 | 579 |
| 548 // Entry is dirty. | 580 // Entry is dirty. |
| 549 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 581 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 550 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); | 582 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| 583 flags &= ~FS_NODUMP_FL; | |
| 584 EXPECT_EQ(Lsattr(dest_file), flags); | |
| 551 | 585 |
| 552 // Open (2). | 586 // Open (2). |
| 553 std::unique_ptr<base::ScopedClosureRunner> file_closer2; | 587 std::unique_ptr<base::ScopedClosureRunner> file_closer2; |
| 554 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2)); | 588 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2)); |
| 555 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); | 589 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); |
| 556 | 590 |
| 557 // Close (1). | 591 // Close (1). |
| 558 file_closer1.reset(); | 592 file_closer1.reset(); |
| 559 base::RunLoop().RunUntilIdle(); | 593 base::RunLoop().RunUntilIdle(); |
| 560 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); | 594 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); |
| 561 | 595 |
| 562 // last_modified is updated. | 596 // last_modified is updated. |
| 563 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 597 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 564 EXPECT_NE(0, entry.file_info().last_modified()); | 598 EXPECT_NE(0, entry.file_info().last_modified()); |
| 565 | 599 |
| 566 // Close (2). | 600 // Close (2). |
| 567 file_closer2.reset(); | 601 file_closer2.reset(); |
| 568 base::RunLoop().RunUntilIdle(); | 602 base::RunLoop().RunUntilIdle(); |
| 569 EXPECT_FALSE(cache_->IsOpenedForWrite(id)); | 603 EXPECT_FALSE(cache_->IsOpenedForWrite(id)); |
| 570 | 604 |
| 571 // Try to open non-existent file. | 605 // Try to open non-existent file. |
| 572 EXPECT_EQ(FILE_ERROR_NOT_FOUND, | 606 EXPECT_EQ(FILE_ERROR_NOT_FOUND, |
| 573 cache_->OpenForWrite("nonexistent_id", &file_closer1)); | 607 cache_->OpenForWrite("nonexistent_id", &file_closer1)); |
| 574 } | 608 } |
| 575 | 609 |
| 576 TEST_F(FileCacheTest, UpdateMd5) { | 610 TEST_F(FileCacheTest, UpdateMd5) { |
| 611 ASSERT_TRUE(cache_->Initialize()); | |
| 577 // Store test data. | 612 // Store test data. |
| 578 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 613 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 579 const std::string contents_before = "before"; | 614 const std::string contents_before = "before"; |
| 580 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 615 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 581 contents_before)); | 616 contents_before)); |
| 582 std::string id("id1"); | 617 std::string id("id1"); |
| 583 ResourceEntry entry; | 618 ResourceEntry entry; |
| 584 entry.set_local_id(id); | 619 entry.set_local_id(id); |
| 585 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 620 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 586 EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before), | 621 EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 608 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); | 643 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); |
| 609 | 644 |
| 610 // Update MD5. | 645 // Update MD5. |
| 611 EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id)); | 646 EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id)); |
| 612 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 647 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 613 EXPECT_EQ(base::MD5String(contents_after), | 648 EXPECT_EQ(base::MD5String(contents_after), |
| 614 entry.file_specific_info().cache_state().md5()); | 649 entry.file_specific_info().cache_state().md5()); |
| 615 } | 650 } |
| 616 | 651 |
| 617 TEST_F(FileCacheTest, ClearDirty) { | 652 TEST_F(FileCacheTest, ClearDirty) { |
| 653 ASSERT_TRUE(cache_->Initialize()); | |
| 618 // Prepare a file. | 654 // Prepare a file. |
| 619 base::FilePath src_file; | 655 base::FilePath src_file; |
| 620 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 656 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 621 | 657 |
| 622 const std::string id = "id"; | 658 const std::string id = "id"; |
| 623 ResourceEntry entry; | 659 ResourceEntry entry; |
| 624 entry.set_local_id(id); | 660 entry.set_local_id(id); |
| 625 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 661 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 626 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, | 662 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, |
| 627 FileCache::FILE_OPERATION_COPY)); | 663 FileCache::FILE_OPERATION_COPY)); |
| 628 | 664 |
| 665 const base::FilePath dest_file = cache_files_dir_.AppendASCII(id); | |
| 666 | |
| 667 int64_t flags = Lsattr(dest_file); | |
| 668 ASSERT_GE(flags, 0); | |
| 669 EXPECT_EQ(flags & FS_NODUMP_FL, FS_NODUMP_FL); | |
| 670 | |
| 629 // Open the file. | 671 // Open the file. |
| 630 std::unique_ptr<base::ScopedClosureRunner> file_closer; | 672 std::unique_ptr<base::ScopedClosureRunner> file_closer; |
| 631 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); | 673 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); |
| 632 | 674 |
| 633 // Entry is dirty. | 675 // Entry is dirty. |
| 634 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 676 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 635 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); | 677 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); |
| 678 flags &= ~FS_NODUMP_FL; | |
| 679 EXPECT_EQ(Lsattr(dest_file), flags); | |
| 636 | 680 |
| 637 // Cannot clear the dirty bit of an opened entry. | 681 // Cannot clear the dirty bit of an opened entry. |
| 638 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id)); | 682 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id)); |
| 683 EXPECT_EQ(Lsattr(dest_file), flags); | |
| 639 | 684 |
| 640 // Close the file and clear the dirty bit. | 685 // Close the file and clear the dirty bit. |
| 641 file_closer.reset(); | 686 file_closer.reset(); |
| 642 base::RunLoop().RunUntilIdle(); | 687 base::RunLoop().RunUntilIdle(); |
| 643 EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id)); | 688 EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id)); |
| 644 | 689 |
| 645 // Entry is not dirty. | 690 // Entry is not dirty. |
| 646 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); | 691 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); |
| 647 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); | 692 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); |
| 693 flags |= FS_NODUMP_FL; | |
| 694 EXPECT_EQ(Lsattr(dest_file), flags); | |
| 648 } | 695 } |
| 649 | 696 |
| 650 TEST_F(FileCacheTest, Remove) { | 697 TEST_F(FileCacheTest, Remove) { |
| 698 ASSERT_TRUE(cache_->Initialize()); | |
| 651 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); | 699 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); |
| 652 const std::string src_contents = "test"; | 700 const std::string src_contents = "test"; |
| 653 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, | 701 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, |
| 654 src_contents)); | 702 src_contents)); |
| 655 std::string id("id"); | 703 std::string id("id"); |
| 656 std::string md5(base::MD5String(src_contents)); | 704 std::string md5(base::MD5String(src_contents)); |
| 657 | 705 |
| 658 // First store a file to cache. | 706 // First store a file to cache. |
| 659 ResourceEntry entry; | 707 ResourceEntry entry; |
| 660 entry.set_local_id(id); | 708 entry.set_local_id(id); |
| 661 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 709 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 662 base::FilePath src_file; | 710 base::FilePath src_file; |
| 663 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 711 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 664 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( | 712 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( |
| 665 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); | 713 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); |
| 666 | 714 |
| 667 base::FilePath cache_file_path; | 715 base::FilePath cache_file_path; |
| 668 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); | 716 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); |
| 669 | 717 |
| 670 // Then try to remove existing file from cache. | 718 // Then try to remove existing file from cache. |
| 671 EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); | 719 EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); |
| 672 EXPECT_FALSE(base::PathExists(cache_file_path)); | 720 EXPECT_FALSE(base::PathExists(cache_file_path)); |
| 673 } | 721 } |
| 674 | 722 |
| 675 TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) { | 723 TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) { |
| 724 ASSERT_TRUE(cache_->Initialize()); | |
| 676 const base::FilePath file_directory = | 725 const base::FilePath file_directory = |
| 677 temp_dir_.path().Append(kCacheFileDirectory); | 726 temp_dir_.path().Append(kCacheFileDirectory); |
| 678 | 727 |
| 679 // File with an old style "<prefix>:<ID>.<MD5>" name. | 728 // File with an old style "<prefix>:<ID>.<MD5>" name. |
| 680 ASSERT_TRUE(google_apis::test_util::WriteStringToFile( | 729 ASSERT_TRUE(google_apis::test_util::WriteStringToFile( |
| 681 file_directory.AppendASCII("file:id_koo.md5"), "koo")); | 730 file_directory.AppendASCII("file:id_koo.md5"), "koo")); |
| 682 | 731 |
| 683 // File with multiple extensions should be removed. | 732 // File with multiple extensions should be removed. |
| 684 ASSERT_TRUE(google_apis::test_util::WriteStringToFile( | 733 ASSERT_TRUE(google_apis::test_util::WriteStringToFile( |
| 685 file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)")); | 734 file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)")); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 704 contents.clear(); | 753 contents.clear(); |
| 705 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"), | 754 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"), |
| 706 &contents)); | 755 &contents)); |
| 707 EXPECT_EQ("koo", contents); | 756 EXPECT_EQ("koo", contents); |
| 708 contents.clear(); | 757 contents.clear(); |
| 709 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"), | 758 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"), |
| 710 &contents)); | 759 &contents)); |
| 711 EXPECT_EQ("kyu", contents); | 760 EXPECT_EQ("kyu", contents); |
| 712 } | 761 } |
| 713 | 762 |
| 714 // Test for migrating cache files from files to blobs. | 763 // Test for migrating cache files resolving inconsistency in metadata. |
| 715 TEST_F(FileCacheTest, MigrateCacheFiles) { | 764 TEST_F(FileCacheTest, MigrateCacheFiles) { |
| 716 // Create test files and metadata. | 765 // Create test files and metadata. |
| 717 base::FilePath temp_file; | 766 base::FilePath temp_file; |
| 718 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); | 767 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); |
| 719 | 768 |
| 720 const base::FilePath old_cache_dir = | 769 // Entry A: pinned cache file. |
| 721 temp_dir_.path().Append(kCacheFileDirectory); | |
| 722 const base::FilePath new_cache_dir = | |
| 723 temp_dir_.path().Append(kNewCacheFileDirectory); | |
| 724 const base::FilePath link_dir = temp_dir_.path().Append(kLinkDirectory); | |
| 725 ASSERT_TRUE(base::CreateDirectory(old_cache_dir)); | |
| 726 ASSERT_TRUE(base::CreateDirectory(new_cache_dir)); | |
| 727 ASSERT_TRUE(base::CreateDirectory(link_dir)); | |
| 728 | |
| 729 // Entry A: cache file in old cache directory with metadata. | |
| 730 const std::string id_a = "id_a"; | 770 const std::string id_a = "id_a"; |
| 731 ResourceEntry entry_a; | 771 ResourceEntry entry_a; |
| 732 entry_a.set_local_id(id_a); | 772 entry_a.set_local_id(id_a); |
| 733 entry_a.mutable_file_specific_info()->mutable_cache_state()->set_is_present( | 773 FileCacheEntry* file_cache_entry_a = |
| 734 true); | 774 entry_a.mutable_file_specific_info()->mutable_cache_state(); |
| 775 file_cache_entry_a->set_is_present(true); | |
| 776 file_cache_entry_a->set_is_pinned(true); | |
| 777 file_cache_entry_a->set_is_dirty(false); | |
| 735 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); | 778 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); |
| 736 const base::FilePath old_file_path_a = old_cache_dir.AppendASCII(id_a); | 779 const base::FilePath file_path_a = cache_files_dir_.AppendASCII(id_a); |
| 737 const base::FilePath new_file_path_a = new_cache_dir.AppendASCII(id_a); | 780 ASSERT_TRUE(base::CopyFile(temp_file, file_path_a)); |
| 738 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_a)); | |
| 739 | 781 |
| 740 // Entry B: cache file in old cache directory without metadata. | 782 // Entry B: dirty cache file. |
| 741 const std::string id_b = "id_b"; | 783 const std::string id_b = "id_b"; |
| 742 const base::FilePath old_file_path_b = old_cache_dir.AppendASCII(id_b); | 784 ResourceEntry entry_b; |
| 743 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_b)); | 785 entry_b.set_local_id(id_b); |
| 786 FileCacheEntry* file_cache_entry_b = | |
| 787 entry_b.mutable_file_specific_info()->mutable_cache_state(); | |
| 788 file_cache_entry_b->set_is_present(true); | |
| 789 file_cache_entry_b->set_is_pinned(false); | |
| 790 file_cache_entry_b->set_is_dirty(true); | |
| 791 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_b)); | |
| 792 const base::FilePath file_path_b = cache_files_dir_.AppendASCII(id_b); | |
| 793 ASSERT_TRUE(base::CopyFile(temp_file, file_path_b)); | |
| 744 | 794 |
| 745 // Entry C: already migrated cache file. | 795 // Entry C: not pinned nor dirty cache file. |
| 746 const std::string id_c = "id_c"; | 796 const std::string id_c = "id_c"; |
| 747 ResourceEntry entry_c; | 797 ResourceEntry entry_c; |
| 748 entry_c.set_local_id(id_c); | 798 entry_c.set_local_id(id_c); |
| 749 entry_c.mutable_file_specific_info()->mutable_cache_state()->set_is_present( | 799 FileCacheEntry* file_cache_entry_c = |
| 750 true); | 800 entry_c.mutable_file_specific_info()->mutable_cache_state(); |
| 801 file_cache_entry_c->set_is_present(true); | |
| 802 file_cache_entry_c->set_is_pinned(false); | |
| 803 file_cache_entry_c->set_is_dirty(false); | |
| 751 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c)); | 804 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c)); |
| 752 const base::FilePath new_file_path_c = new_cache_dir.AppendASCII(id_c); | 805 const base::FilePath file_path_c = cache_files_dir_.AppendASCII(id_c); |
| 753 ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_c)); | 806 ASSERT_TRUE(base::CopyFile(temp_file, file_path_c)); |
| 754 | 807 |
| 755 // Entry D: metadata entry without cache file. | 808 // Entry D: pinned cache file somehow having removable flag. |
| 756 const std::string id_d = "id_d"; | 809 const std::string id_d = "id_d"; |
| 757 ResourceEntry entry_d; | 810 ResourceEntry entry_d; |
| 758 entry_d.set_local_id(id_d); | 811 entry_d.set_local_id(id_d); |
| 759 entry_d.mutable_file_specific_info()->mutable_cache_state()->set_is_present( | 812 FileCacheEntry* file_cache_entry_d = |
| 760 true); | 813 entry_d.mutable_file_specific_info()->mutable_cache_state(); |
| 814 file_cache_entry_d->set_is_present(true); | |
| 815 file_cache_entry_d->set_is_pinned(true); | |
| 816 file_cache_entry_d->set_is_dirty(false); | |
| 761 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); | 817 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); |
| 818 const base::FilePath file_path_d = cache_files_dir_.AppendASCII(id_d); | |
| 819 ASSERT_TRUE(base::CopyFile(temp_file, file_path_d)); | |
| 762 | 820 |
| 763 // Entry E: pinned cache file. | 821 // 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
| |
| 822 int fd; | |
| 823 ASSERT_GE(fd = open(file_path_d.value().c_str(), O_RDONLY), 0); | |
| 824 int64_t flags; | |
| 825 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.
| |
| 826 flags |= FS_NODUMP_FL; | |
| 827 ASSERT_EQ(ioctl(fd, FS_IOC_SETFLAGS, &flags), 0); | |
| 828 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.
| |
| 829 | |
| 830 // Entry E: there is no file; removed by cryptohome. | |
| 764 const std::string id_e = "id_e"; | 831 const std::string id_e = "id_e"; |
| 765 ResourceEntry entry_e; | 832 ResourceEntry entry_e; |
| 766 entry_e.set_local_id(id_e); | 833 entry_e.set_local_id(id_e); |
| 767 FileCacheEntry* file_cache_entry_e = | 834 FileCacheEntry* file_cache_entry_e = |
| 768 entry_e.mutable_file_specific_info()->mutable_cache_state(); | 835 entry_e.mutable_file_specific_info()->mutable_cache_state(); |
| 769 file_cache_entry_e->set_is_present(true); | 836 file_cache_entry_e->set_is_present(true); |
| 770 file_cache_entry_e->set_is_pinned(true); | 837 file_cache_entry_e->set_is_pinned(false); |
| 771 file_cache_entry_e->set_is_dirty(false); | 838 file_cache_entry_e->set_is_dirty(false); |
| 772 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); | 839 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); |
| 773 const base::FilePath old_file_path_e = old_cache_dir.AppendASCII(id_e); | 840 const base::FilePath file_path_e = cache_files_dir_.AppendASCII(id_e); |
| 774 const base::FilePath new_file_path_e = new_cache_dir.AppendASCII(id_e); | |
| 775 const base::FilePath link_path_e = link_dir.AppendASCII(id_e); | |
| 776 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_e)); | |
| 777 | 841 |
| 778 // Entry F: dirty cache file. | 842 // Initialize resolves metadta inconsistency and invokes migration. |
| 779 const std::string id_f = "id_f"; | 843 ASSERT_TRUE(cache_->Initialize()); |
| 780 ResourceEntry entry_f; | |
| 781 entry_f.set_local_id(id_f); | |
| 782 FileCacheEntry* file_cache_entry_f = | |
| 783 entry_f.mutable_file_specific_info()->mutable_cache_state(); | |
| 784 file_cache_entry_f->set_is_present(true); | |
| 785 file_cache_entry_f->set_is_pinned(false); | |
| 786 file_cache_entry_f->set_is_dirty(true); | |
| 787 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f)); | |
| 788 const base::FilePath old_file_path_f = old_cache_dir.AppendASCII(id_f); | |
| 789 const base::FilePath new_file_path_f = new_cache_dir.AppendASCII(id_f); | |
| 790 const base::FilePath link_path_f = link_dir.AppendASCII(id_f); | |
| 791 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_f)); | |
| 792 | |
| 793 // Entry G: partially migrated pinned cache file. | |
| 794 const std::string id_g = "id_g"; | |
| 795 ResourceEntry entry_g; | |
| 796 entry_g.set_local_id(id_g); | |
| 797 FileCacheEntry* file_cache_entry_g = | |
| 798 entry_g.mutable_file_specific_info()->mutable_cache_state(); | |
| 799 file_cache_entry_g->set_is_present(true); | |
| 800 file_cache_entry_g->set_is_pinned(true); | |
| 801 file_cache_entry_g->set_is_dirty(false); | |
| 802 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_g)); | |
| 803 const base::FilePath old_file_path_g = old_cache_dir.AppendASCII(id_g); | |
| 804 const base::FilePath new_file_path_g = new_cache_dir.AppendASCII(id_g); | |
| 805 const base::FilePath link_path_g = link_dir.AppendASCII(id_g); | |
| 806 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_g)); | |
| 807 ASSERT_EQ(0, link(old_file_path_g.AsUTF8Unsafe().c_str(), | |
| 808 link_path_g.AsUTF8Unsafe().c_str())); | |
| 809 | |
| 810 // Entry H: pinned entry without cache file. | |
| 811 const std::string id_h = "id_h"; | |
| 812 ResourceEntry entry_h; | |
| 813 entry_h.set_local_id(id_h); | |
| 814 FileCacheEntry* file_cache_entry_h = | |
| 815 entry_h.mutable_file_specific_info()->mutable_cache_state(); | |
| 816 file_cache_entry_h->set_is_present(true); | |
| 817 file_cache_entry_h->set_is_pinned(true); | |
| 818 file_cache_entry_h->set_is_dirty(false); | |
| 819 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_h)); | |
| 820 | |
| 821 // Entry I: already migrated pinned cache file. | |
| 822 const std::string id_i = "id_i"; | |
| 823 ResourceEntry entry_i; | |
| 824 entry_i.set_local_id(id_i); | |
| 825 FileCacheEntry* file_cache_entry_i = | |
| 826 entry_i.mutable_file_specific_info()->mutable_cache_state(); | |
| 827 file_cache_entry_i->set_is_present(true); | |
| 828 file_cache_entry_i->set_is_pinned(true); | |
| 829 file_cache_entry_i->set_is_dirty(false); | |
| 830 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_i)); | |
| 831 const base::FilePath new_file_path_i = new_cache_dir.AppendASCII(id_i); | |
| 832 const base::FilePath link_path_i = link_dir.AppendASCII(id_i); | |
| 833 ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_i)); | |
| 834 ASSERT_EQ(0, link(new_file_path_i.AsUTF8Unsafe().c_str(), | |
| 835 link_path_i.AsUTF8Unsafe().c_str())); | |
| 836 | |
| 837 // Run migration. | |
| 838 ASSERT_TRUE(FileCache::MigrateCacheFiles(old_cache_dir, new_cache_dir, | |
| 839 link_dir, metadata_storage_.get())); | |
| 840 | 844 |
| 841 // Check result. | 845 // Check result. |
| 842 EXPECT_FALSE(base::PathExists(old_file_path_a)); | 846 int64_t flags_a = Lsattr(file_path_a); |
| 843 EXPECT_TRUE(base::PathExists(new_file_path_a)); | 847 int64_t flags_b = Lsattr(file_path_b); |
| 844 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_a)); | 848 int64_t flags_c = Lsattr(file_path_c); |
| 845 // MigrateCacheFiles doesn't delete invalid cache file. | 849 int64_t flags_d = Lsattr(file_path_d); |
| 846 EXPECT_TRUE(base::PathExists(old_file_path_b)); | 850 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*.
| |
| 847 EXPECT_TRUE(base::PathExists(new_file_path_c)); | 851 EXPECT_GE(flags_b, 0); |
| 848 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_c)); | 852 EXPECT_GE(flags_c, 0); |
| 849 EXPECT_FALSE(base::PathExists(old_file_path_e)); | 853 EXPECT_GE(flags_d, 0); |
| 850 EXPECT_TRUE(base::PathExists(new_file_path_e)); | 854 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.
| |
| 851 EXPECT_TRUE(base::PathExists(link_path_e)); | 855 EXPECT_EQ(flags_b & FS_NODUMP_FL, 0); |
| 852 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_e)); | 856 EXPECT_EQ(flags_c & FS_NODUMP_FL, FS_NODUMP_FL); |
| 853 EXPECT_FALSE(base::PathExists(old_file_path_f)); | 857 EXPECT_EQ(flags_d & FS_NODUMP_FL, 0); |
| 854 EXPECT_TRUE(base::PathExists(new_file_path_f)); | 858 |
| 855 EXPECT_TRUE(base::PathExists(link_path_f)); | 859 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_e, &entry_e)); |
| 856 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_f)); | 860 EXPECT_FALSE(entry_e.file_specific_info().cache_state().is_present()); |
| 857 EXPECT_FALSE(base::PathExists(old_file_path_g)); | 861 |
| 858 EXPECT_TRUE(base::PathExists(new_file_path_g)); | 862 // Check the cache dir has appropriate attributes. |
| 859 EXPECT_TRUE(base::PathExists(link_path_g)); | 863 int64_t flags_cache_dir = Lsattr(cache_files_dir_); |
| 860 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_g)); | 864 EXPECT_GE(flags_cache_dir, 0); |
| 861 EXPECT_TRUE(base::PathExists(new_file_path_i)); | 865 EXPECT_EQ(flags_cache_dir & FS_NODUMP_FL, FS_NODUMP_FL); |
| 862 EXPECT_TRUE(base::PathExists(link_path_i)); | 866 |
| 863 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_i)); | 867 std::string value = ""; |
| 868 value.resize(4); | |
| 869 char* v = string_as_array(&value); | |
| 870 ASSERT_EQ(getxattr(cache_files_dir_.value().c_str(), "user.GCacheFiles", v, | |
| 871 5), 5); | |
| 872 EXPECT_STREQ(value.c_str(), "true"); | |
| 873 } | |
| 874 | |
| 875 TEST_F(FileCacheTest, MigrationHappensOnlyOnce) { | |
| 876 ASSERT_TRUE(cache_->Initialize()); | |
| 877 EXPECT_FALSE(cache_->ShouldStartDriveCacheMigration()); | |
| 864 } | 878 } |
| 865 | 879 |
| 866 TEST_F(FileCacheTest, ClearAll) { | 880 TEST_F(FileCacheTest, ClearAll) { |
| 881 ASSERT_TRUE(cache_->Initialize()); | |
| 867 const std::string id("1a2b"); | 882 const std::string id("1a2b"); |
| 868 const std::string md5("abcdef0123456789"); | 883 const std::string md5("abcdef0123456789"); |
| 869 | 884 |
| 870 // Store an existing file. | 885 // Store an existing file. |
| 871 ResourceEntry entry; | 886 ResourceEntry entry; |
| 872 entry.set_local_id(id); | 887 entry.set_local_id(id); |
| 873 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 888 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
| 874 base::FilePath src_file; | 889 base::FilePath src_file; |
| 875 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 890 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
| 876 ASSERT_EQ(FILE_ERROR_OK, | 891 ASSERT_EQ(FILE_ERROR_OK, |
| 877 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); | 892 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); |
| 878 | 893 |
| 879 // Clear cache. | 894 // Clear cache. |
| 880 EXPECT_TRUE(cache_->ClearAll()); | 895 EXPECT_TRUE(cache_->ClearAll()); |
| 881 | 896 |
| 882 // Verify that the cache is removed. | 897 // Verify that the cache is removed. |
| 883 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); | 898 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); |
| 884 } | 899 } |
| 885 | 900 |
| 886 } // namespace internal | 901 } // namespace internal |
| 887 } // namespace drive | 902 } // namespace drive |
| OLD | NEW |