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