Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Side by Side Diff: components/drive/chromeos/file_cache_unittest.cc

Issue 1918243004: Mark removable Drive caches for cryptohome. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW
« components/drive/chromeos/file_cache.cc ('K') | « components/drive/chromeos/file_cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698