summaryrefslogtreecommitdiffstats
path: root/net/base/host_cache_unittest.cc
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 00:49:38 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 00:49:38 +0000
commit8a00f00ab5d68ffcc998fd04d2ca343af7cdf190 (patch)
treefd464ba49db4271c76c1cf8f769a22120ad631af /net/base/host_cache_unittest.cc
parent77ae132c1bfdd986228b6f1c0d8c63baa441afdf (diff)
downloadchromium_src-8a00f00ab5d68ffcc998fd04d2ca343af7cdf190.zip
chromium_src-8a00f00ab5d68ffcc998fd04d2ca343af7cdf190.tar.gz
chromium_src-8a00f00ab5d68ffcc998fd04d2ca343af7cdf190.tar.bz2
* Avoid doing concurrent DNS resolves of the same hostname in HostResolver.
* Add a 1 minute cache for host resolves. * Refactor HostResolver to handle multiple requests. * Make HostResolver a dependency of URLRequestContext. operate the HostResolver in async mode for proxy resolver (bridging to IO thread). TEST=unittests BUG=13163 Review URL: http://codereview.chromium.org/118100 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18236 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/host_cache_unittest.cc')
-rw-r--r--net/base/host_cache_unittest.cc218
1 files changed, 218 insertions, 0 deletions
diff --git a/net/base/host_cache_unittest.cc b/net/base/host_cache_unittest.cc
new file mode 100644
index 0000000..fe01e20
--- /dev/null
+++ b/net/base/host_cache_unittest.cc
@@ -0,0 +1,218 @@
+// Copyright (c) 2009 The Chromium 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 "net/base/host_cache.h"
+
+#include "base/stl_util-inl.h"
+#include "base/string_util.h"
+#include "net/base/net_errors.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+static const int kMaxCacheEntries = 10;
+static const int kCacheDurationMs = 10000; // 10 seconds.
+}
+
+TEST(HostCacheTest, Basic) {
+ HostCache cache(kMaxCacheEntries, kCacheDurationMs);
+
+ // Start at t=0.
+ base::TimeTicks now;
+
+ const HostCache::Entry* entry1 = NULL; // Entry for foobar.com.
+ const HostCache::Entry* entry2 = NULL; // Entry for foobar2.com.
+
+ EXPECT_EQ(0U, cache.size());
+
+ // Add an entry for "foobar.com" at t=0.
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks()));
+ cache.Set("foobar.com", OK, AddressList(), now);
+ entry1 = cache.Lookup("foobar.com", base::TimeTicks());
+ EXPECT_FALSE(NULL == entry1);
+ EXPECT_EQ(1U, cache.size());
+
+ // Advance to t=5.
+ now += base::TimeDelta::FromSeconds(5);
+
+ // Add an entry for "foobar2.com" at t=5.
+ EXPECT_EQ(NULL, cache.Lookup("foobar2.com", base::TimeTicks()));
+ cache.Set("foobar2.com", OK, AddressList(), now);
+ entry2 = cache.Lookup("foobar2.com", base::TimeTicks());
+ EXPECT_FALSE(NULL == entry1);
+ EXPECT_EQ(2U, cache.size());
+
+ // Advance to t=9
+ now += base::TimeDelta::FromSeconds(4);
+
+ // Verify that the entries we added are still retrievable, and usable.
+ EXPECT_EQ(entry1, cache.Lookup("foobar.com", now));
+ EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now));
+
+ // Advance to t=10; entry1 is now expired.
+ now += base::TimeDelta::FromSeconds(1);
+
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", now));
+ EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now));
+
+ // Update entry1, so it is no longer expired.
+ cache.Set("foobar.com", OK, AddressList(), now);
+ // Re-uses existing entry storage.
+ EXPECT_EQ(entry1, cache.Lookup("foobar.com", now));
+ EXPECT_EQ(2U, cache.size());
+
+ // Both entries should still be retrievable and usable.
+ EXPECT_EQ(entry1, cache.Lookup("foobar.com", now));
+ EXPECT_EQ(entry2, cache.Lookup("foobar2.com", now));
+
+ // Advance to t=20; both entries are now expired.
+ now += base::TimeDelta::FromSeconds(10);
+
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", now));
+ EXPECT_EQ(NULL, cache.Lookup("foobar2.com", now));
+}
+
+// Try caching entries for a failed resolve attempt.
+TEST(HostCacheTest, NegativeEntry) {
+ HostCache cache(kMaxCacheEntries, kCacheDurationMs);
+
+ // Set t=0.
+ base::TimeTicks now;
+
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks()));
+ cache.Set("foobar.com", ERR_NAME_NOT_RESOLVED, AddressList(), now);
+ EXPECT_EQ(1U, cache.size());
+
+ // We disallow use of negative entries.
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", now));
+
+ // Now overwrite with a valid entry, and then overwrite with negative entry
+ // again -- the valid entry should be kicked out.
+ cache.Set("foobar.com", OK, AddressList(), now);
+ EXPECT_FALSE(NULL == cache.Lookup("foobar.com", now));
+ cache.Set("foobar.com", ERR_NAME_NOT_RESOLVED, AddressList(), now);
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", now));
+}
+
+TEST(HostCacheTest, Compact) {
+ // Initial entries limit is big enough to accomadate everything we add.
+ net::HostCache cache(kMaxCacheEntries, kCacheDurationMs);
+
+ EXPECT_EQ(0U, cache.size());
+
+ // t=10
+ base::TimeTicks now = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
+
+ // Add five valid entries at t=10.
+ for (int i = 0; i < 5; ++i) {
+ std::string hostname = StringPrintf("valid%d", i);
+ cache.Set(hostname, OK, AddressList(), now);
+ }
+ EXPECT_EQ(5U, cache.size());
+
+ // Add 3 expired entries at t=0.
+ for (int i = 0; i < 3; ++i) {
+ std::string hostname = StringPrintf("expired%d", i);
+ base::TimeTicks t = now - base::TimeDelta::FromSeconds(10);
+ cache.Set(hostname, OK, AddressList(), t);
+ }
+ EXPECT_EQ(8U, cache.size());
+
+ // Add 2 negative entries at t=10
+ for (int i = 0; i < 2; ++i) {
+ std::string hostname = StringPrintf("negative%d", i);
+ cache.Set(hostname, ERR_NAME_NOT_RESOLVED, AddressList(), now);
+ }
+ EXPECT_EQ(10U, cache.size());
+
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid0"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid1"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid2"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid3"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid4"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "expired0"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "expired1"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "expired2"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "negative0"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "negative1"));
+
+ // Shrink the max constraints bound and compact. We expect the "negative"
+ // and "expired" entries to have been dropped.
+ cache.max_entries_ = 5;
+ cache.Compact(now, NULL);
+ EXPECT_EQ(5U, cache.entries_.size());
+
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid0"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid1"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid2"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid3"));
+ EXPECT_TRUE(ContainsKey(cache.entries_, "valid4"));
+ EXPECT_FALSE(ContainsKey(cache.entries_, "expired0"));
+ EXPECT_FALSE(ContainsKey(cache.entries_, "expired1"));
+ EXPECT_FALSE(ContainsKey(cache.entries_, "expired2"));
+ EXPECT_FALSE(ContainsKey(cache.entries_, "negative0"));
+ EXPECT_FALSE(ContainsKey(cache.entries_, "negative1"));
+
+ // Shrink further -- this time the compact will start dropping valid entries
+ // to make space.
+ cache.max_entries_ = 3;
+ cache.Compact(now, NULL);
+ EXPECT_EQ(3U, cache.size());
+}
+
+// Add entries while the cache is at capacity, causing evictions.
+TEST(HostCacheTest, SetWithCompact) {
+ net::HostCache cache(3, kCacheDurationMs);
+
+ // t=10
+ base::TimeTicks now =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(kCacheDurationMs);
+
+ cache.Set("host1", OK, AddressList(), now);
+ cache.Set("host2", OK, AddressList(), now);
+ cache.Set("expired", OK, AddressList(),
+ now - base::TimeDelta::FromMilliseconds(kCacheDurationMs));
+
+ EXPECT_EQ(3U, cache.size());
+
+ // Should all be retrievable except "expired".
+ EXPECT_FALSE(NULL == cache.Lookup("host1", now));
+ EXPECT_FALSE(NULL == cache.Lookup("host2", now));
+ EXPECT_TRUE(NULL == cache.Lookup("expired", now));
+
+ // Adding the fourth entry will cause "expired" to be evicted.
+ cache.Set("host3", OK, AddressList(), now);
+ EXPECT_EQ(3U, cache.size());
+ EXPECT_EQ(NULL, cache.Lookup("expired", now));
+ EXPECT_FALSE(NULL == cache.Lookup("host1", now));
+ EXPECT_FALSE(NULL == cache.Lookup("host2", now));
+ EXPECT_FALSE(NULL == cache.Lookup("host3", now));
+
+ // Add two more entries. Something should be evicted, however "host5"
+ // should definitely be in there (since it was last inserted).
+ cache.Set("host4", OK, AddressList(), now);
+ EXPECT_EQ(3U, cache.size());
+ cache.Set("host5", OK, AddressList(), now);
+ EXPECT_EQ(3U, cache.size());
+ EXPECT_FALSE(NULL == cache.Lookup("host5", now));
+}
+
+TEST(HostCacheTest, NoCache) {
+ // Disable caching.
+ HostCache cache(0, kCacheDurationMs);
+ EXPECT_TRUE(cache.caching_is_disabled());
+
+ // Set t=0.
+ base::TimeTicks now;
+
+ // Lookup and Set should have no effect.
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks()));
+ cache.Set("foobar.com", OK, AddressList(), now);
+ EXPECT_EQ(NULL, cache.Lookup("foobar.com", base::TimeTicks()));
+
+ EXPECT_EQ(0U, cache.size());
+}
+
+} // namespace net