proxy_host_resolver_cache_unittest.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "services/proxy_resolver/proxy_host_resolver_cache.h"
  5. #include "base/test/task_environment.h"
  6. #include "net/base/ip_address.h"
  7. #include "net/base/network_isolation_key.h"
  8. #include "testing/gmock/include/gmock/gmock.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace proxy_resolver {
  11. namespace {
  12. class ProxyHostResolverCacheTest : public testing::Test {
  13. protected:
  14. base::test::TaskEnvironment task_environment_{
  15. base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  16. ProxyHostResolverCache cache_;
  17. };
  18. TEST_F(ProxyHostResolverCacheTest, SimpleNegativeLookup) {
  19. ASSERT_EQ(cache_.GetSizeForTesting(), 0u);
  20. EXPECT_FALSE(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  21. /*is_ex_operation=*/false));
  22. }
  23. TEST_F(ProxyHostResolverCacheTest, SimpleCachedLookup) {
  24. const net::IPAddress kResult(1, 2, 3, 4);
  25. cache_.StoreEntry("host.test", net::NetworkIsolationKey(),
  26. /*is_ex_operation=*/false, {kResult});
  27. EXPECT_EQ(cache_.GetSizeForTesting(), 1u);
  28. EXPECT_THAT(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  29. /*is_ex_operation=*/false),
  30. testing::Pointee(testing::ElementsAre(kResult)));
  31. }
  32. TEST_F(ProxyHostResolverCacheTest, NoResultWithNonMatchingKeyFields) {
  33. cache_.StoreEntry("host.test", net::NetworkIsolationKey(),
  34. /*is_ex_operation=*/false, {net::IPAddress(1, 2, 3, 5)});
  35. ASSERT_EQ(cache_.GetSizeForTesting(), 1u);
  36. // Non-matching hostname
  37. EXPECT_FALSE(cache_.LookupEntry("host1.test", net::NetworkIsolationKey(),
  38. /*is_ex_operation=*/false));
  39. // Non-matching isolation key
  40. EXPECT_FALSE(cache_.LookupEntry("host.test",
  41. net::NetworkIsolationKey::CreateTransient(),
  42. /*is_ex_operation=*/false));
  43. // Non-matching `is_ex_operation`
  44. EXPECT_FALSE(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  45. /*is_ex_operation=*/true));
  46. }
  47. TEST_F(ProxyHostResolverCacheTest, NoResultForExpiredLookup) {
  48. const net::IPAddress kResult(1, 2, 3, 6);
  49. cache_.StoreEntry("host.test", net::NetworkIsolationKey(),
  50. /*is_ex_operation=*/false, {kResult});
  51. task_environment_.FastForwardBy(ProxyHostResolverCache::kTtl -
  52. base::Milliseconds(5));
  53. EXPECT_EQ(cache_.GetSizeForTesting(), 1u);
  54. ASSERT_THAT(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  55. /*is_ex_operation=*/false),
  56. testing::Pointee(testing::ElementsAre(kResult)));
  57. task_environment_.FastForwardBy(base::Milliseconds(10));
  58. EXPECT_FALSE(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  59. /*is_ex_operation=*/false));
  60. // Expect expired entry to be deleted by lookup attempt.
  61. EXPECT_EQ(cache_.GetSizeForTesting(), 0u);
  62. }
  63. TEST_F(ProxyHostResolverCacheTest, EvictsOldestEntriesWhenFull) {
  64. ProxyHostResolverCache cache(/*max_entries=*/3u);
  65. // Initial entry to be deleted.
  66. cache.StoreEntry("to-be-deleted.test", net::NetworkIsolationKey(),
  67. /*is_ex_operation=*/false, /*results=*/{});
  68. // Fill to max capacity
  69. task_environment_.FastForwardBy(base::Milliseconds(5));
  70. cache.StoreEntry("other1.test", net::NetworkIsolationKey(),
  71. /*is_ex_operation=*/false, /*results=*/{});
  72. cache.StoreEntry("other2.test", net::NetworkIsolationKey(),
  73. /*is_ex_operation=*/false, /*results=*/{});
  74. // Nothing should be evicted yet.
  75. EXPECT_EQ(cache.GetSizeForTesting(), 3u);
  76. EXPECT_TRUE(cache.LookupEntry("to-be-deleted.test",
  77. net::NetworkIsolationKey(),
  78. /*is_ex_operation=*/false));
  79. EXPECT_TRUE(cache.LookupEntry("other1.test", net::NetworkIsolationKey(),
  80. /*is_ex_operation=*/false));
  81. EXPECT_TRUE(cache.LookupEntry("other2.test", net::NetworkIsolationKey(),
  82. /*is_ex_operation=*/false));
  83. // Add another entry and expect eviction of oldest.
  84. cache.StoreEntry("evictor.test", net::NetworkIsolationKey(),
  85. /*is_ex_operation=*/false, /*results=*/{});
  86. EXPECT_EQ(cache.GetSizeForTesting(), 3u);
  87. EXPECT_FALSE(cache.LookupEntry("to-be-deleted.test",
  88. net::NetworkIsolationKey(),
  89. /*is_ex_operation=*/false));
  90. EXPECT_TRUE(cache.LookupEntry("other1.test", net::NetworkIsolationKey(),
  91. /*is_ex_operation=*/false));
  92. EXPECT_TRUE(cache.LookupEntry("other2.test", net::NetworkIsolationKey(),
  93. /*is_ex_operation=*/false));
  94. EXPECT_TRUE(cache.LookupEntry("evictor.test", net::NetworkIsolationKey(),
  95. /*is_ex_operation=*/false));
  96. }
  97. TEST_F(ProxyHostResolverCacheTest, UpdatesAlreadyExistingEntryWithSameKey) {
  98. cache_.StoreEntry("host.test", net::NetworkIsolationKey(),
  99. /*is_ex_operation=*/false, /*results=*/{});
  100. ASSERT_EQ(cache_.GetSizeForTesting(), 1u);
  101. const net::IPAddress kResult(1, 2, 3, 7);
  102. cache_.StoreEntry("host.test", net::NetworkIsolationKey(),
  103. /*is_ex_operation=*/false, {kResult});
  104. EXPECT_EQ(cache_.GetSizeForTesting(), 1u);
  105. EXPECT_THAT(cache_.LookupEntry("host.test", net::NetworkIsolationKey(),
  106. /*is_ex_operation=*/false),
  107. testing::Pointee(testing::ElementsAre(kResult)));
  108. }
  109. TEST_F(ProxyHostResolverCacheTest, EntryUpdateRefreshesExpiration) {
  110. ProxyHostResolverCache cache(/*max_entries=*/2u);
  111. // Insert two entries, with "to-be-refreshed.test" as the older one.
  112. cache.StoreEntry("to-be-refreshed.test", net::NetworkIsolationKey(),
  113. /*is_ex_operation=*/false, /*results=*/{});
  114. task_environment_.FastForwardBy(base::Milliseconds(5));
  115. cache.StoreEntry("to-be-evicted.test", net::NetworkIsolationKey(),
  116. /*is_ex_operation=*/false, /*results=*/{});
  117. ASSERT_EQ(cache.GetSizeForTesting(), 2u);
  118. // Update "to-be-refreshed.test" to refresh its expiration.
  119. task_environment_.FastForwardBy(base::Milliseconds(5));
  120. cache.StoreEntry("to-be-refreshed.test", net::NetworkIsolationKey(),
  121. /*is_ex_operation=*/false, /*results=*/{});
  122. ASSERT_EQ(cache.GetSizeForTesting(), 2u);
  123. // Add another entry to force an eviction.
  124. cache.StoreEntry("evictor.test", net::NetworkIsolationKey(),
  125. /*is_ex_operation=*/false, /*results=*/{});
  126. EXPECT_EQ(cache.GetSizeForTesting(), 2u);
  127. EXPECT_FALSE(cache.LookupEntry("to-be-evicted.test",
  128. net::NetworkIsolationKey(),
  129. /*is_ex_operation=*/false));
  130. EXPECT_TRUE(cache.LookupEntry("to-be-refreshed.test",
  131. net::NetworkIsolationKey(),
  132. /*is_ex_operation=*/false));
  133. EXPECT_TRUE(cache.LookupEntry("evictor.test", net::NetworkIsolationKey(),
  134. /*is_ex_operation=*/false));
  135. }
  136. TEST_F(ProxyHostResolverCacheTest, EntryCanBeEvictedAfterUpdate) {
  137. ProxyHostResolverCache cache(/*max_entries=*/1u);
  138. // Add entry and then update it.
  139. cache.StoreEntry("host.test", net::NetworkIsolationKey(),
  140. /*is_ex_operation=*/false, /*results=*/{});
  141. ASSERT_EQ(cache.GetSizeForTesting(), 1u);
  142. task_environment_.FastForwardBy(base::Milliseconds(5));
  143. cache.StoreEntry("host.test", net::NetworkIsolationKey(),
  144. /*is_ex_operation=*/false, /*results=*/{});
  145. ASSERT_EQ(cache.GetSizeForTesting(), 1u);
  146. // Add another entry to force an eviction.
  147. task_environment_.FastForwardBy(base::Milliseconds(5));
  148. cache.StoreEntry("evictor.test", net::NetworkIsolationKey(),
  149. /*is_ex_operation=*/false, /*results=*/{});
  150. EXPECT_EQ(cache.GetSizeForTesting(), 1u);
  151. EXPECT_FALSE(cache.LookupEntry("host.test", net::NetworkIsolationKey(),
  152. /*is_ex_operation=*/false));
  153. EXPECT_TRUE(cache.LookupEntry("evictor.test", net::NetworkIsolationKey(),
  154. /*is_ex_operation=*/false));
  155. }
  156. } // namespace
  157. } // namespace proxy_resolver