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

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

Issue 8762001: Isolates generic DnsClient from AsyncHostResolver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: retrying to fix status of dns_session.h Created 9 years 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
« no previous file with comments | « net/dns/dns_client.cc ('k') | net/dns/dns_protocol.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "net/dns/dns_client.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "net/base/big_endian.h"
10 #include "net/base/net_log.h"
11 #include "net/base/sys_addrinfo.h"
12 #include "net/dns/dns_response.h"
13 #include "net/dns/dns_session.h"
14 #include "net/dns/dns_test_util.h"
15 #include "net/socket/socket_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 // TODO(szym): test DnsClient::Request::Start with synchronous failure
19 // TODO(szym): test suffix search and server fallback once implemented
20
21 namespace net {
22
23 namespace {
24
25 class DnsClientTest : public testing::Test {
26 public:
27 class TestRequestHelper {
28 public:
29 // If |answer_count| < 0, it is the expected error code.
30 TestRequestHelper(const char* name,
31 uint16 type,
32 const MockWrite& write,
33 const MockRead& read,
34 int answer_count) {
35 // Must include the terminating \x00.
36 qname = std::string(name, strlen(name) + 1);
37 qtype = type;
38 expected_answer_count = answer_count;
39 completed = false;
40 writes.push_back(write);
41 reads.push_back(read);
42 ReadBigEndian<uint16>(write.data, &transaction_id);
43 data.reset(new StaticSocketDataProvider(&reads[0], reads.size(),
44 &writes[0], writes.size()));
45 }
46
47 void MakeRequest(DnsClient* client) {
48 EXPECT_EQ(NULL, request.get());
49 request.reset(client->CreateRequest(
50 qname,
51 qtype,
52 base::Bind(&TestRequestHelper::OnRequestComplete,
53 base::Unretained(this)),
54 BoundNetLog()));
55 EXPECT_EQ(qname, request->qname());
56 EXPECT_EQ(qtype, request->qtype());
57 EXPECT_EQ(ERR_IO_PENDING, request->Start());
58 }
59
60 void Cancel() {
61 ASSERT_TRUE(request.get() != NULL);
62 request.reset(NULL);
63 }
64
65 void OnRequestComplete(DnsClient::Request* req,
66 int rv,
67 const DnsResponse* response) {
68 EXPECT_FALSE(completed);
69 EXPECT_EQ(request.get(), req);
70
71 if (expected_answer_count >= 0) {
72 EXPECT_EQ(OK, rv);
73 EXPECT_EQ(expected_answer_count, response->answer_count());
74
75 DnsRecordParser parser = response->Parser();
76 DnsResourceRecord record;
77 for (int i = 0; i < expected_answer_count; ++i) {
78 EXPECT_TRUE(parser.ParseRecord(&record));
79 }
80 EXPECT_TRUE(parser.AtEnd());
81
82 } else {
83 EXPECT_EQ(expected_answer_count, rv);
84 EXPECT_EQ(NULL, response);
85 }
86
87 completed = true;
88 }
89
90 void CancelOnRequestComplete(DnsClient::Request* req,
91 int rv,
92 const DnsResponse* response) {
93 EXPECT_FALSE(completed);
94 Cancel();
95 }
96
97 std::string qname;
98 uint16 qtype;
99 std::vector<MockWrite> writes;
100 std::vector<MockRead> reads;
101 uint16 transaction_id; // Id from first write.
102 scoped_ptr<StaticSocketDataProvider> data;
103 scoped_ptr<DnsClient::Request> request;
104 int expected_answer_count;
105
106 bool completed;
107 };
108
109 virtual void SetUp() OVERRIDE {
110 helpers_.push_back(new TestRequestHelper(
111 kT0DnsName,
112 kT0Qtype,
113 MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram),
114 arraysize(kT0QueryDatagram)),
115 MockRead(true, reinterpret_cast<const char*>(kT0ResponseDatagram),
116 arraysize(kT0ResponseDatagram)),
117 arraysize(kT0IpAddresses) + 1)); // +1 for CNAME RR
118
119 helpers_.push_back(new TestRequestHelper(
120 kT1DnsName,
121 kT1Qtype,
122 MockWrite(true, reinterpret_cast<const char*>(kT1QueryDatagram),
123 arraysize(kT1QueryDatagram)),
124 MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram),
125 arraysize(kT1ResponseDatagram)),
126 arraysize(kT1IpAddresses) + 1)); // +1 for CNAME RR
127
128 helpers_.push_back(new TestRequestHelper(
129 kT2DnsName,
130 kT2Qtype,
131 MockWrite(true, reinterpret_cast<const char*>(kT2QueryDatagram),
132 arraysize(kT2QueryDatagram)),
133 MockRead(true, reinterpret_cast<const char*>(kT2ResponseDatagram),
134 arraysize(kT2ResponseDatagram)),
135 arraysize(kT2IpAddresses) + 1)); // +1 for CNAME RR
136
137 helpers_.push_back(new TestRequestHelper(
138 kT3DnsName,
139 kT3Qtype,
140 MockWrite(true, reinterpret_cast<const char*>(kT3QueryDatagram),
141 arraysize(kT3QueryDatagram)),
142 MockRead(true, reinterpret_cast<const char*>(kT3ResponseDatagram),
143 arraysize(kT3ResponseDatagram)),
144 arraysize(kT3IpAddresses) + 2)); // +2 for CNAME RR
145
146 CreateClient();
147 }
148
149 void CreateClient() {
150 MockClientSocketFactory* factory = new MockClientSocketFactory();
151
152 transaction_ids_.clear();
153 for (unsigned i = 0; i < helpers_.size(); ++i) {
154 factory->AddSocketDataProvider(helpers_[i]->data.get());
155 transaction_ids_.push_back(static_cast<int>(helpers_[i]->transaction_id));
156 }
157
158 DnsConfig config;
159
160 IPEndPoint dns_server;
161 {
162 bool rv = CreateDnsAddress(kDnsIp, kDnsPort, &dns_server);
163 EXPECT_TRUE(rv);
164 }
165 config.nameservers.push_back(dns_server);
166
167 DnsSession* session = new DnsSession(
168 config,
169 factory,
170 base::Bind(&DnsClientTest::GetNextId, base::Unretained(this)),
171 NULL /* NetLog */);
172
173 client_.reset(DnsClient::CreateClient(session));
174 }
175
176 virtual void TearDown() OVERRIDE {
177 STLDeleteElements(&helpers_);
178 }
179
180 int GetNextId(int min, int max) {
181 EXPECT_FALSE(transaction_ids_.empty());
182 int id = transaction_ids_.front();
183 transaction_ids_.pop_front();
184 EXPECT_GE(id, min);
185 EXPECT_LE(id, max);
186 return id;
187 }
188
189 protected:
190 std::vector<TestRequestHelper*> helpers_;
191 std::deque<int> transaction_ids_;
192 scoped_ptr<DnsClient> client_;
193 };
194
195 TEST_F(DnsClientTest, Lookup) {
196 helpers_[0]->MakeRequest(client_.get());
197
198 // Wait until result.
199 MessageLoop::current()->RunAllPending();
200
201 EXPECT_TRUE(helpers_[0]->completed);
202 }
203
204 TEST_F(DnsClientTest, ConcurrentLookup) {
205 for (unsigned i = 0; i < helpers_.size(); ++i) {
206 helpers_[i]->MakeRequest(client_.get());
207 }
208
209 MessageLoop::current()->RunAllPending();
210
211 for (unsigned i = 0; i < helpers_.size(); ++i) {
212 EXPECT_TRUE(helpers_[i]->completed);
213 }
214 }
215
216 TEST_F(DnsClientTest, CancelLookup) {
217 for (unsigned i = 0; i < helpers_.size(); ++i) {
218 helpers_[i]->MakeRequest(client_.get());
219 }
220
221 helpers_[0]->Cancel();
222 helpers_[2]->Cancel();
223
224 MessageLoop::current()->RunAllPending();
225
226 EXPECT_FALSE(helpers_[0]->completed);
227 EXPECT_TRUE(helpers_[1]->completed);
228 EXPECT_FALSE(helpers_[2]->completed);
229 EXPECT_TRUE(helpers_[3]->completed);
230 }
231
232 TEST_F(DnsClientTest, DestroyClient) {
233 for (unsigned i = 0; i < helpers_.size(); ++i) {
234 helpers_[i]->MakeRequest(client_.get());
235 }
236
237 // Destroying the client does not affect running requests.
238 client_.reset(NULL);
239
240 MessageLoop::current()->RunAllPending();
241
242 for (unsigned i = 0; i < helpers_.size(); ++i) {
243 EXPECT_TRUE(helpers_[i]->completed);
244 }
245 }
246
247 TEST_F(DnsClientTest, DestroyRequestFromCallback) {
248 // Custom callback to cancel the completing request.
249 helpers_[0]->request.reset(client_->CreateRequest(
250 helpers_[0]->qname,
251 helpers_[0]->qtype,
252 base::Bind(&TestRequestHelper::CancelOnRequestComplete,
253 base::Unretained(helpers_[0])),
254 BoundNetLog()));
255 helpers_[0]->request->Start();
256
257 for (unsigned i = 1; i < helpers_.size(); ++i) {
258 helpers_[i]->MakeRequest(client_.get());
259 }
260
261 MessageLoop::current()->RunAllPending();
262
263 EXPECT_FALSE(helpers_[0]->completed);
264 for (unsigned i = 1; i < helpers_.size(); ++i) {
265 EXPECT_TRUE(helpers_[i]->completed);
266 }
267 }
268
269 TEST_F(DnsClientTest, HandleFailure) {
270 STLDeleteElements(&helpers_);
271 // Wrong question.
272 helpers_.push_back(new TestRequestHelper(
273 kT0DnsName,
274 kT0Qtype,
275 MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram),
276 arraysize(kT0QueryDatagram)),
277 MockRead(true, reinterpret_cast<const char*>(kT1ResponseDatagram),
278 arraysize(kT1ResponseDatagram)),
279 ERR_DNS_MALFORMED_RESPONSE));
280
281 // Response with NXDOMAIN.
282 uint8 nxdomain_response[arraysize(kT0QueryDatagram)];
283 memcpy(nxdomain_response, kT0QueryDatagram, arraysize(nxdomain_response));
284 nxdomain_response[2] &= 0x80; // Response bit.
285 nxdomain_response[3] &= 0x03; // NXDOMAIN bit.
286 helpers_.push_back(new TestRequestHelper(
287 kT0DnsName,
288 kT0Qtype,
289 MockWrite(true, reinterpret_cast<const char*>(kT0QueryDatagram),
290 arraysize(kT0QueryDatagram)),
291 MockRead(true, reinterpret_cast<const char*>(nxdomain_response),
292 arraysize(nxdomain_response)),
293 ERR_NAME_NOT_RESOLVED));
294
295 CreateClient();
296
297 for (unsigned i = 0; i < helpers_.size(); ++i) {
298 helpers_[i]->MakeRequest(client_.get());
299 }
300
301 MessageLoop::current()->RunAllPending();
302
303 for (unsigned i = 0; i < helpers_.size(); ++i) {
304 EXPECT_TRUE(helpers_[i]->completed);
305 }
306 }
307
308 } // namespace
309
310 } // namespace net
311
OLDNEW
« no previous file with comments | « net/dns/dns_client.cc ('k') | net/dns/dns_protocol.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698