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

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

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

Powered by Google App Engine
This is Rietveld 408576698