OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 |
| 5 #include "net/base/host_cache.h" |
| 6 |
| 7 #include "base/stl_util-inl.h" |
| 8 #include "base/string_util.h" |
| 9 #include "net/base/net_errors.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 namespace net { |
| 13 |
| 14 namespace { |
| 15 static const int kMaxCacheEntries = 10; |
| 16 static const int kCacheDurationMs = 10000; // 10 seconds. |
| 17 } |
| 18 |
| 19 TEST(HostCacheTest, Basic) { |
| 20 HostCache cache(kMaxCacheEntries, kCacheDurationMs); |
| 21 |
| 22 // Start at t=0. |
| 23 base::TimeTicks now; |
| 24 |
| 25 const HostCache::Entry* entry1 = NULL; // Entry for foobar.com. |
| 26 const HostCache::Entry* entry2 = NULL; // Entry for foobar2.com. |
| 27 |
| 28 EXPECT_EQ(0U, cache.size()); |
| 29 |
| 30 // Add an entry for "foobar.com" at t=0. |
| 31 EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks())); |
| 32 cache.Set("foobar.com", OK, AddressList(), now); |
| 33 entry1 = cache.Lookup("foobar.com", base::TimeTicks()); |
| 34 EXPECT_FALSE(NULL == entry1); |
| 35 EXPECT_EQ(1U, cache.size()); |
| 36 |
| 37 // Advance to t=5. |
| 38 now += base::TimeDelta::FromSeconds(5); |
| 39 |
| 40 // Add an entry for "foobar2.com" at t=5. |
| 41 EXPECT_EQ(NULL, cache.Lookup("foobar2.com", base::TimeTicks())); |
| 42 cache.Set("foobar2.com", OK, AddressList(), now); |
| 43 entry2 = cache.Lookup("foobar2.com", base::TimeTicks()); |
| 44 EXPECT_FALSE(NULL == entry1); |
| 45 EXPECT_EQ(2U, cache.size()); |
| 46 |
| 47 // Advance to t=9 |
| 48 now += base::TimeDelta::FromSeconds(4); |
| 49 |
| 50 // Verify that the entries we added are still retrievable, and usable. |
| 51 EXPECT_EQ(entry1, cache.Lookup("foobar.com", now)); |
| 52 EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now)); |
| 53 |
| 54 // Advance to t=10; entry1 is now expired. |
| 55 now += base::TimeDelta::FromSeconds(1); |
| 56 |
| 57 EXPECT_EQ(NULL, cache.Lookup("foobar.com", now)); |
| 58 EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now)); |
| 59 |
| 60 // Update entry1, so it is no longer expired. |
| 61 cache.Set("foobar.com", OK, AddressList(), now); |
| 62 // Re-uses existing entry storage. |
| 63 EXPECT_EQ(entry1, cache.Lookup("foobar.com", now)); |
| 64 EXPECT_EQ(2U, cache.size()); |
| 65 |
| 66 // Both entries should still be retrievable and usable. |
| 67 EXPECT_EQ(entry1, cache.Lookup("foobar.com", now)); |
| 68 EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now)); |
| 69 |
| 70 // Advance to t=20; both entries are now expired. |
| 71 now += base::TimeDelta::FromSeconds(10); |
| 72 |
| 73 EXPECT_EQ(NULL, cache.Lookup("foobar.com", now)); |
| 74 EXPECT_EQ(NULL, cache.Lookup("foobar2.com", now)); |
| 75 } |
| 76 |
| 77 // Try caching entries for a failed resolve attempt. |
| 78 TEST(HostCacheTest, NegativeEntry) { |
| 79 HostCache cache(kMaxCacheEntries, kCacheDurationMs); |
| 80 |
| 81 // Set t=0. |
| 82 base::TimeTicks now; |
| 83 |
| 84 EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks())); |
| 85 cache.Set("foobar.com", ERR_NAME_NOT_RESOLVED, AddressList(), now); |
| 86 EXPECT_EQ(1U, cache.size()); |
| 87 |
| 88 // We disallow use of negative entries. |
| 89 EXPECT_EQ(NULL, cache.Lookup("foobar.com", now)); |
| 90 |
| 91 // Now overwrite with a valid entry, and then overwrite with negative entry |
| 92 // again -- the valid entry should be kicked out. |
| 93 cache.Set("foobar.com", OK, AddressList(), now); |
| 94 EXPECT_FALSE(NULL == cache.Lookup("foobar.com", now)); |
| 95 cache.Set("foobar.com", ERR_NAME_NOT_RESOLVED, AddressList(), now); |
| 96 EXPECT_EQ(NULL, cache.Lookup("foobar.com", now)); |
| 97 } |
| 98 |
| 99 TEST(HostCacheTest, Compact) { |
| 100 // Initial entries limit is big enough to accomadate everything we add. |
| 101 net::HostCache cache(kMaxCacheEntries, kCacheDurationMs); |
| 102 |
| 103 EXPECT_EQ(0U, cache.size()); |
| 104 |
| 105 // t=10 |
| 106 base::TimeTicks now = base::TimeTicks() + base::TimeDelta::FromSeconds(10); |
| 107 |
| 108 // Add five valid entries at t=10. |
| 109 for (int i = 0; i < 5; ++i) { |
| 110 std::string hostname = StringPrintf("valid%d", i); |
| 111 cache.Set(hostname, OK, AddressList(), now); |
| 112 } |
| 113 EXPECT_EQ(5U, cache.size()); |
| 114 |
| 115 // Add 3 expired entries at t=0. |
| 116 for (int i = 0; i < 3; ++i) { |
| 117 std::string hostname = StringPrintf("expired%d", i); |
| 118 base::TimeTicks t = now - base::TimeDelta::FromSeconds(10); |
| 119 cache.Set(hostname, OK, AddressList(), t); |
| 120 } |
| 121 EXPECT_EQ(8U, cache.size()); |
| 122 |
| 123 // Add 2 negative entries at t=10 |
| 124 for (int i = 0; i < 2; ++i) { |
| 125 std::string hostname = StringPrintf("negative%d", i); |
| 126 cache.Set(hostname, ERR_NAME_NOT_RESOLVED, AddressList(), now); |
| 127 } |
| 128 EXPECT_EQ(10U, cache.size()); |
| 129 |
| 130 EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); |
| 131 EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); |
| 132 EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); |
| 133 EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); |
| 134 EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); |
| 135 EXPECT_TRUE(ContainsKey(cache.entries_, "expired0")); |
| 136 EXPECT_TRUE(ContainsKey(cache.entries_, "expired1")); |
| 137 EXPECT_TRUE(ContainsKey(cache.entries_, "expired2")); |
| 138 EXPECT_TRUE(ContainsKey(cache.entries_, "negative0")); |
| 139 EXPECT_TRUE(ContainsKey(cache.entries_, "negative1")); |
| 140 |
| 141 // Shrink the max constraints bound and compact. We expect the "negative" |
| 142 // and "expired" entries to have been dropped. |
| 143 cache.max_entries_ = 5; |
| 144 cache.Compact(now, NULL); |
| 145 EXPECT_EQ(5U, cache.entries_.size()); |
| 146 |
| 147 EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); |
| 148 EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); |
| 149 EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); |
| 150 EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); |
| 151 EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); |
| 152 EXPECT_FALSE(ContainsKey(cache.entries_, "expired0")); |
| 153 EXPECT_FALSE(ContainsKey(cache.entries_, "expired1")); |
| 154 EXPECT_FALSE(ContainsKey(cache.entries_, "expired2")); |
| 155 EXPECT_FALSE(ContainsKey(cache.entries_, "negative0")); |
| 156 EXPECT_FALSE(ContainsKey(cache.entries_, "negative1")); |
| 157 |
| 158 // Shrink further -- this time the compact will start dropping valid entries |
| 159 // to make space. |
| 160 cache.max_entries_ = 3; |
| 161 cache.Compact(now, NULL); |
| 162 EXPECT_EQ(3U, cache.size()); |
| 163 } |
| 164 |
| 165 // Add entries while the cache is at capacity, causing evictions. |
| 166 TEST(HostCacheTest, SetWithCompact) { |
| 167 net::HostCache cache(3, kCacheDurationMs); |
| 168 |
| 169 // t=10 |
| 170 base::TimeTicks now = |
| 171 base::TimeTicks() + base::TimeDelta::FromMilliseconds(kCacheDurationMs); |
| 172 |
| 173 cache.Set("host1", OK, AddressList(), now); |
| 174 cache.Set("host2", OK, AddressList(), now); |
| 175 cache.Set("expired", OK, AddressList(), |
| 176 now - base::TimeDelta::FromMilliseconds(kCacheDurationMs)); |
| 177 |
| 178 EXPECT_EQ(3U, cache.size()); |
| 179 |
| 180 // Should all be retrievable except "expired". |
| 181 EXPECT_FALSE(NULL == cache.Lookup("host1", now)); |
| 182 EXPECT_FALSE(NULL == cache.Lookup("host2", now)); |
| 183 EXPECT_TRUE(NULL == cache.Lookup("expired", now)); |
| 184 |
| 185 // Adding the fourth entry will cause "expired" to be evicted. |
| 186 cache.Set("host3", OK, AddressList(), now); |
| 187 EXPECT_EQ(3U, cache.size()); |
| 188 EXPECT_EQ(NULL, cache.Lookup("expired", now)); |
| 189 EXPECT_FALSE(NULL == cache.Lookup("host1", now)); |
| 190 EXPECT_FALSE(NULL == cache.Lookup("host2", now)); |
| 191 EXPECT_FALSE(NULL == cache.Lookup("host3", now)); |
| 192 |
| 193 // Add two more entries. Something should be evicted, however "host5" |
| 194 // should definitely be in there (since it was last inserted). |
| 195 cache.Set("host4", OK, AddressList(), now); |
| 196 EXPECT_EQ(3U, cache.size()); |
| 197 cache.Set("host5", OK, AddressList(), now); |
| 198 EXPECT_EQ(3U, cache.size()); |
| 199 EXPECT_FALSE(NULL == cache.Lookup("host5", now)); |
| 200 } |
| 201 |
| 202 TEST(HostCacheTest, NoCache) { |
| 203 // Disable caching. |
| 204 HostCache cache(0, kCacheDurationMs); |
| 205 EXPECT_TRUE(cache.caching_is_disabled()); |
| 206 |
| 207 // Set t=0. |
| 208 base::TimeTicks now; |
| 209 |
| 210 // Lookup and Set should have no effect. |
| 211 EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks())); |
| 212 cache.Set("foobar.com", OK, AddressList(), now); |
| 213 EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks())); |
| 214 |
| 215 EXPECT_EQ(0U, cache.size()); |
| 216 } |
| 217 |
| 218 } // namespace net |
OLD | NEW |