Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: net/dns/dns_test_util.cc

Issue 9667025: [net/dns] Serve requests from HOSTS file if possible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added MockDnsClient. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include <netinet/in.h>
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop.h"
12 #include "net/base/big_endian.h"
13 #include "net/base/dns_util.h"
14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h"
16 #include "net/dns/dns_client.h"
17 #include "net/dns/dns_config_service.h"
18 #include "net/dns/dns_protocol.h"
19 #include "net/dns/dns_query.h"
20 #include "net/dns/dns_response.h"
21 #include "net/dns/dns_transaction.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace net {
25
26 // A DnsTransactionFactory which responds with 127.0.0.1 to all queries
27 // starting with "ok", fails synchronously on all queries starting with "er",
28 // and NXDOMAIN to all others.
29 class MockTransactionFactory : public DnsTransactionFactory {
mmenke 2012/03/12 16:23:31 nit: This should all be in an anonymous namespace
30 public:
31 // Using WeakPtr to support cancellation.
32 class MockTransaction : public DnsTransaction,
33 public base::SupportsWeakPtr<MockTransaction> {
mmenke 2012/03/12 16:23:31 nit: To make the code a little easier to follow,
34 public:
35 MockTransaction(const std::string& hostname,
36 uint16 qtype,
37 const DnsTransactionFactory::CallbackType& callback)
38 : hostname_(hostname),
39 qtype_(qtype),
40 callback_(callback),
41 started_(false) {
42 }
43
44 virtual const std::string& GetHostname() const OVERRIDE {
45 return hostname_;
46 }
47
48 virtual uint16 GetType() const OVERRIDE {
49 return qtype_;
50 }
51
52 virtual int Start() OVERRIDE {
53 EXPECT_FALSE(started_);
54 started_ = true;
55 if (hostname_.substr(0, 2) == "er")
56 return ERR_NAME_NOT_RESOLVED;
57 MessageLoop::current()->PostTask(
58 FROM_HERE,
59 base::Bind(&MockTransaction::Finish, AsWeakPtr()));
60 return ERR_IO_PENDING;
61 }
62
63 private:
64 void Finish() {
65 if (hostname_.substr(0, 2) == "ok") {
66 std::string qname;
67 DNSDomainFromDot(hostname_, &qname);
68 DnsQuery query(0, qname, qtype_);
69
70 DnsResponse response;
71 char* buffer = response.io_buffer()->data();
72 int nbytes = query.io_buffer()->size();
73 memcpy(buffer, query.io_buffer()->data(), nbytes);
74 reinterpret_cast<dns_protocol::Header*>(buffer)->ancount = htons(1);
75
76 const uint16 kPointerToQueryName =
77 static_cast<uint16>(0xc000 | sizeof(net::dns_protocol::Header));
78
79 const uint32 kTTL = 86400; // One day.
80
81 // Size of RDATA which is a IPv4 or IPv6 address.
82 size_t rdata_size = qtype_ == net::dns_protocol::kTypeA ?
83 net::kIPv4AddressSize : net::kIPv6AddressSize;
84
85 // 12 is the sum of sizes of the compressed name reference, TYPE,
86 // CLASS, TTL and RDLENGTH.
87 size_t answer_size = 12 + rdata_size;
88
89 // Write 127.0.0.1 answer
mmenke 2012/03/12 16:23:31 nit: Suggest you say "loopback address", since IP
90 BigEndianWriter writer(buffer + nbytes, answer_size);
91 writer.WriteU16(kPointerToQueryName);
92 writer.WriteU16(qtype_);
93 writer.WriteU16(net::dns_protocol::kClassIN);
94 writer.WriteU32(kTTL);
95 writer.WriteU16(rdata_size);
96 if (qtype_ == net::dns_protocol::kTypeA)
97 writer.WriteU32(INADDR_LOOPBACK);
98 else
99 writer.WriteBytes(&in6addr_loopback, sizeof(in6_addr));
100
101 EXPECT_TRUE(response.InitParse(nbytes + answer_size, query));
102 callback_.Run(this, OK, &response);
103 } else {
104 callback_.Run(this, ERR_NAME_NOT_RESOLVED, NULL);
105 }
106 }
107
108 const std::string hostname_;
109 const uint16 qtype_;
110 DnsTransactionFactory::CallbackType callback_;
111 bool started_;
112 };
113
114 typedef std::pair<std::string, uint16> Key;
115
116 MockTransactionFactory() : num_requests_(0) {}
117 virtual ~MockTransactionFactory() {}
118
119 virtual scoped_ptr<DnsTransaction> CreateTransaction(
120 const std::string& hostname,
121 uint16 qtype,
122 const DnsTransactionFactory::CallbackType& callback,
123 const BoundNetLog&) OVERRIDE {
124 ++num_requests_;
125 return scoped_ptr<DnsTransaction>(
126 new MockTransaction(hostname, qtype, callback));
127 }
128
129 int num_requests() const { return num_requests_; }
130
131 private:
132 int num_requests_;
133 };
134
135 // MockDnsClient provides MockTransactionFactory.
136 class MockDnsClient : public DnsClient {
137 public:
138 virtual ~MockDnsClient() {}
139
140 virtual void SetConfig(const DnsConfig& config) OVERRIDE {
141 config_ = config;
142 }
143
144 virtual const DnsConfig* GetConfig() const OVERRIDE {
145 return config_.IsValid() ? &config_ : NULL;
146 }
147
148 virtual DnsTransactionFactory* GetTransactionFactory() OVERRIDE {
149 return &factory_;
150 }
151
152 private:
153 DnsConfig config_;
154 MockTransactionFactory factory_;
155 };
156
157
158 // static
159 scoped_ptr<DnsClient> CreateMockDnsClient() {
160 return scoped_ptr<DnsClient>(new MockDnsClient());
161 }
162
163 } // namespace net
OLDNEW
« net/dns/dns_client.cc ('K') | « net/dns/dns_test_util.h ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698