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

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: Rebased to trunk. 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 <string>
6
7 #include "base/bind.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/sys_byteorder.h"
11 #include "net/base/big_endian.h"
12 #include "net/base/dns_util.h"
mmenke 2012/03/13 15:56:27 nit: Put this up top.
szym 2012/03/13 18:14:29 Actually, this is dns_util.h, dns_test_util.h is m
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/dns/dns_client.h"
16 #include "net/dns/dns_config_service.h"
17 #include "net/dns/dns_protocol.h"
18 #include "net/dns/dns_query.h"
19 #include "net/dns/dns_response.h"
20 #include "net/dns/dns_transaction.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace net {
24 namespace {
25
26 // A DnsTransaction which responds with loopback to all queries starting with
27 // "ok", fails synchronously on all queries starting with "er", and NXDOMAIN to
28 // all others.
29 class MockTransaction : public DnsTransaction,
30 public base::SupportsWeakPtr<MockTransaction> {
31 public:
32 MockTransaction(const std::string& hostname,
33 uint16 qtype,
34 const DnsTransactionFactory::CallbackType& callback)
35 : hostname_(hostname),
36 qtype_(qtype),
37 callback_(callback),
38 started_(false) {
39 }
40
41 virtual const std::string& GetHostname() const OVERRIDE {
42 return hostname_;
43 }
44
45 virtual uint16 GetType() const OVERRIDE {
46 return qtype_;
47 }
48
49 virtual int Start() OVERRIDE {
50 EXPECT_FALSE(started_);
51 started_ = true;
52 if (hostname_.substr(0, 2) == "er")
53 return ERR_NAME_NOT_RESOLVED;
54 // Using WeakPtr to cleanly cancel when transaction is destroyed.
55 MessageLoop::current()->PostTask(
56 FROM_HERE,
57 base::Bind(&MockTransaction::Finish, AsWeakPtr()));
58 return ERR_IO_PENDING;
59 }
60
61 private:
62 void Finish() {
63 if (hostname_.substr(0, 2) == "ok") {
64 std::string qname;
65 DNSDomainFromDot(hostname_, &qname);
66 DnsQuery query(0, qname, qtype_);
67
68 DnsResponse response;
69 char* buffer = response.io_buffer()->data();
70 int nbytes = query.io_buffer()->size();
71 memcpy(buffer, query.io_buffer()->data(), nbytes);
72
73 const uint16 kPointerToQueryName =
74 static_cast<uint16>(0xc000 | sizeof(net::dns_protocol::Header));
75
76 const uint32 kTTL = 86400; // One day.
77
78 // Size of RDATA which is a IPv4 or IPv6 address.
79 size_t rdata_size = qtype_ == net::dns_protocol::kTypeA ?
80 net::kIPv4AddressSize : net::kIPv6AddressSize;
81
82 // 12 is the sum of sizes of the compressed name reference, TYPE,
83 // CLASS, TTL and RDLENGTH.
84 size_t answer_size = 12 + rdata_size;
85
86 // Write answer with loopback IP address.
87 reinterpret_cast<dns_protocol::Header*>(buffer)->ancount = htons(1);
88 BigEndianWriter writer(buffer + nbytes, answer_size);
89 writer.WriteU16(kPointerToQueryName);
90 writer.WriteU16(qtype_);
91 writer.WriteU16(net::dns_protocol::kClassIN);
92 writer.WriteU32(kTTL);
93 writer.WriteU16(rdata_size);
94 if (qtype_ == net::dns_protocol::kTypeA) {
95 char kIPv4Loopback[] = { 0x7f, 0, 0, 1 };
96 writer.WriteBytes(kIPv4Loopback, sizeof(kIPv4Loopback));
97 } else {
98 char kIPv6Loopback[] = { 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0, 0, 0, 0, 0, 1 };
100 writer.WriteBytes(kIPv6Loopback, sizeof(kIPv6Loopback));
101 }
102
103 EXPECT_TRUE(response.InitParse(nbytes + answer_size, query));
104 callback_.Run(this, OK, &response);
105 } else {
106 callback_.Run(this, ERR_NAME_NOT_RESOLVED, NULL);
107 }
108 }
109
110 const std::string hostname_;
111 const uint16 qtype_;
112 DnsTransactionFactory::CallbackType callback_;
113 bool started_;
114 };
115
116
117 // A DnsTransactionFactory which creates MockTransaction.
118 class MockTransactionFactory : public DnsTransactionFactory {
119 public:
120 MockTransactionFactory() : num_requests_(0) {}
121 virtual ~MockTransactionFactory() {}
122
123 virtual scoped_ptr<DnsTransaction> CreateTransaction(
124 const std::string& hostname,
125 uint16 qtype,
126 const DnsTransactionFactory::CallbackType& callback,
127 const BoundNetLog&) OVERRIDE {
128 ++num_requests_;
129 return scoped_ptr<DnsTransaction>(
130 new MockTransaction(hostname, qtype, callback));
131 }
132
133 int num_requests() const { return num_requests_; }
134
135 private:
136 int num_requests_;
mmenke 2012/03/13 15:56:27 This isn't currently used anywhere. Also, suggest
szym 2012/03/13 18:14:29 It would help if this was exposed to the tests, bu
137 };
138
139 // MockDnsClient provides MockTransactionFactory.
140 class MockDnsClient : public DnsClient {
141 public:
142 explicit MockDnsClient(const DnsConfig& config) : config_(config) {}
143 virtual ~MockDnsClient() {}
144
145 virtual void SetConfig(const DnsConfig& config) OVERRIDE {
146 config_ = config;
147 }
148
149 virtual const DnsConfig* GetConfig() const OVERRIDE {
150 return config_.IsValid() ? &config_ : NULL;
151 }
152
153 virtual DnsTransactionFactory* GetTransactionFactory() OVERRIDE {
154 return &factory_;
155 }
156
157 private:
158 DnsConfig config_;
159 MockTransactionFactory factory_;
160 };
161
162 } // namespace
163
164 // static
165 scoped_ptr<DnsClient> CreateMockDnsClient(const DnsConfig& config) {
166 return scoped_ptr<DnsClient>(new MockDnsClient(config));
167 }
168
169 } // namespace net
170
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698