Index: net/base/host_resolver_unittest.cc |
=================================================================== |
--- net/base/host_resolver_unittest.cc (revision 18360) |
+++ net/base/host_resolver_unittest.cc (working copy) |
@@ -18,6 +18,7 @@ |
#include "base/ref_counted.h" |
#include "net/base/address_list.h" |
#include "net/base/completion_callback.h" |
+#include "net/base/dns_resolution_observer.h" |
#include "net/base/host_resolver_unittest.h" |
#include "net/base/net_errors.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -82,25 +83,35 @@ |
const std::string& hostname, |
int port, |
Delegate* delegate) |
- : hostname_(hostname), port_(port), resolver_(resolver), |
- delegate_(delegate), |
+ : info_(hostname, port), resolver_(resolver), delegate_(delegate), |
ALLOW_THIS_IN_INITIALIZER_LIST( |
callback_(this, &ResolveRequest::OnLookupFinished)) { |
// Start the request. |
- int err = resolver->Resolve(hostname, port, &addrlist_, &callback_, &req_); |
+ int err = resolver->Resolve(info_, &addrlist_, &callback_, &req_); |
EXPECT_EQ(net::ERR_IO_PENDING, err); |
} |
+ ResolveRequest(net::HostResolver* resolver, |
+ const net::HostResolver::RequestInfo& info, |
+ Delegate* delegate) |
+ : info_(info), resolver_(resolver), delegate_(delegate), |
+ ALLOW_THIS_IN_INITIALIZER_LIST( |
+ callback_(this, &ResolveRequest::OnLookupFinished)) { |
+ // Start the request. |
+ int err = resolver->Resolve(info, &addrlist_, &callback_, &req_); |
+ EXPECT_EQ(net::ERR_IO_PENDING, err); |
+ } |
+ |
void Cancel() { |
resolver_->CancelRequest(req_); |
} |
const std::string& hostname() const { |
- return hostname_; |
+ return info_.hostname(); |
} |
int port() const { |
- return port_; |
+ return info_.port(); |
} |
int result() const { |
@@ -122,8 +133,7 @@ |
} |
// The request details. |
- std::string hostname_; |
- int port_; |
+ net::HostResolver::RequestInfo info_; |
net::HostResolver::Request* req_; |
// The result of the resolve. |
@@ -168,8 +178,8 @@ |
mapper->AddRule("just.testing", "192.168.1.42"); |
ScopedHostMapper scoped_mapper(mapper.get()); |
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, NULL, |
- NULL); |
+ net::HostResolver::RequestInfo info("just.testing", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
EXPECT_EQ(net::OK, err); |
const struct addrinfo* ainfo = adrlist.head(); |
@@ -191,8 +201,8 @@ |
mapper->AddRule("just.testing", "192.168.1.42"); |
ScopedHostMapper scoped_mapper(mapper.get()); |
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, |
- &callback_, NULL); |
+ net::HostResolver::RequestInfo info("just.testing", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL); |
EXPECT_EQ(net::ERR_IO_PENDING, err); |
MessageLoop::current()->Run(); |
@@ -219,8 +229,8 @@ |
net::AddressList adrlist; |
const int kPortnum = 80; |
- int err = host_resolver.Resolve("just.testing", kPortnum, &adrlist, |
- &callback_, NULL); |
+ net::HostResolver::RequestInfo info("just.testing", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, &callback_, NULL); |
EXPECT_EQ(net::ERR_IO_PENDING, err); |
// Make sure we will exit the queue even when callback is not called. |
@@ -245,7 +255,8 @@ |
net::HostResolver host_resolver; |
net::AddressList adrlist; |
const int kPortnum = 5555; |
- int err = host_resolver.Resolve("127.1.2.3", kPortnum, &adrlist, NULL, NULL); |
+ net::HostResolver::RequestInfo info("127.1.2.3", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
EXPECT_EQ(net::OK, err); |
const struct addrinfo* ainfo = adrlist.head(); |
@@ -268,8 +279,8 @@ |
net::HostResolver host_resolver; |
net::AddressList adrlist; |
const int kPortnum = 5555; |
- int err = host_resolver.Resolve("2001:db8::1", kPortnum, &adrlist, NULL, |
- NULL); |
+ net::HostResolver::RequestInfo info("2001:db8::1", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
// On computers without IPv6 support, getaddrinfo cannot convert IPv6 |
// address literals to addresses (getaddrinfo returns EAI_NONAME). So this |
// test has to allow host_resolver.Resolve to fail. |
@@ -302,7 +313,8 @@ |
net::HostResolver host_resolver; |
net::AddressList adrlist; |
const int kPortnum = 5555; |
- int err = host_resolver.Resolve("", kPortnum, &adrlist, NULL, NULL); |
+ net::HostResolver::RequestInfo info("", kPortnum); |
+ int err = host_resolver.Resolve(info, &adrlist, NULL, NULL); |
EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, err); |
} |
@@ -457,7 +469,7 @@ |
// Start a request (so we can make sure the canceled requests don't |
// complete before "finalrequest" finishes. |
final_request_.reset(new ResolveRequest( |
- resolve->resolver(), "finalrequest", 70, this)); |
+ resolve->resolver(), "finalrequest", 70, this)); |
} else if (83 == resolve->port()) { |
EXPECT_EQ("a", resolve->hostname()); |
@@ -618,4 +630,164 @@ |
MessageLoop::current()->Run(); |
} |
+// Helper class used by HostResolverTest.BypassCache. |
+class BypassCacheVerifier : public ResolveRequest::Delegate { |
+ public: |
+ BypassCacheVerifier() {} |
+ |
+ virtual void OnCompleted(ResolveRequest* resolve) { |
+ EXPECT_EQ("a", resolve->hostname()); |
+ net::HostResolver* resolver = resolve->resolver(); |
+ |
+ if (80 == resolve->port()) { |
+ // On completing the first request, start another request for "a". |
+ // Since caching is enabled, this should complete synchronously. |
+ |
+ // Note that |junk_callback| shouldn't be used since we are going to |
+ // complete synchronously. We can't specify NULL though since that would |
+ // mean synchronous mode so we give it a value of 1. |
+ net::CompletionCallback* junk_callback = |
+ reinterpret_cast<net::CompletionCallback*> (1); |
+ net::AddressList addrlist; |
+ |
+ net::HostResolver::RequestInfo info("a", 70); |
+ int error = resolver->Resolve(info, &addrlist, junk_callback, NULL); |
+ EXPECT_EQ(net::OK, error); |
+ |
+ // Ok good. Now make sure that if we ask to bypass the cache, it can no |
+ // longer service the request synchronously. |
+ info = net::HostResolver::RequestInfo("a", 71); |
+ info.set_allow_cached_response(false); |
+ final_request_.reset(new ResolveRequest(resolver, info, this)); |
+ } else if (71 == resolve->port()) { |
+ // Test is done. |
+ MessageLoop::current()->Quit(); |
+ } else { |
+ FAIL() << "Unexpected port number"; |
+ } |
+ } |
+ |
+ private: |
+ scoped_ptr<ResolveRequest> final_request_; |
+ DISALLOW_COPY_AND_ASSIGN(BypassCacheVerifier); |
+}; |
+ |
+TEST_F(HostResolverTest, BypassCache) { |
+ net::HostResolver host_resolver; |
+ |
+ // The class will receive callbacks for when each resolve completes. It |
+ // checks that the right things happened. |
+ BypassCacheVerifier verifier; |
+ |
+ // Start a request. |
+ ResolveRequest req1(&host_resolver, "a", 80, &verifier); |
+ |
+ // |verifier| will send quit message once all the requests have finished. |
+ MessageLoop::current()->Run(); |
+} |
+ |
+bool operator==(const net::HostResolver::RequestInfo& a, |
+ const net::HostResolver::RequestInfo& b) { |
+ return a.hostname() == b.hostname() && |
+ a.port() == b.port() && |
+ a.allow_cached_response() == b.allow_cached_response() && |
+ a.is_speculative() == b.is_speculative() && |
+ a.referrer() == b.referrer(); |
+} |
+ |
+// Observer that just makes note of how it was called. The test code can then |
+// inspect to make sure it was called with the right parameters. |
+class CapturingObserver : public net::DnsResolutionObserver { |
+ public: |
+ // DnsResolutionObserver methods: |
+ virtual void OnStartResolution(int id, |
+ const net::HostResolver::RequestInfo& info) { |
+ start_log.push_back(StartEntry(id, info)); |
+ } |
+ |
+ virtual void OnFinishResolutionWithStatus( |
+ int id, |
+ bool was_resolved, |
+ const net::HostResolver::RequestInfo& info) { |
+ finish_log.push_back(FinishEntry(id, was_resolved, info)); |
+ } |
+ |
+ // Tuple (id, info). |
+ struct StartEntry { |
+ StartEntry(int id, const net::HostResolver::RequestInfo& info) |
+ : id(id), info(info) {} |
+ |
+ bool operator==(const StartEntry& other) const { |
+ return id == other.id && info == other.info; |
+ } |
+ |
+ int id; |
+ net::HostResolver::RequestInfo info; |
+ }; |
+ |
+ // Tuple (id, was_resolved, info). |
+ struct FinishEntry { |
+ FinishEntry(int id, bool was_resolved, |
+ const net::HostResolver::RequestInfo& info) |
+ : id(id), was_resolved(was_resolved), info(info) {} |
+ |
+ bool operator==(const FinishEntry& other) const { |
+ return id == other.id && |
+ was_resolved == other.was_resolved && |
+ info == other.info; |
+ } |
+ |
+ int id; |
+ bool was_resolved; |
+ net::HostResolver::RequestInfo info; |
+ }; |
+ |
+ std::vector<StartEntry> start_log; |
+ std::vector<FinishEntry> finish_log; |
+}; |
+ |
+// Test that registering, unregistering, and notifying of observers works. |
+TEST_F(HostResolverTest, Observers) { |
+ net::HostResolver host_resolver; |
+ |
+ CapturingObserver observer; |
+ |
+ host_resolver.AddObserver(&observer); |
+ |
+ net::AddressList addrlist; |
+ |
+ // Resolve "host1". |
+ net::HostResolver::RequestInfo info1("host1", 70); |
+ host_resolver.Resolve(info1, &addrlist, NULL, NULL); |
+ |
+ EXPECT_EQ(1U, observer.start_log.size()); |
+ EXPECT_EQ(1U, observer.finish_log.size()); |
+ EXPECT_TRUE( |
+ observer.start_log[0] == CapturingObserver::StartEntry(0, info1)); |
+ EXPECT_TRUE( |
+ observer.finish_log[0] == CapturingObserver::FinishEntry(0, true, info1)); |
+ |
+ // Resolve "host2", setting referrer to "http://foobar.com" |
+ net::HostResolver::RequestInfo info2("host2", 70); |
+ info2.set_referrer(GURL("http://foobar.com")); |
+ host_resolver.Resolve(info2, &addrlist, NULL, NULL); |
+ |
+ EXPECT_EQ(2U, observer.start_log.size()); |
+ EXPECT_EQ(2U, observer.finish_log.size()); |
+ EXPECT_TRUE(observer.start_log[1] == CapturingObserver::StartEntry(1, info2)); |
+ EXPECT_TRUE(observer.finish_log[1] == CapturingObserver::FinishEntry( |
+ 1, true, info2)); |
+ |
+ // Unregister the observer. |
+ host_resolver.RemoveObserver(&observer); |
+ |
+ // Resolve "host3" |
+ net::HostResolver::RequestInfo info3("host3", 70); |
+ host_resolver.Resolve(info3, &addrlist, NULL, NULL); |
+ |
+ // No effect this time, since observer was removed. |
+ EXPECT_EQ(2U, observer.start_log.size()); |
+ EXPECT_EQ(2U, observer.finish_log.size()); |
+} |
+ |
} // namespace |