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

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

Issue 10824238: [net/dns] Don't abandon a DnsUDPAttempt when the response does not match the query. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 8 years, 3 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
« no previous file with comments | « net/dns/dns_transaction.cc ('k') | net/socket/socket_test_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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_transaction.h" 5 #include "net/dns/dns_transaction.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 "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 13 matching lines...) Expand all
24 namespace net { 24 namespace net {
25 25
26 namespace { 26 namespace {
27 27
28 std::string DomainFromDot(const base::StringPiece& dotted) { 28 std::string DomainFromDot(const base::StringPiece& dotted) {
29 std::string out; 29 std::string out;
30 EXPECT_TRUE(DNSDomainFromDot(dotted, &out)); 30 EXPECT_TRUE(DNSDomainFromDot(dotted, &out));
31 return out; 31 return out;
32 } 32 }
33 33
34 // A SocketDataProvider builder for MockUDPClientSocket. Each socket used by a
35 // DnsTransaction expects only one write and zero or more reads.
36 class DnsSocketData {
37 public:
38 // The ctor takes parameters for the DnsQuery.
39 DnsSocketData(uint16 id, const char* dotted_name, uint16 qtype, IoMode mode)
40 : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)),
41 write_(mode, query_->io_buffer()->data(), query_->io_buffer()->size()) {
42 }
43 ~DnsSocketData() {}
44
45 // All responses must be added before GetProvider.
46
47 // Add pre-built DnsResponse.
48 void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) {
49 CHECK(!provider_.get());
50 reads_.push_back(MockRead(mode,
51 response->io_buffer()->data(),
52 response->io_buffer()->size()));
53 responses_.push_back(response.release());
54 }
55
56 // Adds pre-built response from |data| buffer.
57 void AddResponseData(const uint8* data, size_t length, IoMode mode) {
58 CHECK(!provider_.get());
59 AddResponse(make_scoped_ptr(
60 new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode);
61 }
62
63 // Add no-answer (RCODE only) response matching the query.
64 void AddRcode(int rcode, IoMode mode) {
65 scoped_ptr<DnsResponse> response(
66 new DnsResponse(query_->io_buffer()->data(),
67 query_->io_buffer()->size(),
68 0));
69 dns_protocol::Header* header =
70 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data());
71 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode);
72 AddResponse(response.Pass(), mode);
73 }
74
75 // Build, if needed, and return the SocketDataProvider. No new responses
76 // should be added afterwards.
77 SocketDataProvider* GetProvider() {
78 if (provider_.get())
79 return provider_.get();
80 if (reads_.empty()) {
81 // Timeout.
82 provider_.reset(new DelayedSocketData(2, NULL, 0, &write_, 1));
83 } else {
84 // Terminate the reads with ERR_IO_PENDING to prevent overrun.
85 reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING));
86 provider_.reset(new DelayedSocketData(1, &reads_[0], reads_.size(),
87 &write_, 1));
88 }
89 return provider_.get();
90 }
91
92 uint16 query_id() const {
93 return query_->id();
94 }
95
96 // Returns true if the expected query was written to the socket.
97 bool was_written() const {
98 CHECK(provider_.get());
99 return provider_->write_index() > 0;
100 }
101
102 private:
103 scoped_ptr<DnsQuery> query_;
104 ScopedVector<DnsResponse> responses_;
105 MockWrite write_;
106 std::vector<MockRead> reads_;
107 scoped_ptr<DelayedSocketData> provider_;
108
109 DISALLOW_COPY_AND_ASSIGN(DnsSocketData);
110 };
111
34 class TestSocketFactory; 112 class TestSocketFactory;
35 113
36 // A variant of MockUDPClientSocket which notifies the factory OnConnect. 114 // A variant of MockUDPClientSocket which notifies the factory OnConnect.
37 class TestUDPClientSocket : public MockUDPClientSocket { 115 class TestUDPClientSocket : public MockUDPClientSocket {
38 public: 116 public:
39 TestUDPClientSocket(TestSocketFactory* factory, 117 TestUDPClientSocket(TestSocketFactory* factory,
40 SocketDataProvider* data, 118 SocketDataProvider* data,
41 net::NetLog* net_log) 119 net::NetLog* net_log)
42 : MockUDPClientSocket(data, net_log), factory_(factory) { 120 : MockUDPClientSocket(data, net_log), factory_(factory) {
43 } 121 }
44 virtual ~TestUDPClientSocket() {} 122 virtual ~TestUDPClientSocket() {}
45 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE; 123 virtual int Connect(const IPEndPoint& endpoint) OVERRIDE;
124
46 private: 125 private:
47 TestSocketFactory* factory_; 126 TestSocketFactory* factory_;
127
128 DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket);
48 }; 129 };
49 130
50 // Creates TestUDPClientSockets and keeps endpoints reported via OnConnect. 131 // Creates TestUDPClientSockets and keeps endpoints reported via OnConnect.
51 class TestSocketFactory : public MockClientSocketFactory { 132 class TestSocketFactory : public MockClientSocketFactory {
52 public: 133 public:
53 TestSocketFactory() {} 134 TestSocketFactory() {}
54 virtual ~TestSocketFactory() {} 135 virtual ~TestSocketFactory() {}
55 136
56 virtual DatagramClientSocket* CreateDatagramClientSocket( 137 virtual DatagramClientSocket* CreateDatagramClientSocket(
57 DatagramSocket::BindType bind_type, 138 DatagramSocket::BindType bind_type,
58 const RandIntCallback& rand_int_cb, 139 const RandIntCallback& rand_int_cb,
59 net::NetLog* net_log, 140 net::NetLog* net_log,
60 const net::NetLog::Source& source) OVERRIDE { 141 const net::NetLog::Source& source) OVERRIDE {
61 SocketDataProvider* data_provider = mock_data().GetNext(); 142 SocketDataProvider* data_provider = mock_data().GetNext();
62 TestUDPClientSocket* socket = new TestUDPClientSocket(this, 143 TestUDPClientSocket* socket = new TestUDPClientSocket(this,
63 data_provider, 144 data_provider,
64 net_log); 145 net_log);
65 data_provider->set_socket(socket); 146 data_provider->set_socket(socket);
66 return socket; 147 return socket;
67 } 148 }
68 149
69 void OnConnect(const IPEndPoint& endpoint) { 150 void OnConnect(const IPEndPoint& endpoint) {
70 remote_endpoints.push_back(endpoint); 151 remote_endpoints.push_back(endpoint);
71 } 152 }
72 153
73 std::vector<IPEndPoint> remote_endpoints; 154 std::vector<IPEndPoint> remote_endpoints;
155
156 private:
157 DISALLOW_COPY_AND_ASSIGN(TestSocketFactory);
74 }; 158 };
75 159
76 int TestUDPClientSocket::Connect(const IPEndPoint& endpoint) { 160 int TestUDPClientSocket::Connect(const IPEndPoint& endpoint) {
77 factory_->OnConnect(endpoint); 161 factory_->OnConnect(endpoint);
78 return MockUDPClientSocket::Connect(endpoint); 162 return MockUDPClientSocket::Connect(endpoint);
79 } 163 }
80 164
81 // Helper class that holds a DnsTransaction and handles OnTransactionComplete. 165 // Helper class that holds a DnsTransaction and handles OnTransactionComplete.
82 class TransactionHelper { 166 class TransactionHelper {
83 public: 167 public:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 EXPECT_FALSE(completed_); 216 EXPECT_FALSE(completed_);
133 EXPECT_EQ(transaction_.get(), t); 217 EXPECT_EQ(transaction_.get(), t);
134 218
135 completed_ = true; 219 completed_ = true;
136 220
137 if (cancel_in_callback_) { 221 if (cancel_in_callback_) {
138 Cancel(); 222 Cancel();
139 return; 223 return;
140 } 224 }
141 225
226 // Tell MessageLoop to quit now, in case any ASSERT_* fails.
227 if (quit_in_callback_)
228 MessageLoop::current()->Quit();
229
142 if (expected_answer_count_ >= 0) { 230 if (expected_answer_count_ >= 0) {
143 EXPECT_EQ(OK, rv); 231 ASSERT_EQ(OK, rv);
232 ASSERT_TRUE(response != NULL);
144 EXPECT_EQ(static_cast<unsigned>(expected_answer_count_), 233 EXPECT_EQ(static_cast<unsigned>(expected_answer_count_),
145 response->answer_count()); 234 response->answer_count());
146 EXPECT_EQ(qtype_, response->qtype()); 235 EXPECT_EQ(qtype_, response->qtype());
147 236
148 DnsRecordParser parser = response->Parser(); 237 DnsRecordParser parser = response->Parser();
149 DnsResourceRecord record; 238 DnsResourceRecord record;
150 for (int i = 0; i < expected_answer_count_; ++i) { 239 for (int i = 0; i < expected_answer_count_; ++i) {
151 EXPECT_TRUE(parser.ReadRecord(&record)); 240 EXPECT_TRUE(parser.ReadRecord(&record));
152 } 241 }
153 } else { 242 } else {
154 EXPECT_EQ(expected_answer_count_, rv); 243 EXPECT_EQ(expected_answer_count_, rv);
155 } 244 }
156
157 if (quit_in_callback_)
158 MessageLoop::current()->Quit();
159 } 245 }
160 246
161 bool has_completed() const { 247 bool has_completed() const {
162 return completed_; 248 return completed_;
163 } 249 }
164 250
165 // Shorthands for commonly used commands. 251 // Shorthands for commonly used commands.
166 252
167 bool Run(DnsTransactionFactory* factory) { 253 bool Run(DnsTransactionFactory* factory) {
168 StartTransaction(factory); 254 StartTransaction(factory);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 void ConfigureFactory() { 299 void ConfigureFactory() {
214 socket_factory_.reset(new TestSocketFactory()); 300 socket_factory_.reset(new TestSocketFactory());
215 session_ = new DnsSession( 301 session_ = new DnsSession(
216 config_, 302 config_,
217 socket_factory_.get(), 303 socket_factory_.get(),
218 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)), 304 base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)),
219 NULL /* NetLog */); 305 NULL /* NetLog */);
220 transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get()); 306 transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get());
221 } 307 }
222 308
223 // Each socket used by a DnsTransaction expects only one write and zero or one 309 void AddSocketData(scoped_ptr<DnsSocketData> data) {
224 // reads. 310 transaction_ids_.push_back(data->query_id());
311 socket_factory_->AddSocketDataProvider(data->GetProvider());
312 socket_data_.push_back(data.release());
313 }
225 314
226 // Add expected query for |dotted_name| and |qtype| with |id| and response 315 // Add expected query for |dotted_name| and |qtype| with |id| and response
227 // taken verbatim from |data| of |data_length| bytes. The transaction id in 316 // taken verbatim from |data| of |data_length| bytes. The transaction id in
228 // |data| should equal |id|, unless testing mismatched response. 317 // |data| should equal |id|, unless testing mismatched response.
229 void AddResponse(const std::string& dotted_name, 318 void AddQueryAndResponse(uint16 id,
230 uint16 qtype, 319 const char* dotted_name,
231 uint16 id, 320 uint16 qtype,
232 const char* data, 321 const uint8* response_data,
233 size_t data_length, 322 size_t response_length,
234 IoMode mode) { 323 IoMode mode) {
235 CHECK(socket_factory_.get()); 324 CHECK(socket_factory_.get());
236 DnsQuery* query = new DnsQuery(id, DomainFromDot(dotted_name), qtype); 325 scoped_ptr<DnsSocketData> data(
237 queries_.push_back(query); 326 new DnsSocketData(id, dotted_name, qtype, mode));
238 327 data->AddResponseData(response_data, response_length, mode);
239 // The response is only used to hold the IOBuffer. 328 AddSocketData(data.Pass());
240 DnsResponse* response = new DnsResponse(data, data_length, 0);
241 responses_.push_back(response);
242
243 writes_.push_back(MockWrite(mode,
244 query->io_buffer()->data(),
245 query->io_buffer()->size()));
246 reads_.push_back(MockRead(mode,
247 response->io_buffer()->data(),
248 data_length));
249
250 transaction_ids_.push_back(id);
251 } 329 }
252 330
253 void AddAsyncResponse(const std::string& dotted_name, 331 void AddAsyncQueryAndResponse(uint16 id,
254 uint16 qtype, 332 const char* dotted_name,
255 uint16 id, 333 uint16 qtype,
256 const char* data, 334 const uint8* data,
257 size_t data_length) { 335 size_t data_length) {
258 AddResponse(dotted_name, qtype, id, data, data_length, ASYNC); 336 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC);
337 }
338
339 void AddSyncQueryAndResponse(uint16 id,
340 const char* dotted_name,
341 uint16 qtype,
342 const uint8* data,
343 size_t data_length) {
344 AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS);
259 } 345 }
260 346
261 // Add expected query of |dotted_name| and |qtype| and no response. 347 // Add expected query of |dotted_name| and |qtype| and no response.
262 void AddTimeout(const char* dotted_name, uint16 qtype) { 348 void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) {
263 CHECK(socket_factory_.get()); 349 CHECK(socket_factory_.get());
264 uint16 id = base::RandInt(0, kuint16max); 350 uint16 id = base::RandInt(0, kuint16max);
265 DnsQuery* query = new DnsQuery(id, DomainFromDot(dotted_name), qtype); 351 scoped_ptr<DnsSocketData> data(
266 queries_.push_back(query); 352 new DnsSocketData(id, dotted_name, qtype, ASYNC));
267 353 AddSocketData(data.Pass());
268 writes_.push_back(MockWrite(ASYNC,
269 query->io_buffer()->data(),
270 query->io_buffer()->size()));
271 // Empty MockRead indicates no data.
272 reads_.push_back(MockRead());
273 transaction_ids_.push_back(id);
274 } 354 }
275 355
276 // Add expected query of |dotted_name| and |qtype| and response with no answer 356 // Add expected query of |dotted_name| and |qtype| and matching response with
277 // and rcode set to |rcode|. 357 // no answer and RCODE set to |rcode|. The id will be generated randomly.
278 void AddRcode(const char* dotted_name, uint16 qtype, int rcode, IoMode mode) { 358 void AddQueryAndRcode(const char* dotted_name,
359 uint16 qtype,
360 int rcode,
361 IoMode mode) {
279 CHECK(socket_factory_.get()); 362 CHECK(socket_factory_.get());
280 CHECK_NE(dns_protocol::kRcodeNOERROR, rcode); 363 CHECK_NE(dns_protocol::kRcodeNOERROR, rcode);
281 uint16 id = base::RandInt(0, kuint16max); 364 uint16 id = base::RandInt(0, kuint16max);
282 DnsQuery* query = new DnsQuery(id, DomainFromDot(dotted_name), qtype); 365 scoped_ptr<DnsSocketData> data(
283 queries_.push_back(query); 366 new DnsSocketData(id, dotted_name, qtype, mode));
284 367 data->AddRcode(rcode, mode);
285 DnsResponse* response = new DnsResponse(query->io_buffer()->data(), 368 AddSocketData(data.Pass());
286 query->io_buffer()->size(),
287 0);
288 dns_protocol::Header* header =
289 reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data());
290 header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode);
291 responses_.push_back(response);
292
293 writes_.push_back(MockWrite(mode,
294 query->io_buffer()->data(),
295 query->io_buffer()->size()));
296 reads_.push_back(MockRead(mode,
297 response->io_buffer()->data(),
298 query->io_buffer()->size()));
299 transaction_ids_.push_back(id);
300 } 369 }
301 370
302 void AddAsyncRcode(const char* dotted_name, uint16 qtype, int rcode) { 371 void AddAsyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
303 AddRcode(dotted_name, qtype, rcode, ASYNC); 372 AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC);
304 } 373 }
305 374
306 // Call after all Add* calls to prepare data for |socket_factory_|. 375 void AddSyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
307 // This separation is necessary because the |reads_| and |writes_| vectors 376 AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS);
308 // could reallocate their data during those calls.
309 void PrepareSockets() {
310 CHECK_EQ(writes_.size(), reads_.size());
311 for (size_t i = 0; i < writes_.size(); ++i) {
312 DelayedSocketData* data;
313 if (reads_[i].data) {
314 data = new DelayedSocketData(1, &reads_[i], 1, &writes_[i], 1);
315 } else {
316 // Timeout.
317 data = new DelayedSocketData(2, NULL, 0, &writes_[i], 1);
318 }
319 socket_data_.push_back(data);
320 socket_factory_->AddSocketDataProvider(data);
321 }
322 } 377 }
323 378
324 // Checks if the sockets were connected in the order matching the indices in 379 // Checks if the sockets were connected in the order matching the indices in
325 // |servers|. 380 // |servers|.
326 void CheckServerOrder(const unsigned* servers, size_t num_attempts) { 381 void CheckServerOrder(const unsigned* servers, size_t num_attempts) {
327 ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints.size()); 382 ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints.size());
328 for (size_t i = 0; i < num_attempts; ++i) { 383 for (size_t i = 0; i < num_attempts; ++i) {
329 EXPECT_EQ(socket_factory_->remote_endpoints[i], 384 EXPECT_EQ(socket_factory_->remote_endpoints[i],
330 session_->config().nameservers[servers[i]]); 385 session_->config().nameservers[servers[i]]);
331 } 386 }
332 } 387 }
333 388
334 void SetUp() OVERRIDE { 389 void SetUp() OVERRIDE {
335 // By default set one server, 390 // By default set one server,
336 ConfigureNumServers(1); 391 ConfigureNumServers(1);
337 // and no retransmissions, 392 // and no retransmissions,
338 config_.attempts = 1; 393 config_.attempts = 1;
339 // but long enough timeout for memory tests. 394 // but long enough timeout for memory tests.
340 config_.timeout = TestTimeouts::action_timeout(); 395 config_.timeout = TestTimeouts::action_timeout();
341 ConfigureFactory(); 396 ConfigureFactory();
342 } 397 }
343 398
344 void TearDown() OVERRIDE { 399 void TearDown() OVERRIDE {
345 // Check that all socket data was at least written to. 400 // Check that all socket data was at least written to.
346 for (size_t i = 0; i < socket_data_.size(); ++i) { 401 for (size_t i = 0; i < socket_data_.size(); ++i) {
347 EXPECT_GT(socket_data_[i]->write_index(), 0u); 402 EXPECT_TRUE(socket_data_[i]->was_written()) << i;
348 } 403 }
349 } 404 }
350 405
351 protected: 406 protected:
352 int GetNextId(int min, int max) { 407 int GetNextId(int min, int max) {
353 EXPECT_FALSE(transaction_ids_.empty()); 408 EXPECT_FALSE(transaction_ids_.empty());
354 int id = transaction_ids_.front(); 409 int id = transaction_ids_.front();
355 transaction_ids_.pop_front(); 410 transaction_ids_.pop_front();
356 EXPECT_GE(id, min); 411 EXPECT_GE(id, min);
357 EXPECT_LE(id, max); 412 EXPECT_LE(id, max);
358 return id; 413 return id;
359 } 414 }
360 415
361 DnsConfig config_; 416 DnsConfig config_;
362 417
363 // Holders for the buffers behind MockRead/MockWrites (they do not own them). 418 ScopedVector<DnsSocketData> socket_data_;
364 ScopedVector<DnsQuery> queries_;
365 ScopedVector<DnsResponse> responses_;
366
367 // Holders for MockRead/MockWrites (SocketDataProvider does not own it).
368 std::vector<MockRead> reads_;
369 std::vector<MockWrite> writes_;
370
371 // Holder for the socket data (MockClientSocketFactory does not own it).
372 ScopedVector<DelayedSocketData> socket_data_;
373 419
374 std::deque<int> transaction_ids_; 420 std::deque<int> transaction_ids_;
375 scoped_ptr<TestSocketFactory> socket_factory_; 421 scoped_ptr<TestSocketFactory> socket_factory_;
376 scoped_refptr<DnsSession> session_; 422 scoped_refptr<DnsSession> session_;
377 scoped_ptr<DnsTransactionFactory> transaction_factory_; 423 scoped_ptr<DnsTransactionFactory> transaction_factory_;
378 }; 424 };
379 425
380 TEST_F(DnsTransactionTest, Lookup) { 426 TEST_F(DnsTransactionTest, Lookup) {
381 AddAsyncResponse(kT0HostName, 427 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
382 kT0Qtype, 428 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
383 0 /* id */,
384 reinterpret_cast<const char*>(kT0ResponseDatagram),
385 arraysize(kT0ResponseDatagram));
386 PrepareSockets();
387 429
388 TransactionHelper helper0(kT0HostName, 430 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
389 kT0Qtype,
390 kT0RecordCount);
391 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 431 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
392 } 432 }
393 433
394 // Concurrent lookup tests assume that DnsTransaction::Start immediately 434 // Concurrent lookup tests assume that DnsTransaction::Start immediately
395 // consumes a socket from ClientSocketFactory. 435 // consumes a socket from ClientSocketFactory.
396 TEST_F(DnsTransactionTest, ConcurrentLookup) { 436 TEST_F(DnsTransactionTest, ConcurrentLookup) {
397 AddAsyncResponse(kT0HostName, 437 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
398 kT0Qtype, 438 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
399 0 /* id */, 439 AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype,
400 reinterpret_cast<const char*>(kT0ResponseDatagram), 440 kT1ResponseDatagram, arraysize(kT1ResponseDatagram));
401 arraysize(kT0ResponseDatagram));
402 AddAsyncResponse(kT1HostName,
403 kT1Qtype,
404 1 /* id */,
405 reinterpret_cast<const char*>(kT1ResponseDatagram),
406 arraysize(kT1ResponseDatagram));
407 PrepareSockets();
408 441
409 TransactionHelper helper0(kT0HostName, 442 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
410 kT0Qtype,
411 kT0RecordCount);
412 helper0.StartTransaction(transaction_factory_.get()); 443 helper0.StartTransaction(transaction_factory_.get());
413 TransactionHelper helper1(kT1HostName, 444 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount);
414 kT1Qtype,
415 kT1RecordCount);
416 helper1.StartTransaction(transaction_factory_.get()); 445 helper1.StartTransaction(transaction_factory_.get());
417 446
418 MessageLoop::current()->RunAllPending(); 447 MessageLoop::current()->RunAllPending();
419 448
420 EXPECT_TRUE(helper0.has_completed()); 449 EXPECT_TRUE(helper0.has_completed());
421 EXPECT_TRUE(helper1.has_completed()); 450 EXPECT_TRUE(helper1.has_completed());
422 } 451 }
423 452
424 TEST_F(DnsTransactionTest, CancelLookup) { 453 TEST_F(DnsTransactionTest, CancelLookup) {
425 AddAsyncResponse(kT0HostName, 454 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
426 kT0Qtype, 455 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
427 0 /* id */, 456 AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype,
428 reinterpret_cast<const char*>(kT0ResponseDatagram), 457 kT1ResponseDatagram, arraysize(kT1ResponseDatagram));
429 arraysize(kT0ResponseDatagram));
430 AddAsyncResponse(kT1HostName,
431 kT1Qtype,
432 1 /* id */,
433 reinterpret_cast<const char*>(kT1ResponseDatagram),
434 arraysize(kT1ResponseDatagram));
435 PrepareSockets();
436 458
437 TransactionHelper helper0(kT0HostName, 459 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
438 kT0Qtype,
439 kT0RecordCount);
440 helper0.StartTransaction(transaction_factory_.get()); 460 helper0.StartTransaction(transaction_factory_.get());
441 TransactionHelper helper1(kT1HostName, 461 TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount);
442 kT1Qtype,
443 kT1RecordCount);
444 helper1.StartTransaction(transaction_factory_.get()); 462 helper1.StartTransaction(transaction_factory_.get());
445 463
446 helper0.Cancel(); 464 helper0.Cancel();
447 465
448 MessageLoop::current()->RunAllPending(); 466 MessageLoop::current()->RunAllPending();
449 467
450 EXPECT_FALSE(helper0.has_completed()); 468 EXPECT_FALSE(helper0.has_completed());
451 EXPECT_TRUE(helper1.has_completed()); 469 EXPECT_TRUE(helper1.has_completed());
452 } 470 }
453 471
454 TEST_F(DnsTransactionTest, DestroyFactory) { 472 TEST_F(DnsTransactionTest, DestroyFactory) {
455 AddAsyncResponse(kT0HostName, 473 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
456 kT0Qtype, 474 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
457 0 /* id */,
458 reinterpret_cast<const char*>(kT0ResponseDatagram),
459 arraysize(kT0ResponseDatagram));
460 PrepareSockets();
461 475
462 TransactionHelper helper0(kT0HostName, 476 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
463 kT0Qtype,
464 kT0RecordCount);
465 helper0.StartTransaction(transaction_factory_.get()); 477 helper0.StartTransaction(transaction_factory_.get());
466 478
467 // Destroying the client does not affect running requests. 479 // Destroying the client does not affect running requests.
468 transaction_factory_.reset(NULL); 480 transaction_factory_.reset(NULL);
469 481
470 MessageLoop::current()->RunAllPending(); 482 MessageLoop::current()->RunAllPending();
471 483
472 EXPECT_TRUE(helper0.has_completed()); 484 EXPECT_TRUE(helper0.has_completed());
473 } 485 }
474 486
475 TEST_F(DnsTransactionTest, CancelFromCallback) { 487 TEST_F(DnsTransactionTest, CancelFromCallback) {
476 AddAsyncResponse(kT0HostName, 488 AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
477 kT0Qtype, 489 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
478 0 /* id */,
479 reinterpret_cast<const char*>(kT0ResponseDatagram),
480 arraysize(kT0ResponseDatagram));
481 PrepareSockets();
482 490
483 TransactionHelper helper0(kT0HostName, 491 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
484 kT0Qtype,
485 kT0RecordCount);
486 helper0.set_cancel_in_callback(); 492 helper0.set_cancel_in_callback();
487 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 493 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
488 } 494 }
489 495
496 TEST_F(DnsTransactionTest, MismatchedResponseSync) {
497 config_.attempts = 2;
498 config_.timeout = TestTimeouts::tiny_timeout();
499 ConfigureFactory();
500
501 // Attempt receives mismatched response followed by valid response.
502 scoped_ptr<DnsSocketData> data(
503 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS));
504 data->AddResponseData(kT1ResponseDatagram,
505 arraysize(kT1ResponseDatagram), SYNCHRONOUS);
506 data->AddResponseData(kT0ResponseDatagram,
507 arraysize(kT0ResponseDatagram), SYNCHRONOUS);
508 AddSocketData(data.Pass());
509
510 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
511 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
512 }
513
514 TEST_F(DnsTransactionTest, MismatchedResponseAsync) {
515 config_.attempts = 2;
516 config_.timeout = TestTimeouts::tiny_timeout();
517 ConfigureFactory();
518
519 // First attempt receives mismatched response followed by valid response.
520 // Second attempt times out.
521 scoped_ptr<DnsSocketData> data(
522 new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC));
523 data->AddResponseData(kT1ResponseDatagram,
524 arraysize(kT1ResponseDatagram), ASYNC);
525 data->AddResponseData(kT0ResponseDatagram,
526 arraysize(kT0ResponseDatagram), ASYNC);
527 AddSocketData(data.Pass());
528 AddQueryAndTimeout(kT0HostName, kT0Qtype);
529
530 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
531 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
532 }
533
534 TEST_F(DnsTransactionTest, MismatchedResponseFail) {
535 config_.timeout = TestTimeouts::tiny_timeout();
536 ConfigureFactory();
537
538 // Attempt receives mismatched response but times out because only one attempt
539 // is allowed.
540 AddAsyncQueryAndResponse(1 /* id */, kT0HostName, kT0Qtype,
541 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
542
543 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
544 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
545 }
546
490 TEST_F(DnsTransactionTest, ServerFail) { 547 TEST_F(DnsTransactionTest, ServerFail) {
491 AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL); 548 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
492 PrepareSockets();
493 549
494 TransactionHelper helper0(kT0HostName, 550 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED);
495 kT0Qtype,
496 ERR_DNS_SERVER_FAILED);
497 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 551 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
498 } 552 }
499 553
500 TEST_F(DnsTransactionTest, NoDomain) { 554 TEST_F(DnsTransactionTest, NoDomain) {
501 AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN); 555 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
502 PrepareSockets();
503 556
504 TransactionHelper helper0(kT0HostName, 557 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED);
505 kT0Qtype,
506 ERR_NAME_NOT_RESOLVED);
507 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 558 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
508 } 559 }
509 560
510 TEST_F(DnsTransactionTest, Timeout) { 561 TEST_F(DnsTransactionTest, Timeout) {
511 config_.attempts = 3; 562 config_.attempts = 3;
512 // Use short timeout to speed up the test. 563 // Use short timeout to speed up the test.
513 config_.timeout = TestTimeouts::tiny_timeout(); 564 config_.timeout = TestTimeouts::tiny_timeout();
514 ConfigureFactory(); 565 ConfigureFactory();
515 566
516 AddTimeout(kT0HostName, kT0Qtype); 567 AddQueryAndTimeout(kT0HostName, kT0Qtype);
517 AddTimeout(kT0HostName, kT0Qtype); 568 AddQueryAndTimeout(kT0HostName, kT0Qtype);
518 AddTimeout(kT0HostName, kT0Qtype); 569 AddQueryAndTimeout(kT0HostName, kT0Qtype);
519 PrepareSockets();
520 570
521 TransactionHelper helper0(kT0HostName, 571 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
522 kT0Qtype,
523 ERR_DNS_TIMED_OUT);
524 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); 572 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
525 MessageLoop::current()->AssertIdle(); 573 MessageLoop::current()->AssertIdle();
526 } 574 }
527 575
528 TEST_F(DnsTransactionTest, ServerFallbackAndRotate) { 576 TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
529 // Test that we fallback on both server failure and timeout. 577 // Test that we fallback on both server failure and timeout.
530 config_.attempts = 2; 578 config_.attempts = 2;
531 // The next request should start from the next server. 579 // The next request should start from the next server.
532 config_.rotate = true; 580 config_.rotate = true;
533 ConfigureNumServers(3); 581 ConfigureNumServers(3);
534 // Use short timeout to speed up the test. 582 // Use short timeout to speed up the test.
535 config_.timeout = TestTimeouts::tiny_timeout(); 583 config_.timeout = TestTimeouts::tiny_timeout();
536 ConfigureFactory(); 584 ConfigureFactory();
537 585
538 // Responses for first request. 586 // Responses for first request.
539 AddTimeout(kT0HostName, kT0Qtype); 587 AddQueryAndTimeout(kT0HostName, kT0Qtype);
540 AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL); 588 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
541 AddTimeout(kT0HostName, kT0Qtype); 589 AddQueryAndTimeout(kT0HostName, kT0Qtype);
542 AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL); 590 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
543 AddAsyncRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN); 591 AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
544 // Responses for second request. 592 // Responses for second request.
545 AddAsyncRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL); 593 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL);
546 AddAsyncRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN); 594 AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN);
547 PrepareSockets();
548 595
549 TransactionHelper helper0(kT0HostName, 596 TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED);
550 kT0Qtype, 597 TransactionHelper helper1(kT1HostName, kT1Qtype, ERR_NAME_NOT_RESOLVED);
551 ERR_NAME_NOT_RESOLVED);
552 TransactionHelper helper1(kT1HostName,
553 kT1Qtype,
554 ERR_NAME_NOT_RESOLVED);
555 598
556 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get())); 599 EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
557 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); 600 EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
558 601
559 unsigned kOrder[] = { 602 unsigned kOrder[] = {
560 0, 1, 2, 0, 1, // The first transaction. 603 0, 1, 2, 0, 1, // The first transaction.
561 1, 2, // The second transaction starts from the next server. 604 1, 2, // The second transaction starts from the next server.
562 }; 605 };
563 CheckServerOrder(kOrder, arraysize(kOrder)); 606 CheckServerOrder(kOrder, arraysize(kOrder));
564 } 607 }
565 608
566 TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) { 609 TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) {
567 config_.ndots = 2; 610 config_.ndots = 2;
568 config_.search.push_back("a"); 611 config_.search.push_back("a");
569 config_.search.push_back("b"); 612 config_.search.push_back("b");
570 config_.search.push_back("c"); 613 config_.search.push_back("c");
571 config_.rotate = true; 614 config_.rotate = true;
572 ConfigureNumServers(2); 615 ConfigureNumServers(2);
573 ConfigureFactory(); 616 ConfigureFactory();
574 617
575 AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 618 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
576 AddAsyncRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 619 dns_protocol::kRcodeNXDOMAIN);
577 AddAsyncRcode("x.y.z.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 620 AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA,
578 AddAsyncRcode("x.y.z.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 621 dns_protocol::kRcodeNXDOMAIN);
579 PrepareSockets(); 622 AddAsyncQueryAndRcode("x.y.z.b", dns_protocol::kTypeA,
623 dns_protocol::kRcodeNXDOMAIN);
624 AddAsyncQueryAndRcode("x.y.z.c", dns_protocol::kTypeA,
625 dns_protocol::kRcodeNXDOMAIN);
580 626
581 TransactionHelper helper0("x.y.z", 627 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA,
582 dns_protocol::kTypeA,
583 ERR_NAME_NOT_RESOLVED); 628 ERR_NAME_NOT_RESOLVED);
584 629
585 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 630 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
586 631
587 // Also check if suffix search causes server rotation. 632 // Also check if suffix search causes server rotation.
588 unsigned kOrder0[] = { 0, 1, 0, 1 }; 633 unsigned kOrder0[] = { 0, 1, 0, 1 };
589 CheckServerOrder(kOrder0, arraysize(kOrder0)); 634 CheckServerOrder(kOrder0, arraysize(kOrder0));
590 } 635 }
591 636
592 TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) { 637 TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) {
593 config_.ndots = 2; 638 config_.ndots = 2;
594 config_.search.push_back("a"); 639 config_.search.push_back("a");
595 config_.search.push_back("b"); 640 config_.search.push_back("b");
596 config_.search.push_back("c"); 641 config_.search.push_back("c");
597 ConfigureFactory(); 642 ConfigureFactory();
598 643
599 // Responses for first transaction. 644 // Responses for first transaction.
600 AddAsyncRcode("x.y.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 645 AddAsyncQueryAndRcode("x.y.a", dns_protocol::kTypeA,
601 AddAsyncRcode("x.y.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 646 dns_protocol::kRcodeNXDOMAIN);
602 AddAsyncRcode("x.y.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 647 AddAsyncQueryAndRcode("x.y.b", dns_protocol::kTypeA,
603 AddAsyncRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 648 dns_protocol::kRcodeNXDOMAIN);
649 AddAsyncQueryAndRcode("x.y.c", dns_protocol::kTypeA,
650 dns_protocol::kRcodeNXDOMAIN);
651 AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA,
652 dns_protocol::kRcodeNXDOMAIN);
604 // Responses for second transaction. 653 // Responses for second transaction.
605 AddAsyncRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 654 AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA,
606 AddAsyncRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 655 dns_protocol::kRcodeNXDOMAIN);
607 AddAsyncRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 656 AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA,
657 dns_protocol::kRcodeNXDOMAIN);
658 AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA,
659 dns_protocol::kRcodeNXDOMAIN);
608 // Responses for third transaction. 660 // Responses for third transaction.
609 AddAsyncRcode("x", dns_protocol::kTypeAAAA, dns_protocol::kRcodeNXDOMAIN); 661 AddAsyncQueryAndRcode("x", dns_protocol::kTypeAAAA,
610 PrepareSockets(); 662 dns_protocol::kRcodeNXDOMAIN);
611 663
612 TransactionHelper helper0("x.y", 664 TransactionHelper helper0("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
613 dns_protocol::kTypeA,
614 ERR_NAME_NOT_RESOLVED);
615 665
616 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 666 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
617 667
618 // A single-label name. 668 // A single-label name.
619 TransactionHelper helper1("x", 669 TransactionHelper helper1("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
620 dns_protocol::kTypeA,
621 ERR_NAME_NOT_RESOLVED);
622 670
623 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); 671 EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
624 672
625 // A fully-qualified name. 673 // A fully-qualified name.
626 TransactionHelper helper2("x.", 674 TransactionHelper helper2("x.", dns_protocol::kTypeAAAA,
627 dns_protocol::kTypeAAAA,
628 ERR_NAME_NOT_RESOLVED); 675 ERR_NAME_NOT_RESOLVED);
629 676
630 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); 677 EXPECT_TRUE(helper2.Run(transaction_factory_.get()));
631 } 678 }
632 679
633 TEST_F(DnsTransactionTest, EmptySuffixSearch) { 680 TEST_F(DnsTransactionTest, EmptySuffixSearch) {
634 // Responses for first transaction. 681 // Responses for first transaction.
635 AddAsyncRcode("x", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 682 AddAsyncQueryAndRcode("x", dns_protocol::kTypeA,
636 PrepareSockets(); 683 dns_protocol::kRcodeNXDOMAIN);
637 684
638 // A fully-qualified name. 685 // A fully-qualified name.
639 TransactionHelper helper0("x.", 686 TransactionHelper helper0("x.", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
640 dns_protocol::kTypeA,
641 ERR_NAME_NOT_RESOLVED);
642 687
643 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 688 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
644 689
645 // A single label name is not even attempted. 690 // A single label name is not even attempted.
646 TransactionHelper helper1("singlelabel", 691 TransactionHelper helper1("singlelabel", dns_protocol::kTypeA,
647 dns_protocol::kTypeA,
648 ERR_DNS_SEARCH_EMPTY); 692 ERR_DNS_SEARCH_EMPTY);
649 693
650 helper1.StartTransaction(transaction_factory_.get()); 694 helper1.StartTransaction(transaction_factory_.get());
651 EXPECT_TRUE(helper1.has_completed()); 695 EXPECT_TRUE(helper1.has_completed());
652 } 696 }
653 697
654 TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) { 698 TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) {
655 config_.search.push_back("a"); 699 config_.search.push_back("a");
656 config_.search.push_back("b"); 700 config_.search.push_back("b");
657 config_.search.push_back("c"); 701 config_.search.push_back("c");
658 config_.append_to_multi_label_name = false; 702 config_.append_to_multi_label_name = false;
659 ConfigureFactory(); 703 ConfigureFactory();
660 704
661 // Responses for first transaction. 705 // Responses for first transaction.
662 AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 706 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
707 dns_protocol::kRcodeNXDOMAIN);
663 // Responses for second transaction. 708 // Responses for second transaction.
664 AddAsyncRcode("x.y", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 709 AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA,
710 dns_protocol::kRcodeNXDOMAIN);
665 // Responses for third transaction. 711 // Responses for third transaction.
666 AddAsyncRcode("x.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 712 AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA,
667 AddAsyncRcode("x.b", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 713 dns_protocol::kRcodeNXDOMAIN);
668 AddAsyncRcode("x.c", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 714 AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA,
669 PrepareSockets(); 715 dns_protocol::kRcodeNXDOMAIN);
716 AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA,
717 dns_protocol::kRcodeNXDOMAIN);
670 718
671 TransactionHelper helper0("x.y.z", 719 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA,
672 dns_protocol::kTypeA,
673 ERR_NAME_NOT_RESOLVED); 720 ERR_NAME_NOT_RESOLVED);
674 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 721 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
675 722
676 TransactionHelper helper1("x.y", 723 TransactionHelper helper1("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
677 dns_protocol::kTypeA,
678 ERR_NAME_NOT_RESOLVED);
679 EXPECT_TRUE(helper1.Run(transaction_factory_.get())); 724 EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
680 725
681 TransactionHelper helper2("x", 726 TransactionHelper helper2("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
682 dns_protocol::kTypeA,
683 ERR_NAME_NOT_RESOLVED);
684 EXPECT_TRUE(helper2.Run(transaction_factory_.get())); 727 EXPECT_TRUE(helper2.Run(transaction_factory_.get()));
685 } 728 }
686 729
687 const uint8 kResponseNoData[] = { 730 const uint8 kResponseNoData[] = {
688 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 731 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
689 // Question 732 // Question
690 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01, 733 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01,
691 // Authority section, SOA record, TTL 0x3E6 734 // Authority section, SOA record, TTL 0x3E6
692 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6, 735 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6,
693 // Minimal RDATA, 18 bytes 736 // Minimal RDATA, 18 bytes
694 0x00, 0x12, 737 0x00, 0x12,
695 0x00, 0x00, 738 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 739 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 740 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 741 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 742 0x00, 0x00, 0x00, 0x00,
700 }; 743 };
701 744
702 TEST_F(DnsTransactionTest, SuffixSearchStop) { 745 TEST_F(DnsTransactionTest, SuffixSearchStop) {
703 config_.ndots = 2; 746 config_.ndots = 2;
704 config_.search.push_back("a"); 747 config_.search.push_back("a");
705 config_.search.push_back("b"); 748 config_.search.push_back("b");
706 config_.search.push_back("c"); 749 config_.search.push_back("c");
707 ConfigureFactory(); 750 ConfigureFactory();
708 751
709 AddAsyncRcode("x.y.z", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 752 AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
710 AddAsyncRcode("x.y.z.a", dns_protocol::kTypeA, dns_protocol::kRcodeNXDOMAIN); 753 dns_protocol::kRcodeNXDOMAIN);
711 AddAsyncResponse("x.y.z.b", 754 AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA,
712 dns_protocol::kTypeA, 755 dns_protocol::kRcodeNXDOMAIN);
713 0 /* id */, 756 AddAsyncQueryAndResponse(0 /* id */, "x.y.z.b", dns_protocol::kTypeA,
714 reinterpret_cast<const char*>(kResponseNoData), 757 kResponseNoData, arraysize(kResponseNoData));
715 arraysize(kResponseNoData));
716 PrepareSockets();
717 758
718 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */); 759 TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */);
719 760
720 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 761 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
721 } 762 }
722 763
723 TEST_F(DnsTransactionTest, SyncFirstQuery) { 764 TEST_F(DnsTransactionTest, SyncFirstQuery) {
724 config_.search.push_back("lab.ccs.neu.edu"); 765 config_.search.push_back("lab.ccs.neu.edu");
725 config_.search.push_back("ccs.neu.edu"); 766 config_.search.push_back("ccs.neu.edu");
726 ConfigureFactory(); 767 ConfigureFactory();
727 768
728 AddResponse(kT0HostName, 769 AddSyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
729 kT0Qtype, 770 kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
730 0 /* id */,
731 reinterpret_cast<const char*>(kT0ResponseDatagram),
732 arraysize(kT0ResponseDatagram),
733 SYNCHRONOUS);
734 PrepareSockets();
735 771
736 TransactionHelper helper0(kT0HostName, 772 TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
737 kT0Qtype,
738 kT0RecordCount);
739 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 773 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
740 } 774 }
741 775
742 TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) { 776 TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) {
743 config_.search.push_back("lab.ccs.neu.edu"); 777 config_.search.push_back("lab.ccs.neu.edu");
744 config_.search.push_back("ccs.neu.edu"); 778 config_.search.push_back("ccs.neu.edu");
745 ConfigureFactory(); 779 ConfigureFactory();
746 780
747 AddRcode("www.lab.ccs.neu.edu", 781 AddSyncQueryAndRcode("www.lab.ccs.neu.edu", kT2Qtype,
748 kT2Qtype, 782 dns_protocol::kRcodeNXDOMAIN);
749 dns_protocol::kRcodeNXDOMAIN, 783 // "www.ccs.neu.edu"
750 SYNCHRONOUS); 784 AddAsyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype,
751 AddResponse(kT2HostName, // "www.ccs.neu.edu" 785 kT2ResponseDatagram, arraysize(kT2ResponseDatagram));
752 kT2Qtype,
753 2 /* id */,
754 reinterpret_cast<const char*>(kT2ResponseDatagram),
755 arraysize(kT2ResponseDatagram),
756 ASYNC);
757 PrepareSockets();
758 786
759 TransactionHelper helper0("www", 787 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount);
760 kT2Qtype,
761 kT2RecordCount);
762 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 788 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
763 } 789 }
764 790
765 TEST_F(DnsTransactionTest, SyncSearchQuery) { 791 TEST_F(DnsTransactionTest, SyncSearchQuery) {
766 config_.search.push_back("lab.ccs.neu.edu"); 792 config_.search.push_back("lab.ccs.neu.edu");
767 config_.search.push_back("ccs.neu.edu"); 793 config_.search.push_back("ccs.neu.edu");
768 ConfigureFactory(); 794 ConfigureFactory();
769 795
770 AddRcode("www.lab.ccs.neu.edu", 796 AddAsyncQueryAndRcode("www.lab.ccs.neu.edu", dns_protocol::kTypeA,
771 dns_protocol::kTypeA, 797 dns_protocol::kRcodeNXDOMAIN);
772 dns_protocol::kRcodeNXDOMAIN, 798 AddSyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype,
773 ASYNC); 799 kT2ResponseDatagram, arraysize(kT2ResponseDatagram));
774 AddResponse(kT2HostName,
775 kT2Qtype,
776 2 /* id */,
777 reinterpret_cast<const char*>(kT2ResponseDatagram),
778 arraysize(kT2ResponseDatagram),
779 SYNCHRONOUS);
780 PrepareSockets();
781 800
782 TransactionHelper helper0("www", 801 TransactionHelper helper0("www", kT2Qtype, kT2RecordCount);
783 kT2Qtype,
784 kT2RecordCount);
785 EXPECT_TRUE(helper0.Run(transaction_factory_.get())); 802 EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
786 } 803 }
787 804
788 } // namespace 805 } // namespace
789 806
790 } // namespace net 807 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/dns_transaction.cc ('k') | net/socket/socket_test_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698