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

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

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

Powered by Google App Engine
This is Rietveld 408576698