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 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/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 19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// In most cases, it is important that unit tests avoid relying on making actual 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// DNS queries since the resulting tests can be flaky, especially if the network 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// is 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: 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual ~MockHostResolverBase(); 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RuleBasedHostResolverProc* rules() { return rules_; } 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Controls whether resolutions complete synchronously or asynchronously. 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void set_synchronous_mode(bool is_synchronous) { 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott synchronous_mode_ = is_synchronous; 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Resets the mock. 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Reset(HostResolverProc* interceptor); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void SetPoolConstraints(HostResolverImpl::JobPoolIndex pool_index, 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t max_outstanding_jobs, 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t max_pending_requests) { 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick impl_->SetPoolConstraints( 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick pool_index, max_outstanding_jobs, max_pending_requests); 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // HostResolver methods: 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual int Resolve(const RequestInfo& info, 633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen AddressList* addresses, 643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback, 653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen RequestHandle* out_req, 663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const BoundNetLog& net_log); 673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual void CancelRequest(RequestHandle req); 683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual void AddObserver(Observer* observer); 693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen virtual void RemoveObserver(Observer* observer); 703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockHostResolverBase(bool use_caching); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<HostResolverImpl> impl_; 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<RuleBasedHostResolverProc> rules_; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool synchronous_mode_; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool use_caching_; 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(MockHostResolverBase); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockHostResolver : public MockHostResolverBase { 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockHostResolver() : MockHostResolverBase(false /*use_caching*/) {} 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MockHostResolver() {} 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Same as MockHostResolver, except internally it uses a host-cache. 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Note that tests are advised to use MockHostResolver instead, since it is 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// more predictable. (MockHostResolver also can be put into synchronous 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// operation mode in case that is what you needed from the caching version). 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MockCachingHostResolver : public MockHostResolverBase { 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MockCachingHostResolver() : MockHostResolverBase(true /*use_caching*/) {} 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 struct Rule; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::list<Rule> RuleList; 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ~RuleBasedHostResolverProc(); 1503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 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: 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick explicit WaitingHostResolverProc(HostResolverProc* previous); 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void Signal(); 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // HostResolverProc methods: 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Resolve(const std::string& host, 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressFamily address_family, 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HostResolverFlags host_resolver_flags, 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddressList* addrlist, 166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int* os_error); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual ~WaitingHostResolverProc(); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::WaitableEvent event_; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class sets the default HostResolverProc for a particular scope. The 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// chain of resolver procs starting at |proc| is placed in front of any existing 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// default resolver proc(s). This means that if multiple 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ScopedDefaultHostResolverProcs are declared, then resolving will start with 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the procs given to the last-allocated one, then fall back to the procs given 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to the previously-allocated one, and so forth. 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// NOTE: Only use this as a catch-all safety net. Individual tests should use 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MockHostResolver. 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ScopedDefaultHostResolverProc { 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedDefaultHostResolverProc(); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit ScopedDefaultHostResolverProc(HostResolverProc* proc); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~ScopedDefaultHostResolverProc(); 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Init(HostResolverProc* proc); 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HostResolverProc> current_proc_; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<HostResolverProc> previous_proc_; 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_BASE_MOCK_HOST_RESOLVER_H_ 200