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