Home | History | Annotate | Download | only in base
      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 
     44   RuleBasedHostResolverProc* rules() { return rules_; }
     45 
     46   // Controls whether resolutions complete synchronously or asynchronously.
     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 
     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:
     85   MockHostResolver() : MockHostResolverBase(false /*use_caching*/) {}
     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:
     96   MockCachingHostResolver() : MockHostResolverBase(true /*use_caching*/) {}
     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