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

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 <linux/fs.h>
7 #include <stddef.h> 8 #include <stddef.h>
8 #include <stdint.h> 9 #include <stdint.h>
9 #include <sys/stat.h> 10 #include <sys/ioctl.h>
10 #include <sys/types.h> 11 #include <sys/xattr.h>
11 #include <unistd.h>
12 12
13 #include <string> 13 #include <string>
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/callback_helpers.h" 16 #include "base/callback_helpers.h"
17 #include "base/files/file.h"
17 #include "base/files/file_enumerator.h" 18 #include "base/files/file_enumerator.h"
18 #include "base/files/file_util.h" 19 #include "base/files/file_util.h"
19 #include "base/files/scoped_temp_dir.h" 20 #include "base/files/scoped_temp_dir.h"
20 #include "base/md5.h" 21 #include "base/md5.h"
21 #include "base/path_service.h" 22 #include "base/path_service.h"
22 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
24 #include "base/stl_util.h"
23 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
24 #include "base/thread_task_runner_handle.h" 26 #include "base/thread_task_runner_handle.h"
25 #include "base/time/time.h" 27 #include "base/time/time.h"
26 #include "components/drive/chromeos/drive_test_util.h" 28 #include "components/drive/chromeos/drive_test_util.h"
27 #include "components/drive/chromeos/fake_free_disk_space_getter.h" 29 #include "components/drive/chromeos/fake_free_disk_space_getter.h"
28 #include "components/drive/drive.pb.h" 30 #include "components/drive/drive.pb.h"
29 #include "components/drive/file_system_core_util.h" 31 #include "components/drive/file_system_core_util.h"
30 #include "components/drive/resource_metadata_storage.h" 32 #include "components/drive/resource_metadata_storage.h"
31 #include "content/public/test/test_browser_thread_bundle.h" 33 #include "content/public/test/test_browser_thread_bundle.h"
32 #include "google_apis/drive/test_util.h" 34 #include "google_apis/drive/test_util.h"
33 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
34 36
35 namespace drive { 37 namespace drive {
36 namespace internal { 38 namespace internal {
37 namespace { 39 namespace {
38 40
39 const base::FilePath::CharType kCacheFileDirectory[] = 41 const base::FilePath::CharType kCacheFileDirectory[] =
40 FILE_PATH_LITERAL("files"); 42 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 43
45 const int kTemporaryFileSizeInBytes = 10; 44 const int kTemporaryFileSizeInBytes = 10;
46 45
47 int GetNumberOfLinks(const base::FilePath& file_path) { 46 int64_t GetFileAttributes(const base::FilePath& file_path) {
48 struct stat result; 47 base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
49 if (stat(file_path.AsUTF8Unsafe().c_str(), &result) != 0) { 48 if (!file.IsValid()) {
49 ADD_FAILURE() << "Failed to open file: " << file_path.value();
50 return -1; 50 return -1;
51 } 51 }
52 return result.st_nlink; 52 long flags = 0; // NOLINT long
53 if (ioctl(file.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) < 0) {
54 ADD_FAILURE() << "Failed to get attributes: " << file_path.value();
55 return -1;
56 }
57 return static_cast<int64_t>(flags);
58 }
59
60 bool HasRemovableFlag(const base::FilePath& file_path) {
61 return (GetFileAttributes(file_path) & FS_NODUMP_FL) == FS_NODUMP_FL;
53 } 62 }
54 63
55 } // namespace 64 } // namespace
56 65
57 // Tests FileCache methods working with the blocking task runner. 66 // Tests FileCache methods working with the blocking task runner.
58 class FileCacheTest : public testing::Test { 67 class FileCacheTest : public testing::Test {
59 protected: 68 protected:
60 void SetUp() override { 69 void SetUp() override {
61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 70 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
62 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta"); 71 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta");
(...skipping 12 matching lines...) Expand all
75 cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_, 84 cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_,
76 base::ThreadTaskRunnerHandle::Get().get(), 85 base::ThreadTaskRunnerHandle::Get().get(),
77 fake_free_disk_space_getter_.get())); 86 fake_free_disk_space_getter_.get()));
78 ASSERT_TRUE(cache_->Initialize()); 87 ASSERT_TRUE(cache_->Initialize());
79 } 88 }
80 89
81 static bool RenameCacheFilesToNewFormat(FileCache* cache) { 90 static bool RenameCacheFilesToNewFormat(FileCache* cache) {
82 return cache->RenameCacheFilesToNewFormat(); 91 return cache->RenameCacheFilesToNewFormat();
83 } 92 }
84 93
94 base::FilePath GetCacheFilePath(const std::string& id) {
95 return cache_->GetCacheFilePath(id);
96 }
97
85 base::FilePath AddTestEntry(const std::string id, 98 base::FilePath AddTestEntry(const std::string id,
86 const std::string md5, 99 const std::string md5,
87 const time_t last_accessed, 100 const time_t last_accessed,
88 const base::FilePath& src_file) { 101 const base::FilePath& src_file) {
89 ResourceEntry entry; 102 ResourceEntry entry;
90 entry.set_local_id(id); 103 entry.set_local_id(id);
91 entry.mutable_file_info()->set_last_accessed(last_accessed); 104 entry.mutable_file_info()->set_last_accessed(last_accessed);
92 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); 105 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
93 EXPECT_EQ(FILE_ERROR_OK, 106 EXPECT_EQ(FILE_ERROR_OK,
94 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); 107 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); 428 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
416 429
417 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 430 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
418 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); 431 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
419 EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5()); 432 EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5());
420 433
421 base::FilePath cache_file_path; 434 base::FilePath cache_file_path;
422 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); 435 EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
423 EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path)); 436 EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path));
424 437
438 base::FilePath dest_file_path = GetCacheFilePath(id);
439 EXPECT_TRUE(HasRemovableFlag((dest_file_path)));
440
425 // Store a non-existent file. 441 // Store a non-existent file.
426 EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store( 442 EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store(
427 id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"), 443 id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"),
428 FileCache::FILE_OPERATION_COPY)); 444 FileCache::FILE_OPERATION_COPY));
429 445
430 // Passing empty MD5 marks the entry as dirty. 446 // Passing empty MD5 marks the entry as dirty.
431 EXPECT_EQ(FILE_ERROR_OK, cache_->Store( 447 EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
432 id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY)); 448 id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY));
433 449
434 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 450 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
435 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); 451 EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
436 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); 452 EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
437 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); 453 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
454 EXPECT_FALSE(HasRemovableFlag((dest_file_path)));
438 455
439 // No free space available. 456 // No free space available.
440 fake_free_disk_space_getter_->set_default_value(0); 457 fake_free_disk_space_getter_->set_default_value(0);
441 458
442 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store( 459 EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store(
443 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); 460 id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
444 } 461 }
445 462
446 TEST_F(FileCacheTest, PinAndUnpin) { 463 TEST_F(FileCacheTest, PinAndUnpin) {
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 = GetCacheFilePath(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 EXPECT_TRUE(HasRemovableFlag((dest_file_path)));
463 482
464 // Pin the existing file. 483 // Pin the existing file.
465 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); 484 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
466 485
467 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 486 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
468 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); 487 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
488 EXPECT_FALSE(HasRemovableFlag((dest_file_path)));
469 489
470 // Unpin the file. 490 // Unpin the file.
471 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id)); 491 EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id));
472 492
473 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 493 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
474 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); 494 EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
495 EXPECT_TRUE(HasRemovableFlag((dest_file_path)));
475 496
476 // Pin a non-present file. 497 // Pin a non-present file.
477 std::string id_non_present = "id_non_present"; 498 std::string id_non_present = "id_non_present";
478 entry.Clear(); 499 entry.Clear();
479 entry.set_local_id(id_non_present); 500 entry.set_local_id(id_non_present);
480 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); 501 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
481 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present)); 502 EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present));
482 503
483 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); 504 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry));
484 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); 505 EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); 554 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
534 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, 555 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
535 FileCache::FILE_OPERATION_COPY)); 556 FileCache::FILE_OPERATION_COPY));
536 EXPECT_EQ(0, entry.file_info().last_modified()); 557 EXPECT_EQ(0, entry.file_info().last_modified());
537 558
538 // Entry is not dirty nor opened. 559 // Entry is not dirty nor opened.
539 EXPECT_FALSE(cache_->IsOpenedForWrite(id)); 560 EXPECT_FALSE(cache_->IsOpenedForWrite(id));
540 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 561 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
541 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); 562 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
542 563
564 const base::FilePath dest_file = GetCacheFilePath(id);
565 EXPECT_TRUE(HasRemovableFlag((dest_file)));
566
543 // Open (1). 567 // Open (1).
544 std::unique_ptr<base::ScopedClosureRunner> file_closer1; 568 std::unique_ptr<base::ScopedClosureRunner> file_closer1;
545 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1)); 569 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1));
546 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); 570 EXPECT_TRUE(cache_->IsOpenedForWrite(id));
547 571
548 // Entry is dirty. 572 // Entry is dirty.
549 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 573 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
550 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); 574 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
575 EXPECT_FALSE(HasRemovableFlag((dest_file)));
551 576
552 // Open (2). 577 // Open (2).
553 std::unique_ptr<base::ScopedClosureRunner> file_closer2; 578 std::unique_ptr<base::ScopedClosureRunner> file_closer2;
554 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2)); 579 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2));
555 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); 580 EXPECT_TRUE(cache_->IsOpenedForWrite(id));
556 581
557 // Close (1). 582 // Close (1).
558 file_closer1.reset(); 583 file_closer1.reset();
559 base::RunLoop().RunUntilIdle(); 584 base::RunLoop().RunUntilIdle();
560 EXPECT_TRUE(cache_->IsOpenedForWrite(id)); 585 EXPECT_TRUE(cache_->IsOpenedForWrite(id));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 base::FilePath src_file; 644 base::FilePath src_file;
620 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); 645 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
621 646
622 const std::string id = "id"; 647 const std::string id = "id";
623 ResourceEntry entry; 648 ResourceEntry entry;
624 entry.set_local_id(id); 649 entry.set_local_id(id);
625 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); 650 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
626 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, 651 ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
627 FileCache::FILE_OPERATION_COPY)); 652 FileCache::FILE_OPERATION_COPY));
628 653
654 const base::FilePath dest_file = GetCacheFilePath(id);
655 EXPECT_TRUE(HasRemovableFlag((dest_file)));
656
629 // Open the file. 657 // Open the file.
630 std::unique_ptr<base::ScopedClosureRunner> file_closer; 658 std::unique_ptr<base::ScopedClosureRunner> file_closer;
631 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); 659 EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
632 660
633 // Entry is dirty. 661 // Entry is dirty.
634 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 662 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
635 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); 663 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
664 EXPECT_FALSE(HasRemovableFlag((dest_file)));
636 665
637 // Cannot clear the dirty bit of an opened entry. 666 // Cannot clear the dirty bit of an opened entry.
638 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id)); 667 EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id));
668 EXPECT_FALSE(HasRemovableFlag((dest_file)));
639 669
640 // Close the file and clear the dirty bit. 670 // Close the file and clear the dirty bit.
641 file_closer.reset(); 671 file_closer.reset();
642 base::RunLoop().RunUntilIdle(); 672 base::RunLoop().RunUntilIdle();
643 EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id)); 673 EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id));
644 674
645 // Entry is not dirty. 675 // Entry is not dirty.
646 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); 676 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
647 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); 677 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
678 EXPECT_TRUE(HasRemovableFlag((dest_file)));
648 } 679 }
649 680
650 TEST_F(FileCacheTest, Remove) { 681 TEST_F(FileCacheTest, Remove) {
651 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat"); 682 const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
652 const std::string src_contents = "test"; 683 const std::string src_contents = "test";
653 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, 684 EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
654 src_contents)); 685 src_contents));
655 std::string id("id"); 686 std::string id("id");
656 std::string md5(base::MD5String(src_contents)); 687 std::string md5(base::MD5String(src_contents));
657 688
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 contents.clear(); 735 contents.clear();
705 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"), 736 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
706 &contents)); 737 &contents));
707 EXPECT_EQ("koo", contents); 738 EXPECT_EQ("koo", contents);
708 contents.clear(); 739 contents.clear();
709 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"), 740 EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
710 &contents)); 741 &contents));
711 EXPECT_EQ("kyu", contents); 742 EXPECT_EQ("kyu", contents);
712 } 743 }
713 744
714 // Test for migrating cache files from files to blobs. 745 // Test for migrating cache files resolving inconsistency in metadata.
715 TEST_F(FileCacheTest, MigrateCacheFiles) { 746 TEST_F(FileCacheTest, MigrateCacheFiles) {
716 // Create test files and metadata. 747 // Create test files and metadata.
717 base::FilePath temp_file; 748 base::FilePath temp_file;
718 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); 749 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file));
719 750
720 const base::FilePath old_cache_dir = 751 // 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"; 752 const std::string id_a = "id_a";
731 ResourceEntry entry_a; 753 ResourceEntry entry_a;
732 entry_a.set_local_id(id_a); 754 entry_a.set_local_id(id_a);
733 entry_a.mutable_file_specific_info()->mutable_cache_state()->set_is_present( 755 FileCacheEntry* file_cache_entry_a =
734 true); 756 entry_a.mutable_file_specific_info()->mutable_cache_state();
757 file_cache_entry_a->set_is_present(true);
758 file_cache_entry_a->set_is_pinned(true);
759 file_cache_entry_a->set_is_dirty(false);
735 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); 760 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a));
736 const base::FilePath old_file_path_a = old_cache_dir.AppendASCII(id_a); 761 const base::FilePath file_path_a = GetCacheFilePath(id_a);
737 const base::FilePath new_file_path_a = new_cache_dir.AppendASCII(id_a); 762 ASSERT_TRUE(base::CopyFile(temp_file, file_path_a));
738 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_a));
739 763
740 // Entry B: cache file in old cache directory without metadata. 764 // Entry B: dirty cache file.
741 const std::string id_b = "id_b"; 765 const std::string id_b = "id_b";
742 const base::FilePath old_file_path_b = old_cache_dir.AppendASCII(id_b); 766 ResourceEntry entry_b;
743 ASSERT_TRUE(base::CopyFile(temp_file, old_file_path_b)); 767 entry_b.set_local_id(id_b);
768 FileCacheEntry* file_cache_entry_b =
769 entry_b.mutable_file_specific_info()->mutable_cache_state();
770 file_cache_entry_b->set_is_present(true);
771 file_cache_entry_b->set_is_pinned(false);
772 file_cache_entry_b->set_is_dirty(true);
773 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_b));
774 const base::FilePath file_path_b = GetCacheFilePath(id_b);
775 ASSERT_TRUE(base::CopyFile(temp_file, file_path_b));
744 776
745 // Entry C: already migrated cache file. 777 // Entry C: not pinned nor dirty cache file.
746 const std::string id_c = "id_c"; 778 const std::string id_c = "id_c";
747 ResourceEntry entry_c; 779 ResourceEntry entry_c;
748 entry_c.set_local_id(id_c); 780 entry_c.set_local_id(id_c);
749 entry_c.mutable_file_specific_info()->mutable_cache_state()->set_is_present( 781 FileCacheEntry* file_cache_entry_c =
750 true); 782 entry_c.mutable_file_specific_info()->mutable_cache_state();
783 file_cache_entry_c->set_is_present(true);
784 file_cache_entry_c->set_is_pinned(false);
785 file_cache_entry_c->set_is_dirty(false);
751 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c)); 786 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c));
752 const base::FilePath new_file_path_c = new_cache_dir.AppendASCII(id_c); 787 const base::FilePath file_path_c = GetCacheFilePath(id_c);
753 ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_c)); 788 ASSERT_TRUE(base::CopyFile(temp_file, file_path_c));
754 789
755 // Entry D: metadata entry without cache file. 790 // Entry D: pinned cache file somehow having removable flag.
756 const std::string id_d = "id_d"; 791 const std::string id_d = "id_d";
757 ResourceEntry entry_d; 792 ResourceEntry entry_d;
758 entry_d.set_local_id(id_d); 793 entry_d.set_local_id(id_d);
759 entry_d.mutable_file_specific_info()->mutable_cache_state()->set_is_present( 794 FileCacheEntry* file_cache_entry_d =
760 true); 795 entry_d.mutable_file_specific_info()->mutable_cache_state();
796 file_cache_entry_d->set_is_present(true);
797 file_cache_entry_d->set_is_pinned(true);
798 file_cache_entry_d->set_is_dirty(false);
761 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); 799 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d));
800 const base::FilePath file_path_d = GetCacheFilePath(id_d);
801 ASSERT_TRUE(base::CopyFile(temp_file, file_path_d));
762 802
763 // Entry E: pinned cache file. 803 // Set removable flag.
804 int64_t flags = GetFileAttributes(file_path_d);
805 ASSERT_GE(flags, 0);
806 flags |= FS_NODUMP_FL;
807 base::File file_d(file_path_d, base::File::FLAG_OPEN | base::File::FLAG_READ);
808 ASSERT_EQ(ioctl(file_d.GetPlatformFile(), FS_IOC_SETFLAGS, &flags), 0);
809
810 // Entry E: there is no file; removed by cryptohome.
764 const std::string id_e = "id_e"; 811 const std::string id_e = "id_e";
765 ResourceEntry entry_e; 812 ResourceEntry entry_e;
766 entry_e.set_local_id(id_e); 813 entry_e.set_local_id(id_e);
767 FileCacheEntry* file_cache_entry_e = 814 FileCacheEntry* file_cache_entry_e =
768 entry_e.mutable_file_specific_info()->mutable_cache_state(); 815 entry_e.mutable_file_specific_info()->mutable_cache_state();
769 file_cache_entry_e->set_is_present(true); 816 file_cache_entry_e->set_is_present(true);
770 file_cache_entry_e->set_is_pinned(true); 817 file_cache_entry_e->set_is_pinned(false);
771 file_cache_entry_e->set_is_dirty(false); 818 file_cache_entry_e->set_is_dirty(false);
772 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); 819 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e));
773 const base::FilePath old_file_path_e = old_cache_dir.AppendASCII(id_e); 820 const base::FilePath file_path_e = GetCacheFilePath(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 821
778 // Entry F: dirty cache file. 822 // Entry F: there is a file, but metadata says not.
779 const std::string id_f = "id_f"; 823 const std::string id_f = "id_f";
780 ResourceEntry entry_f; 824 ResourceEntry entry_f;
781 entry_f.set_local_id(id_f); 825 entry_f.set_local_id(id_f);
782 FileCacheEntry* file_cache_entry_f = 826 entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present(
783 entry_f.mutable_file_specific_info()->mutable_cache_state(); 827 false);
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)); 828 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f));
788 const base::FilePath old_file_path_f = old_cache_dir.AppendASCII(id_f); 829 const base::FilePath file_path_f = GetCacheFilePath(id_f);
789 const base::FilePath new_file_path_f = new_cache_dir.AppendASCII(id_f); 830 ASSERT_TRUE(base::CopyFile(temp_file, file_path_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 831
793 // Entry G: partially migrated pinned cache file. 832 // Entry G: no file nor metadata.
794 const std::string id_g = "id_g"; 833 const std::string id_g = "id_g";
795 ResourceEntry entry_g; 834 ResourceEntry entry_g;
796 entry_g.set_local_id(id_g); 835 entry_g.set_local_id(id_g);
797 FileCacheEntry* file_cache_entry_g = 836 entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present(
798 entry_g.mutable_file_specific_info()->mutable_cache_state(); 837 false);
799 file_cache_entry_g->set_is_present(true); 838 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f));
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 839
810 // Entry H: pinned entry without cache file. 840 // Initialize resolves metadta inconsistency and invokes migration.
811 const std::string id_h = "id_h"; 841 ASSERT_TRUE(cache_->Initialize());
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 842
841 // Check result. 843 // Check result.
842 EXPECT_FALSE(base::PathExists(old_file_path_a)); 844 EXPECT_FALSE(HasRemovableFlag(file_path_a));
843 EXPECT_TRUE(base::PathExists(new_file_path_a)); 845 EXPECT_FALSE(HasRemovableFlag((file_path_b)));
844 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_a)); 846 EXPECT_TRUE(HasRemovableFlag((file_path_c)));
845 // MigrateCacheFiles doesn't delete invalid cache file. 847 EXPECT_FALSE(HasRemovableFlag((file_path_d)));
846 EXPECT_TRUE(base::PathExists(old_file_path_b)); 848 EXPECT_FALSE(base::PathExists(file_path_f));
847 EXPECT_TRUE(base::PathExists(new_file_path_c)); 849
848 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_c)); 850 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_e, &entry_e));
849 EXPECT_FALSE(base::PathExists(old_file_path_e)); 851 EXPECT_FALSE(entry_e.file_specific_info().cache_state().is_present());
850 EXPECT_TRUE(base::PathExists(new_file_path_e)); 852 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_f, &entry_f));
851 EXPECT_TRUE(base::PathExists(link_path_e)); 853 EXPECT_FALSE(entry_f.file_specific_info().cache_state().is_present());
852 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_e)); 854
853 EXPECT_FALSE(base::PathExists(old_file_path_f)); 855 // Check the cache dir has appropriate attributes.
854 EXPECT_TRUE(base::PathExists(new_file_path_f)); 856 EXPECT_TRUE(HasRemovableFlag((cache_files_dir_)));
855 EXPECT_TRUE(base::PathExists(link_path_f)); 857 EXPECT_GE(getxattr(cache_files_dir_.value().c_str(),
856 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_f)); 858 FileCache::kGCacheFilesAttribute, nullptr, 0), 0);
857 EXPECT_FALSE(base::PathExists(old_file_path_g));
858 EXPECT_TRUE(base::PathExists(new_file_path_g));
859 EXPECT_TRUE(base::PathExists(link_path_g));
860 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_g));
861 EXPECT_TRUE(base::PathExists(new_file_path_i));
862 EXPECT_TRUE(base::PathExists(link_path_i));
863 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_i));
864 } 859 }
865 860
866 TEST_F(FileCacheTest, ClearAll) { 861 TEST_F(FileCacheTest, ClearAll) {
867 const std::string id("1a2b"); 862 const std::string id("1a2b");
868 const std::string md5("abcdef0123456789"); 863 const std::string md5("abcdef0123456789");
869 864
870 // Store an existing file. 865 // Store an existing file.
871 ResourceEntry entry; 866 ResourceEntry entry;
872 entry.set_local_id(id); 867 entry.set_local_id(id);
873 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); 868 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
874 base::FilePath src_file; 869 base::FilePath src_file;
875 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); 870 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
876 ASSERT_EQ(FILE_ERROR_OK, 871 ASSERT_EQ(FILE_ERROR_OK,
877 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); 872 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
878 873
879 // Clear cache. 874 // Clear cache.
880 EXPECT_TRUE(cache_->ClearAll()); 875 EXPECT_TRUE(cache_->ClearAll());
881 876
882 // Verify that the cache is removed. 877 // Verify that the cache is removed.
883 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); 878 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_));
884 } 879 }
885 880
886 } // namespace internal 881 } // namespace internal
887 } // namespace drive 882 } // 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