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/file_cache.h" | 5 #include "components/drive/file_cache.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <sys/stat.h> |
| 10 #include <sys/types.h> |
| 11 #include <unistd.h> |
9 | 12 |
10 #include <string> | 13 #include <string> |
11 #include <vector> | 14 #include <vector> |
12 | 15 |
13 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
14 #include "base/files/file_enumerator.h" | 17 #include "base/files/file_enumerator.h" |
15 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
16 #include "base/files/scoped_temp_dir.h" | 19 #include "base/files/scoped_temp_dir.h" |
17 #include "base/md5.h" | 20 #include "base/md5.h" |
18 #include "base/path_service.h" | 21 #include "base/path_service.h" |
(...skipping 11 matching lines...) Expand all Loading... |
30 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
31 | 34 |
32 namespace drive { | 35 namespace drive { |
33 namespace internal { | 36 namespace internal { |
34 namespace { | 37 namespace { |
35 | 38 |
36 const base::FilePath::CharType kCacheFileDirectory[] = | 39 const base::FilePath::CharType kCacheFileDirectory[] = |
37 FILE_PATH_LITERAL("files"); | 40 FILE_PATH_LITERAL("files"); |
38 const base::FilePath::CharType kNewCacheFileDirectory[] = | 41 const base::FilePath::CharType kNewCacheFileDirectory[] = |
39 FILE_PATH_LITERAL("blobs"); | 42 FILE_PATH_LITERAL("blobs"); |
| 43 const base::FilePath::CharType kLinkDirectory[] = FILE_PATH_LITERAL("links"); |
40 | 44 |
41 const int kTemporaryFileSizeInBytes = 10; | 45 const int kTemporaryFileSizeInBytes = 10; |
42 | 46 |
| 47 int GetNumberOfLinks(const base::FilePath& file_path) { |
| 48 struct stat result; |
| 49 if (stat(file_path.AsUTF8Unsafe().c_str(), &result) != 0) { |
| 50 return -1; |
| 51 } |
| 52 return result.st_nlink; |
| 53 } |
| 54 |
43 } // namespace | 55 } // namespace |
44 | 56 |
45 // Tests FileCache methods working with the blocking task runner. | 57 // Tests FileCache methods working with the blocking task runner. |
46 class FileCacheTest : public testing::Test { | 58 class FileCacheTest : public testing::Test { |
47 protected: | 59 protected: |
48 void SetUp() override { | 60 void SetUp() override { |
49 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
50 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta"); | 62 const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta"); |
51 cache_files_dir_ = temp_dir_.path().Append(kCacheFileDirectory); | 63 cache_files_dir_ = temp_dir_.path().Append(kCacheFileDirectory); |
52 | 64 |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 // Test for migrating cache files from files to blobs. | 714 // Test for migrating cache files from files to blobs. |
703 TEST_F(FileCacheTest, MigrateCacheFiles) { | 715 TEST_F(FileCacheTest, MigrateCacheFiles) { |
704 // Create test files and metadata. | 716 // Create test files and metadata. |
705 base::FilePath temp_file; | 717 base::FilePath temp_file; |
706 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); | 718 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); |
707 | 719 |
708 const base::FilePath old_cache_dir = | 720 const base::FilePath old_cache_dir = |
709 temp_dir_.path().Append(kCacheFileDirectory); | 721 temp_dir_.path().Append(kCacheFileDirectory); |
710 const base::FilePath new_cache_dir = | 722 const base::FilePath new_cache_dir = |
711 temp_dir_.path().Append(kNewCacheFileDirectory); | 723 temp_dir_.path().Append(kNewCacheFileDirectory); |
| 724 const base::FilePath link_dir = temp_dir_.path().Append(kLinkDirectory); |
712 ASSERT_TRUE(base::CreateDirectory(old_cache_dir)); | 725 ASSERT_TRUE(base::CreateDirectory(old_cache_dir)); |
713 ASSERT_TRUE(base::CreateDirectory(new_cache_dir)); | 726 ASSERT_TRUE(base::CreateDirectory(new_cache_dir)); |
| 727 ASSERT_TRUE(base::CreateDirectory(link_dir)); |
714 | 728 |
715 // Entry A: cache file in old cache directory with metadata. | 729 // Entry A: cache file in old cache directory with metadata. |
716 const std::string id_a = "id_a"; | 730 const std::string id_a = "id_a"; |
717 ResourceEntry entry_a; | 731 ResourceEntry entry_a; |
718 entry_a.set_local_id(id_a); | 732 entry_a.set_local_id(id_a); |
719 entry_a.mutable_file_specific_info()->mutable_cache_state()->set_is_present( | 733 entry_a.mutable_file_specific_info()->mutable_cache_state()->set_is_present( |
720 true); | 734 true); |
721 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); | 735 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); |
722 const base::FilePath old_file_path_a = old_cache_dir.AppendASCII(id_a); | 736 const base::FilePath old_file_path_a = old_cache_dir.AppendASCII(id_a); |
723 const base::FilePath new_file_path_a = new_cache_dir.AppendASCII(id_a); | 737 const base::FilePath new_file_path_a = new_cache_dir.AppendASCII(id_a); |
(...skipping 15 matching lines...) Expand all Loading... |
739 ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_c)); | 753 ASSERT_TRUE(base::CopyFile(temp_file, new_file_path_c)); |
740 | 754 |
741 // Entry D: metadata entry without cache file. | 755 // Entry D: metadata entry without cache file. |
742 const std::string id_d = "id_d"; | 756 const std::string id_d = "id_d"; |
743 ResourceEntry entry_d; | 757 ResourceEntry entry_d; |
744 entry_d.set_local_id(id_d); | 758 entry_d.set_local_id(id_d); |
745 entry_d.mutable_file_specific_info()->mutable_cache_state()->set_is_present( | 759 entry_d.mutable_file_specific_info()->mutable_cache_state()->set_is_present( |
746 true); | 760 true); |
747 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); | 761 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); |
748 | 762 |
| 763 // Entry E: pinned cache file. |
| 764 const std::string id_e = "id_e"; |
| 765 ResourceEntry entry_e; |
| 766 entry_e.set_local_id(id_e); |
| 767 FileCacheEntry* file_cache_entry_e = |
| 768 entry_e.mutable_file_specific_info()->mutable_cache_state(); |
| 769 file_cache_entry_e->set_is_present(true); |
| 770 file_cache_entry_e->set_is_pinned(true); |
| 771 file_cache_entry_e->set_is_dirty(false); |
| 772 ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); |
| 773 const base::FilePath old_file_path_e = old_cache_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 |
| 778 // Entry F: dirty cache file. |
| 779 const std::string id_f = "id_f"; |
| 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 |
749 // Run migration. | 837 // Run migration. |
750 ASSERT_TRUE(FileCache::MigrateCacheFiles(old_cache_dir, new_cache_dir, | 838 ASSERT_TRUE(FileCache::MigrateCacheFiles(old_cache_dir, new_cache_dir, |
751 metadata_storage_.get())); | 839 link_dir, metadata_storage_.get())); |
752 | 840 |
753 // Check result. | 841 // Check result. |
754 EXPECT_FALSE(base::PathExists(old_file_path_a)); | 842 EXPECT_FALSE(base::PathExists(old_file_path_a)); |
755 EXPECT_TRUE(base::PathExists(new_file_path_a)); | 843 EXPECT_TRUE(base::PathExists(new_file_path_a)); |
| 844 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_a)); |
756 // MigrateCacheFiles doesn't delete invalid cache file. | 845 // MigrateCacheFiles doesn't delete invalid cache file. |
757 EXPECT_TRUE(base::PathExists(old_file_path_b)); | 846 EXPECT_TRUE(base::PathExists(old_file_path_b)); |
758 EXPECT_TRUE(base::PathExists(new_file_path_c)); | 847 EXPECT_TRUE(base::PathExists(new_file_path_c)); |
| 848 EXPECT_EQ(1, GetNumberOfLinks(new_file_path_c)); |
| 849 EXPECT_FALSE(base::PathExists(old_file_path_e)); |
| 850 EXPECT_TRUE(base::PathExists(new_file_path_e)); |
| 851 EXPECT_TRUE(base::PathExists(link_path_e)); |
| 852 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_e)); |
| 853 EXPECT_FALSE(base::PathExists(old_file_path_f)); |
| 854 EXPECT_TRUE(base::PathExists(new_file_path_f)); |
| 855 EXPECT_TRUE(base::PathExists(link_path_f)); |
| 856 EXPECT_EQ(2, GetNumberOfLinks(new_file_path_f)); |
| 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)); |
759 } | 864 } |
760 | 865 |
761 TEST_F(FileCacheTest, ClearAll) { | 866 TEST_F(FileCacheTest, ClearAll) { |
762 const std::string id("1a2b"); | 867 const std::string id("1a2b"); |
763 const std::string md5("abcdef0123456789"); | 868 const std::string md5("abcdef0123456789"); |
764 | 869 |
765 // Store an existing file. | 870 // Store an existing file. |
766 ResourceEntry entry; | 871 ResourceEntry entry; |
767 entry.set_local_id(id); | 872 entry.set_local_id(id); |
768 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); | 873 EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); |
769 base::FilePath src_file; | 874 base::FilePath src_file; |
770 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); | 875 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file)); |
771 ASSERT_EQ(FILE_ERROR_OK, | 876 ASSERT_EQ(FILE_ERROR_OK, |
772 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); | 877 cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); |
773 | 878 |
774 // Clear cache. | 879 // Clear cache. |
775 EXPECT_TRUE(cache_->ClearAll()); | 880 EXPECT_TRUE(cache_->ClearAll()); |
776 | 881 |
777 // Verify that the cache is removed. | 882 // Verify that the cache is removed. |
778 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); | 883 EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); |
779 } | 884 } |
780 | 885 |
781 } // namespace internal | 886 } // namespace internal |
782 } // namespace drive | 887 } // namespace drive |
OLD | NEW |