| // Copyright 2018 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <memory> |
| |
| #include <base/test/simple_test_tick_clock.h> |
| #include <gtest/gtest.h> |
| |
| #include "smbprovider/constants.h" |
| #include "smbprovider/metadata_cache.h" |
| |
| namespace smbprovider { |
| |
| namespace { |
| bool AreEntriesEqual(const DirectoryEntry& lhs, const DirectoryEntry& rhs) { |
| return lhs.name == rhs.name && lhs.full_path == rhs.full_path && |
| lhs.size == rhs.size && |
| lhs.last_modified_time == rhs.last_modified_time && |
| lhs.is_directory == rhs.is_directory; |
| } |
| } // namespace |
| |
| class MetadataCacheTest : public testing::Test { |
| public: |
| MetadataCacheTest() { |
| cache_lifetime_ = |
| base::TimeDelta::FromMicroseconds(kMetadataCacheLifetimeMicroseconds); |
| tick_clock_ = std::make_unique<base::SimpleTestTickClock>(); |
| cache_ = std::make_unique<MetadataCache>(tick_clock_.get(), cache_lifetime_, |
| MetadataCache::Mode::kStandard); |
| } |
| |
| ~MetadataCacheTest() override = default; |
| |
| protected: |
| base::TimeDelta cache_lifetime_; |
| std::unique_ptr<MetadataCache> cache_; |
| std::unique_ptr<base::SimpleTestTickClock> tick_clock_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MetadataCacheTest); |
| }; |
| |
| TEST_F(MetadataCacheTest, FindOnEmptyCache) { |
| DirectoryEntry found_entry; |
| EXPECT_FALSE(cache_->FindEntry("smb://server/share/not/found", &found_entry)); |
| } |
| |
| TEST_F(MetadataCacheTest, AddAndFindEntry) { |
| const std::string name = "file"; |
| const std::string full_path = "smb://server/share/dir/" + name; |
| |
| DirectoryEntry found_entry; |
| EXPECT_FALSE(cache_->FindEntry(full_path, &found_entry)); |
| |
| const int64_t expected_size = 1234; |
| const int64_t expected_date = 9999999; |
| const DirectoryEntry expected_entry(false /* is_directory */, name, full_path, |
| expected_size, expected_date); |
| cache_->AddEntry(expected_entry); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry)); |
| |
| // Verify it can be found again. |
| DirectoryEntry found_entry2; |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry2)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry2)); |
| } |
| |
| TEST_F(MetadataCacheTest, AddAndFindEntryOnExpirationBoundary) { |
| const std::string name = "file"; |
| const std::string full_path = "smb://server/share/dir/" + name; |
| |
| DirectoryEntry found_entry; |
| EXPECT_FALSE(cache_->FindEntry(full_path, &found_entry)); |
| |
| const int64_t expected_size = 1234; |
| const int64_t expected_date = 9999999; |
| const DirectoryEntry expected_entry(false /* is_directory */, name, full_path, |
| expected_size, expected_date); |
| cache_->AddEntry(expected_entry); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry)); |
| |
| // Advance the clock to the last tick where it is still valid. |
| tick_clock_->Advance( |
| base::TimeDelta::FromMicroseconds(kMetadataCacheLifetimeMicroseconds)); |
| |
| // Verify it can be found again. |
| DirectoryEntry found_entry2; |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry2)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry2)); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| |
| // Advance one more tick to expire it. |
| tick_clock_->Advance(base::TimeDelta::FromMicroseconds(1)); |
| |
| // Verify it is not found any more and removed from cache. |
| DirectoryEntry found_entry3; |
| EXPECT_FALSE(cache_->FindEntry(full_path, &found_entry3)); |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, PurgeExpiresEntries) { |
| const std::string name = "file"; |
| const std::string full_path = "smb://server/share/dir/" + name; |
| |
| DirectoryEntry found_entry; |
| EXPECT_FALSE(cache_->FindEntry(full_path, &found_entry)); |
| |
| const int64_t expected_size = 1234; |
| const int64_t expected_date = 9999999; |
| const DirectoryEntry expected_entry(false /* is_directory */, name, full_path, |
| expected_size, expected_date); |
| cache_->AddEntry(expected_entry); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry)); |
| |
| // Advance the clock to the last tick where it is still valid. |
| tick_clock_->Advance( |
| base::TimeDelta::FromMicroseconds(kMetadataCacheLifetimeMicroseconds)); |
| |
| // Purge the cache but it shouldn't expire anything |
| cache_->PurgeExpiredEntries(); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| |
| // Verify it can be found again. |
| DirectoryEntry found_entry2; |
| EXPECT_TRUE(cache_->FindEntry(full_path, &found_entry2)); |
| EXPECT_TRUE(AreEntriesEqual(expected_entry, found_entry2)); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| |
| // Advance one more tick to expire it. |
| tick_clock_->Advance(base::TimeDelta::FromMicroseconds(1)); |
| |
| // Purging should now remove the entry. |
| cache_->PurgeExpiredEntries(); |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, IsEmptyOnNewCache) { |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, ClearOnEmptyCache) { |
| EXPECT_TRUE(cache_->IsEmpty()); |
| cache_->ClearAll(); |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, ClearRemovesItems) { |
| EXPECT_TRUE(cache_->IsEmpty()); |
| |
| const std::string name = "path"; |
| const std::string full_path = "smb://server/share/some/" + name; |
| cache_->AddEntry(DirectoryEntry(false /* is_directory */, name, full_path, |
| 1234 /* size */, 999999 /* date */)); |
| |
| EXPECT_FALSE(cache_->IsEmpty()); |
| cache_->ClearAll(); |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, RemoveItemExplicitly) { |
| EXPECT_TRUE(cache_->IsEmpty()); |
| |
| const std::string name = "path"; |
| const std::string full_path = "smb://server/share/some/" + name; |
| cache_->AddEntry(DirectoryEntry(false /* is_directory */, name, full_path, |
| 1234 /* size */, 999999 /* date */)); |
| |
| EXPECT_FALSE(cache_->IsEmpty()); |
| EXPECT_TRUE(cache_->RemoveEntry(full_path)); |
| EXPECT_TRUE(cache_->IsEmpty()); |
| } |
| |
| TEST_F(MetadataCacheTest, RemoveItemThatDoesntExist) { |
| EXPECT_TRUE(cache_->IsEmpty()); |
| |
| const std::string name = "path"; |
| const std::string full_path = "smb://server/share/some/" + name; |
| cache_->AddEntry(DirectoryEntry(false /* is_directory */, name, full_path, |
| 1234 /* size */, 999999 /* date */)); |
| |
| EXPECT_FALSE(cache_->IsEmpty()); |
| |
| // Removal of an entry that doesn't exist returns false and |
| // doesn't change the cache. |
| EXPECT_FALSE(cache_->RemoveEntry(full_path + "2")); |
| EXPECT_FALSE(cache_->IsEmpty()); |
| DirectoryEntry entry; |
| EXPECT_TRUE(cache_->FindEntry(full_path, &entry)); |
| } |
| |
| } // namespace smbprovider |