mock_host_resolver.h revision c7f5f8508d98d5952d42ed7648c2a8f30a4da156
1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef NET_BASE_MOCK_HOST_RESOLVER_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_BASE_MOCK_HOST_RESOLVER_H_ 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <list> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/waitable_event.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/host_resolver_impl.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/host_resolver_proc.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RuleBasedHostResolverProc; 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// In most cases, it is important that unit tests avoid making actual DNS 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// queries since the resulting tests can be flaky, especially if the network is 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// unreliable for some reason. To simplify writing tests that avoid making 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// actual DNS queries, pass a MockHostResolver as the HostResolver dependency. 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The socket addresses returned can be configured using the 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RuleBasedHostResolverProc: 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// host_resolver->rules()->AddRule("foo.com", "1.2.3.4"); 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// host_resolver->rules()->AddRule("bar.com", "2.3.4.5"); 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The above rules define a static mapping from hostnames to IP address 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// literals. The first parameter to AddRule specifies a host pattern to match 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// against, and the second parameter indicates what value should be used to 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// replace the given hostname. So, the following is also supported: 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// host_mapper->AddRule("*.com", "127.0.0.1"); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Replacement doesn't have to be string representing an IP address. It can 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// re-map one hostname to another as well. 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Base class shared by MockHostResolver and MockCachingHostResolver. 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockHostResolverBase : public HostResolver { 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HostResolver methods: 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Resolve(const RequestInfo& info, 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList* addresses, 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* callback, 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RequestHandle* out_req, 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LoadLog* load_log); 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void CancelRequest(RequestHandle req); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void AddObserver(Observer* observer); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void RemoveObserver(Observer* observer); 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(eroman): temp hack for http://crbug.com/18373 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Shutdown(); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RuleBasedHostResolverProc* rules() { return rules_; } 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Controls whether resolutions complete synchronously or asynchronously. 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_synchronous_mode(bool is_synchronous) { 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott synchronous_mode_ = is_synchronous; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resets the mock. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Reset(HostResolverProc* interceptor); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockHostResolverBase(bool use_caching); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MockHostResolverBase() {} 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HostResolverImpl> impl_; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<RuleBasedHostResolverProc> rules_; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool synchronous_mode_; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool use_caching_; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockHostResolver : public MockHostResolverBase { 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockHostResolver() : MockHostResolverBase(false /*use_caching*/) {} 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MockHostResolver() {} 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Same as MockHostResolver, except internally it uses a host-cache. 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Note that tests are advised to use MockHostResolver instead, since it is 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// more predictable. (MockHostResolver also can be put into synchronous 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// operation mode in case that is what you needed from the caching version). 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockCachingHostResolver : public MockHostResolverBase { 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockCachingHostResolver() : MockHostResolverBase(true /*use_caching*/) {} 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~MockCachingHostResolver() {} 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RuleBasedHostResolverProc applies a set of rules to map a host string to 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a replacement host string. It then uses the system host resolver to return 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a socket address. Generally the replacement should be an IPv4 literal so 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// there is no network dependency. 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass RuleBasedHostResolverProc : public HostResolverProc { 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit RuleBasedHostResolverProc(HostResolverProc* previous); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Any hostname matching the given pattern will be replaced with the given 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // replacement value. Usually, replacement should be an IP address literal. 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddRule(const std::string& host_pattern, 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& replacement); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Same as AddRule(), but further restricts to |address_family|. 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddRuleForAddressFamily(const std::string& host_pattern, 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressFamily address_family, 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& replacement); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Same as AddRule(), but the replacement is expected to be an IPV6 literal. 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // You should use this in place of AddRule(), since the system's host resolver 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // may not support IPv6 literals on all systems. Whereas this variant 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // constructs the socket address directly so it will always work. 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddIPv6Rule(const std::string& host_pattern, 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& ipv6_literal); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddRuleWithLatency(const std::string& host_pattern, 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& replacement, 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int latency_ms); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make sure that |host| will not be re-mapped or even processed by underlying 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // host resolver procedures. It can also be a pattern. 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AllowDirectLookup(const std::string& host); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Simulate a lookup failure for |host| (it also can be a pattern). 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void AddSimulatedFailure(const std::string& host); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HostResolverProc methods: 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Resolve(const std::string& host, 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressFamily address_family, 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList* addrlist); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~RuleBasedHostResolverProc(); 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Rule; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::list<Rule> RuleList; 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RuleList rules_; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Using WaitingHostResolverProc you can simulate very long lookups. 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass WaitingHostResolverProc : public HostResolverProc { 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit WaitingHostResolverProc(HostResolverProc* previous) 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : HostResolverProc(previous), event_(false, false) {} 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Signal() { 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_.Signal(); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HostResolverProc methods: 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Resolve(const std::string& host, 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressFamily address_family, 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList* addrlist) { 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott event_.Wait(); 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ResolveUsingPrevious(host, address_family, addrlist); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~WaitingHostResolverProc() {} 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::WaitableEvent event_; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class sets the default HostResolverProc for a particular scope. The 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// chain of resolver procs starting at |proc| is placed in front of any existing 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// default resolver proc(s). This means that if multiple 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ScopedDefaultHostResolverProcs are declared, then resolving will start with 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the procs given to the last-allocated one, then fall back to the procs given 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to the previously-allocated one, and so forth. 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NOTE: Only use this as a catch-all safety net. Individual tests should use 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MockHostResolver. 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ScopedDefaultHostResolverProc { 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ScopedDefaultHostResolverProc() {} 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ScopedDefaultHostResolverProc(HostResolverProc* proc); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~ScopedDefaultHostResolverProc(); 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Init(HostResolverProc* proc); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HostResolverProc> current_proc_; 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HostResolverProc> previous_proc_; 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_MOCK_HOST_RESOLVER_H_ 194