diff options
author | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 00:49:38 +0000 |
---|---|---|
committer | ericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 00:49:38 +0000 |
commit | 8a00f00ab5d68ffcc998fd04d2ca343af7cdf190 (patch) | |
tree | fd464ba49db4271c76c1cf8f769a22120ad631af /net/base/host_cache_unittest.cc | |
parent | 77ae132c1bfdd986228b6f1c0d8c63baa441afdf (diff) | |
download | chromium_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.cc | 218 |
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 |