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