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