| Index: net/dns/dns_transaction_unittest.cc
|
| diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc
|
| deleted file mode 100644
|
| index f22478c045024a2f5eade0a3efe8e0b603776e12..0000000000000000000000000000000000000000
|
| --- a/net/dns/dns_transaction_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1011 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/dns/dns_transaction.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/rand_util.h"
|
| -#include "base/sys_byteorder.h"
|
| -#include "base/test/test_timeouts.h"
|
| -#include "net/base/dns_util.h"
|
| -#include "net/base/net_log.h"
|
| -#include "net/dns/dns_protocol.h"
|
| -#include "net/dns/dns_query.h"
|
| -#include "net/dns/dns_response.h"
|
| -#include "net/dns/dns_session.h"
|
| -#include "net/dns/dns_test_util.h"
|
| -#include "net/socket/socket_test_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace {
|
| -
|
| -std::string DomainFromDot(const base::StringPiece& dotted) {
|
| - std::string out;
|
| - EXPECT_TRUE(DNSDomainFromDot(dotted, &out));
|
| - return out;
|
| -}
|
| -
|
| -// A SocketDataProvider builder.
|
| -class DnsSocketData {
|
| - public:
|
| - // The ctor takes parameters for the DnsQuery.
|
| - DnsSocketData(uint16 id,
|
| - const char* dotted_name,
|
| - uint16 qtype,
|
| - IoMode mode,
|
| - bool use_tcp)
|
| - : query_(new DnsQuery(id, DomainFromDot(dotted_name), qtype)),
|
| - use_tcp_(use_tcp) {
|
| - if (use_tcp_) {
|
| - scoped_ptr<uint16> length(new uint16);
|
| - *length = base::HostToNet16(query_->io_buffer()->size());
|
| - writes_.push_back(MockWrite(mode,
|
| - reinterpret_cast<const char*>(length.get()),
|
| - sizeof(uint16)));
|
| - lengths_.push_back(length.release());
|
| - }
|
| - writes_.push_back(MockWrite(mode,
|
| - query_->io_buffer()->data(),
|
| - query_->io_buffer()->size()));
|
| - }
|
| - ~DnsSocketData() {}
|
| -
|
| - // All responses must be added before GetProvider.
|
| -
|
| - // Adds pre-built DnsResponse. |tcp_length| will be used in TCP mode only.
|
| - void AddResponseWithLength(scoped_ptr<DnsResponse> response, IoMode mode,
|
| - uint16 tcp_length) {
|
| - CHECK(!provider_.get());
|
| - if (use_tcp_) {
|
| - scoped_ptr<uint16> length(new uint16);
|
| - *length = base::HostToNet16(tcp_length);
|
| - reads_.push_back(MockRead(mode,
|
| - reinterpret_cast<const char*>(length.get()),
|
| - sizeof(uint16)));
|
| - lengths_.push_back(length.release());
|
| - }
|
| - reads_.push_back(MockRead(mode,
|
| - response->io_buffer()->data(),
|
| - response->io_buffer()->size()));
|
| - responses_.push_back(response.release());
|
| - }
|
| -
|
| - // Adds pre-built DnsResponse.
|
| - void AddResponse(scoped_ptr<DnsResponse> response, IoMode mode) {
|
| - uint16 tcp_length = response->io_buffer()->size();
|
| - AddResponseWithLength(response.Pass(), mode, tcp_length);
|
| - }
|
| -
|
| - // Adds pre-built response from |data| buffer.
|
| - void AddResponseData(const uint8* data, size_t length, IoMode mode) {
|
| - CHECK(!provider_.get());
|
| - AddResponse(make_scoped_ptr(
|
| - new DnsResponse(reinterpret_cast<const char*>(data), length, 0)), mode);
|
| - }
|
| -
|
| - // Add no-answer (RCODE only) response matching the query.
|
| - void AddRcode(int rcode, IoMode mode) {
|
| - scoped_ptr<DnsResponse> response(
|
| - new DnsResponse(query_->io_buffer()->data(),
|
| - query_->io_buffer()->size(),
|
| - 0));
|
| - dns_protocol::Header* header =
|
| - reinterpret_cast<dns_protocol::Header*>(response->io_buffer()->data());
|
| - header->flags |= base::HostToNet16(dns_protocol::kFlagResponse | rcode);
|
| - AddResponse(response.Pass(), mode);
|
| - }
|
| -
|
| - // Add error response.
|
| - void AddReadError(int error, IoMode mode) {
|
| - reads_.push_back(MockRead(mode, error));
|
| - }
|
| -
|
| - // Build, if needed, and return the SocketDataProvider. No new responses
|
| - // should be added afterwards.
|
| - SocketDataProvider* GetProvider() {
|
| - if (provider_.get())
|
| - return provider_.get();
|
| - // Terminate the reads with ERR_IO_PENDING to prevent overrun and default to
|
| - // timeout.
|
| - reads_.push_back(MockRead(ASYNC, ERR_IO_PENDING));
|
| - provider_.reset(new DelayedSocketData(1, &reads_[0], reads_.size(),
|
| - &writes_[0], writes_.size()));
|
| - if (use_tcp_) {
|
| - provider_->set_connect_data(MockConnect(reads_[0].mode, OK));
|
| - }
|
| - return provider_.get();
|
| - }
|
| -
|
| - uint16 query_id() const {
|
| - return query_->id();
|
| - }
|
| -
|
| - // Returns true if the expected query was written to the socket.
|
| - bool was_written() const {
|
| - CHECK(provider_.get());
|
| - return provider_->write_index() > 0;
|
| - }
|
| -
|
| - private:
|
| - scoped_ptr<DnsQuery> query_;
|
| - bool use_tcp_;
|
| - ScopedVector<uint16> lengths_;
|
| - ScopedVector<DnsResponse> responses_;
|
| - std::vector<MockWrite> writes_;
|
| - std::vector<MockRead> reads_;
|
| - scoped_ptr<DelayedSocketData> provider_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DnsSocketData);
|
| -};
|
| -
|
| -class TestSocketFactory;
|
| -
|
| -// A variant of MockUDPClientSocket which always fails to Connect.
|
| -class FailingUDPClientSocket : public MockUDPClientSocket {
|
| - public:
|
| - FailingUDPClientSocket(SocketDataProvider* data,
|
| - net::NetLog* net_log)
|
| - : MockUDPClientSocket(data, net_log) {
|
| - }
|
| - ~FailingUDPClientSocket() override {}
|
| - int Connect(const IPEndPoint& endpoint) override {
|
| - return ERR_CONNECTION_REFUSED;
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(FailingUDPClientSocket);
|
| -};
|
| -
|
| -// A variant of MockUDPClientSocket which notifies the factory OnConnect.
|
| -class TestUDPClientSocket : public MockUDPClientSocket {
|
| - public:
|
| - TestUDPClientSocket(TestSocketFactory* factory,
|
| - SocketDataProvider* data,
|
| - net::NetLog* net_log)
|
| - : MockUDPClientSocket(data, net_log), factory_(factory) {
|
| - }
|
| - ~TestUDPClientSocket() override {}
|
| - int Connect(const IPEndPoint& endpoint) override;
|
| -
|
| - private:
|
| - TestSocketFactory* factory_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestUDPClientSocket);
|
| -};
|
| -
|
| -// Creates TestUDPClientSockets and keeps endpoints reported via OnConnect.
|
| -class TestSocketFactory : public MockClientSocketFactory {
|
| - public:
|
| - TestSocketFactory() : fail_next_socket_(false) {}
|
| - ~TestSocketFactory() override {}
|
| -
|
| - scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
|
| - DatagramSocket::BindType bind_type,
|
| - const RandIntCallback& rand_int_cb,
|
| - net::NetLog* net_log,
|
| - const net::NetLog::Source& source) override {
|
| - if (fail_next_socket_) {
|
| - fail_next_socket_ = false;
|
| - return scoped_ptr<DatagramClientSocket>(
|
| - new FailingUDPClientSocket(&empty_data_, net_log));
|
| - }
|
| - SocketDataProvider* data_provider = mock_data().GetNext();
|
| - scoped_ptr<TestUDPClientSocket> socket(
|
| - new TestUDPClientSocket(this, data_provider, net_log));
|
| - data_provider->set_socket(socket.get());
|
| - return socket.Pass();
|
| - }
|
| -
|
| - void OnConnect(const IPEndPoint& endpoint) {
|
| - remote_endpoints_.push_back(endpoint);
|
| - }
|
| -
|
| - std::vector<IPEndPoint> remote_endpoints_;
|
| - bool fail_next_socket_;
|
| -
|
| - private:
|
| - StaticSocketDataProvider empty_data_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestSocketFactory);
|
| -};
|
| -
|
| -int TestUDPClientSocket::Connect(const IPEndPoint& endpoint) {
|
| - factory_->OnConnect(endpoint);
|
| - return MockUDPClientSocket::Connect(endpoint);
|
| -}
|
| -
|
| -// Helper class that holds a DnsTransaction and handles OnTransactionComplete.
|
| -class TransactionHelper {
|
| - public:
|
| - // If |expected_answer_count| < 0 then it is the expected net error.
|
| - TransactionHelper(const char* hostname,
|
| - uint16 qtype,
|
| - int expected_answer_count)
|
| - : hostname_(hostname),
|
| - qtype_(qtype),
|
| - expected_answer_count_(expected_answer_count),
|
| - cancel_in_callback_(false),
|
| - quit_in_callback_(false),
|
| - completed_(false) {
|
| - }
|
| -
|
| - // Mark that the transaction shall be destroyed immediately upon callback.
|
| - void set_cancel_in_callback() {
|
| - cancel_in_callback_ = true;
|
| - }
|
| -
|
| - // Mark to call MessageLoop::Quit() upon callback.
|
| - void set_quit_in_callback() {
|
| - quit_in_callback_ = true;
|
| - }
|
| -
|
| - void StartTransaction(DnsTransactionFactory* factory) {
|
| - EXPECT_EQ(NULL, transaction_.get());
|
| - transaction_ = factory->CreateTransaction(
|
| - hostname_,
|
| - qtype_,
|
| - base::Bind(&TransactionHelper::OnTransactionComplete,
|
| - base::Unretained(this)),
|
| - BoundNetLog());
|
| - EXPECT_EQ(hostname_, transaction_->GetHostname());
|
| - EXPECT_EQ(qtype_, transaction_->GetType());
|
| - transaction_->Start();
|
| - }
|
| -
|
| - void Cancel() {
|
| - ASSERT_TRUE(transaction_.get() != NULL);
|
| - transaction_.reset(NULL);
|
| - }
|
| -
|
| - void OnTransactionComplete(DnsTransaction* t,
|
| - int rv,
|
| - const DnsResponse* response) {
|
| - EXPECT_FALSE(completed_);
|
| - EXPECT_EQ(transaction_.get(), t);
|
| -
|
| - completed_ = true;
|
| -
|
| - if (cancel_in_callback_) {
|
| - Cancel();
|
| - return;
|
| - }
|
| -
|
| - // Tell MessageLoop to quit now, in case any ASSERT_* fails.
|
| - if (quit_in_callback_)
|
| - base::MessageLoop::current()->Quit();
|
| -
|
| - if (expected_answer_count_ >= 0) {
|
| - ASSERT_EQ(OK, rv);
|
| - ASSERT_TRUE(response != NULL);
|
| - EXPECT_EQ(static_cast<unsigned>(expected_answer_count_),
|
| - response->answer_count());
|
| - EXPECT_EQ(qtype_, response->qtype());
|
| -
|
| - DnsRecordParser parser = response->Parser();
|
| - DnsResourceRecord record;
|
| - for (int i = 0; i < expected_answer_count_; ++i) {
|
| - EXPECT_TRUE(parser.ReadRecord(&record));
|
| - }
|
| - } else {
|
| - EXPECT_EQ(expected_answer_count_, rv);
|
| - }
|
| - }
|
| -
|
| - bool has_completed() const {
|
| - return completed_;
|
| - }
|
| -
|
| - // Shorthands for commonly used commands.
|
| -
|
| - bool Run(DnsTransactionFactory* factory) {
|
| - StartTransaction(factory);
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| - return has_completed();
|
| - }
|
| -
|
| - // Use when some of the responses are timeouts.
|
| - bool RunUntilDone(DnsTransactionFactory* factory) {
|
| - set_quit_in_callback();
|
| - StartTransaction(factory);
|
| - base::MessageLoop::current()->Run();
|
| - return has_completed();
|
| - }
|
| -
|
| - private:
|
| - std::string hostname_;
|
| - uint16 qtype_;
|
| - scoped_ptr<DnsTransaction> transaction_;
|
| - int expected_answer_count_;
|
| - bool cancel_in_callback_;
|
| - bool quit_in_callback_;
|
| -
|
| - bool completed_;
|
| -};
|
| -
|
| -class DnsTransactionTest : public testing::Test {
|
| - public:
|
| - DnsTransactionTest() {}
|
| -
|
| - // Generates |nameservers| for DnsConfig.
|
| - void ConfigureNumServers(unsigned num_servers) {
|
| - CHECK_LE(num_servers, 255u);
|
| - config_.nameservers.clear();
|
| - IPAddressNumber dns_ip;
|
| - {
|
| - bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip);
|
| - EXPECT_TRUE(rv);
|
| - }
|
| - for (unsigned i = 0; i < num_servers; ++i) {
|
| - dns_ip[3] = i;
|
| - config_.nameservers.push_back(IPEndPoint(dns_ip,
|
| - dns_protocol::kDefaultPort));
|
| - }
|
| - }
|
| -
|
| - // Called after fully configuring |config|.
|
| - void ConfigureFactory() {
|
| - socket_factory_.reset(new TestSocketFactory());
|
| - session_ = new DnsSession(
|
| - config_,
|
| - DnsSocketPool::CreateNull(socket_factory_.get()),
|
| - base::Bind(&DnsTransactionTest::GetNextId, base::Unretained(this)),
|
| - NULL /* NetLog */);
|
| - transaction_factory_ = DnsTransactionFactory::CreateFactory(session_.get());
|
| - }
|
| -
|
| - void AddSocketData(scoped_ptr<DnsSocketData> data) {
|
| - CHECK(socket_factory_.get());
|
| - transaction_ids_.push_back(data->query_id());
|
| - socket_factory_->AddSocketDataProvider(data->GetProvider());
|
| - socket_data_.push_back(data.release());
|
| - }
|
| -
|
| - // Add expected query for |dotted_name| and |qtype| with |id| and response
|
| - // taken verbatim from |data| of |data_length| bytes. The transaction id in
|
| - // |data| should equal |id|, unless testing mismatched response.
|
| - void AddQueryAndResponse(uint16 id,
|
| - const char* dotted_name,
|
| - uint16 qtype,
|
| - const uint8* response_data,
|
| - size_t response_length,
|
| - IoMode mode,
|
| - bool use_tcp) {
|
| - CHECK(socket_factory_.get());
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(id, dotted_name, qtype, mode, use_tcp));
|
| - data->AddResponseData(response_data, response_length, mode);
|
| - AddSocketData(data.Pass());
|
| - }
|
| -
|
| - void AddAsyncQueryAndResponse(uint16 id,
|
| - const char* dotted_name,
|
| - uint16 qtype,
|
| - const uint8* data,
|
| - size_t data_length) {
|
| - AddQueryAndResponse(id, dotted_name, qtype, data, data_length, ASYNC,
|
| - false);
|
| - }
|
| -
|
| - void AddSyncQueryAndResponse(uint16 id,
|
| - const char* dotted_name,
|
| - uint16 qtype,
|
| - const uint8* data,
|
| - size_t data_length) {
|
| - AddQueryAndResponse(id, dotted_name, qtype, data, data_length, SYNCHRONOUS,
|
| - false);
|
| - }
|
| -
|
| - // Add expected query of |dotted_name| and |qtype| and no response.
|
| - void AddQueryAndTimeout(const char* dotted_name, uint16 qtype) {
|
| - uint16 id = base::RandInt(0, kuint16max);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(id, dotted_name, qtype, ASYNC, false));
|
| - AddSocketData(data.Pass());
|
| - }
|
| -
|
| - // Add expected query of |dotted_name| and |qtype| and matching response with
|
| - // no answer and RCODE set to |rcode|. The id will be generated randomly.
|
| - void AddQueryAndRcode(const char* dotted_name,
|
| - uint16 qtype,
|
| - int rcode,
|
| - IoMode mode,
|
| - bool use_tcp) {
|
| - CHECK_NE(dns_protocol::kRcodeNOERROR, rcode);
|
| - uint16 id = base::RandInt(0, kuint16max);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(id, dotted_name, qtype, mode, use_tcp));
|
| - data->AddRcode(rcode, mode);
|
| - AddSocketData(data.Pass());
|
| - }
|
| -
|
| - void AddAsyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
|
| - AddQueryAndRcode(dotted_name, qtype, rcode, ASYNC, false);
|
| - }
|
| -
|
| - void AddSyncQueryAndRcode(const char* dotted_name, uint16 qtype, int rcode) {
|
| - AddQueryAndRcode(dotted_name, qtype, rcode, SYNCHRONOUS, false);
|
| - }
|
| -
|
| - // Checks if the sockets were connected in the order matching the indices in
|
| - // |servers|.
|
| - void CheckServerOrder(const unsigned* servers, size_t num_attempts) {
|
| - ASSERT_EQ(num_attempts, socket_factory_->remote_endpoints_.size());
|
| - for (size_t i = 0; i < num_attempts; ++i) {
|
| - EXPECT_EQ(socket_factory_->remote_endpoints_[i],
|
| - session_->config().nameservers[servers[i]]);
|
| - }
|
| - }
|
| -
|
| - void SetUp() override {
|
| - // By default set one server,
|
| - ConfigureNumServers(1);
|
| - // and no retransmissions,
|
| - config_.attempts = 1;
|
| - // but long enough timeout for memory tests.
|
| - config_.timeout = TestTimeouts::action_timeout();
|
| - ConfigureFactory();
|
| - }
|
| -
|
| - void TearDown() override {
|
| - // Check that all socket data was at least written to.
|
| - for (size_t i = 0; i < socket_data_.size(); ++i) {
|
| - EXPECT_TRUE(socket_data_[i]->was_written()) << i;
|
| - }
|
| - }
|
| -
|
| - protected:
|
| - int GetNextId(int min, int max) {
|
| - EXPECT_FALSE(transaction_ids_.empty());
|
| - int id = transaction_ids_.front();
|
| - transaction_ids_.pop_front();
|
| - EXPECT_GE(id, min);
|
| - EXPECT_LE(id, max);
|
| - return id;
|
| - }
|
| -
|
| - DnsConfig config_;
|
| -
|
| - ScopedVector<DnsSocketData> socket_data_;
|
| -
|
| - std::deque<int> transaction_ids_;
|
| - scoped_ptr<TestSocketFactory> socket_factory_;
|
| - scoped_refptr<DnsSession> session_;
|
| - scoped_ptr<DnsTransactionFactory> transaction_factory_;
|
| -};
|
| -
|
| -TEST_F(DnsTransactionTest, Lookup) {
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -// Concurrent lookup tests assume that DnsTransaction::Start immediately
|
| -// consumes a socket from ClientSocketFactory.
|
| -TEST_F(DnsTransactionTest, ConcurrentLookup) {
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| - AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype,
|
| - kT1ResponseDatagram, arraysize(kT1ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - helper0.StartTransaction(transaction_factory_.get());
|
| - TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount);
|
| - helper1.StartTransaction(transaction_factory_.get());
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_TRUE(helper0.has_completed());
|
| - EXPECT_TRUE(helper1.has_completed());
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, CancelLookup) {
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| - AddAsyncQueryAndResponse(1 /* id */, kT1HostName, kT1Qtype,
|
| - kT1ResponseDatagram, arraysize(kT1ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - helper0.StartTransaction(transaction_factory_.get());
|
| - TransactionHelper helper1(kT1HostName, kT1Qtype, kT1RecordCount);
|
| - helper1.StartTransaction(transaction_factory_.get());
|
| -
|
| - helper0.Cancel();
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_FALSE(helper0.has_completed());
|
| - EXPECT_TRUE(helper1.has_completed());
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, DestroyFactory) {
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - helper0.StartTransaction(transaction_factory_.get());
|
| -
|
| - // Destroying the client does not affect running requests.
|
| - transaction_factory_.reset(NULL);
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_TRUE(helper0.has_completed());
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, CancelFromCallback) {
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - helper0.set_cancel_in_callback();
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, MismatchedResponseSync) {
|
| - config_.attempts = 2;
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - // Attempt receives mismatched response followed by valid response.
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, SYNCHRONOUS, false));
|
| - data->AddResponseData(kT1ResponseDatagram,
|
| - arraysize(kT1ResponseDatagram), SYNCHRONOUS);
|
| - data->AddResponseData(kT0ResponseDatagram,
|
| - arraysize(kT0ResponseDatagram), SYNCHRONOUS);
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, MismatchedResponseAsync) {
|
| - config_.attempts = 2;
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - // First attempt receives mismatched response followed by valid response.
|
| - // Second attempt times out.
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, false));
|
| - data->AddResponseData(kT1ResponseDatagram,
|
| - arraysize(kT1ResponseDatagram), ASYNC);
|
| - data->AddResponseData(kT0ResponseDatagram,
|
| - arraysize(kT0ResponseDatagram), ASYNC);
|
| - AddSocketData(data.Pass());
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, MismatchedResponseFail) {
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - // Attempt receives mismatched response but times out because only one attempt
|
| - // is allowed.
|
| - AddAsyncQueryAndResponse(1 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, ServerFail) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, NoDomain) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, Timeout) {
|
| - config_.attempts = 3;
|
| - // Use short timeout to speed up the test.
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| - EXPECT_TRUE(base::MessageLoop::current()->IsIdleForTesting());
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, ServerFallbackAndRotate) {
|
| - // Test that we fallback on both server failure and timeout.
|
| - config_.attempts = 2;
|
| - // The next request should start from the next server.
|
| - config_.rotate = true;
|
| - ConfigureNumServers(3);
|
| - // Use short timeout to speed up the test.
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - // Responses for first request.
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
|
| - AddQueryAndTimeout(kT0HostName, kT0Qtype);
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL);
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeNXDOMAIN);
|
| - // Responses for second request.
|
| - AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL);
|
| - AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeSERVFAIL);
|
| - AddAsyncQueryAndRcode(kT1HostName, kT1Qtype, dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_NAME_NOT_RESOLVED);
|
| - TransactionHelper helper1(kT1HostName, kT1Qtype, ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| - EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
|
| -
|
| - unsigned kOrder[] = {
|
| - 0, 1, 2, 0, 1, // The first transaction.
|
| - 1, 2, 0, // The second transaction starts from the next server.
|
| - };
|
| - CheckServerOrder(kOrder, arraysize(kOrder));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, SuffixSearchAboveNdots) {
|
| - config_.ndots = 2;
|
| - config_.search.push_back("a");
|
| - config_.search.push_back("b");
|
| - config_.search.push_back("c");
|
| - config_.rotate = true;
|
| - ConfigureNumServers(2);
|
| - ConfigureFactory();
|
| -
|
| - AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.z.b", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.z.c", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - TransactionHelper helper0("x.y.z", dns_protocol::kTypeA,
|
| - ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -
|
| - // Also check if suffix search causes server rotation.
|
| - unsigned kOrder0[] = { 0, 1, 0, 1 };
|
| - CheckServerOrder(kOrder0, arraysize(kOrder0));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, SuffixSearchBelowNdots) {
|
| - config_.ndots = 2;
|
| - config_.search.push_back("a");
|
| - config_.search.push_back("b");
|
| - config_.search.push_back("c");
|
| - ConfigureFactory();
|
| -
|
| - // Responses for first transaction.
|
| - AddAsyncQueryAndRcode("x.y.a", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.b", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.c", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - // Responses for second transaction.
|
| - AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - // Responses for third transaction.
|
| - AddAsyncQueryAndRcode("x", dns_protocol::kTypeAAAA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - TransactionHelper helper0("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -
|
| - // A single-label name.
|
| - TransactionHelper helper1("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
|
| -
|
| - // A fully-qualified name.
|
| - TransactionHelper helper2("x.", dns_protocol::kTypeAAAA,
|
| - ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper2.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, EmptySuffixSearch) {
|
| - // Responses for first transaction.
|
| - AddAsyncQueryAndRcode("x", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - // A fully-qualified name.
|
| - TransactionHelper helper0("x.", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
|
| -
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -
|
| - // A single label name is not even attempted.
|
| - TransactionHelper helper1("singlelabel", dns_protocol::kTypeA,
|
| - ERR_DNS_SEARCH_EMPTY);
|
| -
|
| - helper1.Run(transaction_factory_.get());
|
| - EXPECT_TRUE(helper1.has_completed());
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, DontAppendToMultiLabelName) {
|
| - config_.search.push_back("a");
|
| - config_.search.push_back("b");
|
| - config_.search.push_back("c");
|
| - config_.append_to_multi_label_name = false;
|
| - ConfigureFactory();
|
| -
|
| - // Responses for first transaction.
|
| - AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - // Responses for second transaction.
|
| - AddAsyncQueryAndRcode("x.y", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - // Responses for third transaction.
|
| - AddAsyncQueryAndRcode("x.a", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.b", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.c", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| -
|
| - TransactionHelper helper0("x.y.z", dns_protocol::kTypeA,
|
| - ERR_NAME_NOT_RESOLVED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -
|
| - TransactionHelper helper1("x.y", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
|
| - EXPECT_TRUE(helper1.Run(transaction_factory_.get()));
|
| -
|
| - TransactionHelper helper2("x", dns_protocol::kTypeA, ERR_NAME_NOT_RESOLVED);
|
| - EXPECT_TRUE(helper2.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -const uint8 kResponseNoData[] = {
|
| - 0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
| - // Question
|
| - 0x01, 'x', 0x01, 'y', 0x01, 'z', 0x01, 'b', 0x00, 0x00, 0x01, 0x00, 0x01,
|
| - // Authority section, SOA record, TTL 0x3E6
|
| - 0x01, 'z', 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x03, 0xE6,
|
| - // Minimal RDATA, 18 bytes
|
| - 0x00, 0x12,
|
| - 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00,
|
| - 0x00, 0x00, 0x00, 0x00,
|
| -};
|
| -
|
| -TEST_F(DnsTransactionTest, SuffixSearchStop) {
|
| - config_.ndots = 2;
|
| - config_.search.push_back("a");
|
| - config_.search.push_back("b");
|
| - config_.search.push_back("c");
|
| - ConfigureFactory();
|
| -
|
| - AddAsyncQueryAndRcode("x.y.z", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndRcode("x.y.z.a", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddAsyncQueryAndResponse(0 /* id */, "x.y.z.b", dns_protocol::kTypeA,
|
| - kResponseNoData, arraysize(kResponseNoData));
|
| -
|
| - TransactionHelper helper0("x.y.z", dns_protocol::kTypeA, 0 /* answers */);
|
| -
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, SyncFirstQuery) {
|
| - config_.search.push_back("lab.ccs.neu.edu");
|
| - config_.search.push_back("ccs.neu.edu");
|
| - ConfigureFactory();
|
| -
|
| - AddSyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, SyncFirstQueryWithSearch) {
|
| - config_.search.push_back("lab.ccs.neu.edu");
|
| - config_.search.push_back("ccs.neu.edu");
|
| - ConfigureFactory();
|
| -
|
| - AddSyncQueryAndRcode("www.lab.ccs.neu.edu", kT2Qtype,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - // "www.ccs.neu.edu"
|
| - AddAsyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype,
|
| - kT2ResponseDatagram, arraysize(kT2ResponseDatagram));
|
| -
|
| - TransactionHelper helper0("www", kT2Qtype, kT2RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, SyncSearchQuery) {
|
| - config_.search.push_back("lab.ccs.neu.edu");
|
| - config_.search.push_back("ccs.neu.edu");
|
| - ConfigureFactory();
|
| -
|
| - AddAsyncQueryAndRcode("www.lab.ccs.neu.edu", dns_protocol::kTypeA,
|
| - dns_protocol::kRcodeNXDOMAIN);
|
| - AddSyncQueryAndResponse(2 /* id */, kT2HostName, kT2Qtype,
|
| - kT2ResponseDatagram, arraysize(kT2ResponseDatagram));
|
| -
|
| - TransactionHelper helper0("www", kT2Qtype, kT2RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, ConnectFailure) {
|
| - socket_factory_->fail_next_socket_ = true;
|
| - transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt.
|
| - TransactionHelper helper0("www.chromium.org", dns_protocol::kTypeA,
|
| - ERR_CONNECTION_REFUSED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, ConnectFailureFollowedBySuccess) {
|
| - // Retry after server failure.
|
| - config_.attempts = 2;
|
| - ConfigureFactory();
|
| - // First server connection attempt fails.
|
| - transaction_ids_.push_back(0); // Needed to make a DnsUDPAttempt.
|
| - socket_factory_->fail_next_socket_ = true;
|
| - // Second DNS query succeeds.
|
| - AddAsyncQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram));
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPLookup) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - AddQueryAndResponse(0 /* id */, kT0HostName, kT0Qtype,
|
| - kT0ResponseDatagram, arraysize(kT0ResponseDatagram),
|
| - ASYNC, true /* use_tcp */);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, kT0RecordCount);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPFailure) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - AddQueryAndRcode(kT0HostName, kT0Qtype, dns_protocol::kRcodeSERVFAIL,
|
| - ASYNC, true /* use_tcp */);
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_SERVER_FAILED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPMalformed) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
|
| - // Valid response but length too short.
|
| - // This must be truncated in the question section. The DnsResponse doesn't
|
| - // examine the answer section until asked to parse it, so truncating it in
|
| - // the answer section would result in the DnsTransaction itself succeeding.
|
| - data->AddResponseWithLength(
|
| - make_scoped_ptr(
|
| - new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
|
| - arraysize(kT0ResponseDatagram), 0)),
|
| - ASYNC,
|
| - static_cast<uint16>(kT0QuerySize - 1));
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_MALFORMED_RESPONSE);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPTimeout) {
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - AddSocketData(make_scoped_ptr(
|
| - new DnsSocketData(1 /* id */, kT0HostName, kT0Qtype, ASYNC, true)));
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_DNS_TIMED_OUT);
|
| - EXPECT_TRUE(helper0.RunUntilDone(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPReadReturnsZeroAsync) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
|
| - // Return all but the last byte of the response.
|
| - data->AddResponseWithLength(
|
| - make_scoped_ptr(
|
| - new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
|
| - arraysize(kT0ResponseDatagram) - 1, 0)),
|
| - ASYNC,
|
| - static_cast<uint16>(arraysize(kT0ResponseDatagram)));
|
| - // Then return a 0-length read.
|
| - data->AddReadError(0, ASYNC);
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPReadReturnsZeroSynchronous) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
|
| - // Return all but the last byte of the response.
|
| - data->AddResponseWithLength(
|
| - make_scoped_ptr(
|
| - new DnsResponse(reinterpret_cast<const char*>(kT0ResponseDatagram),
|
| - arraysize(kT0ResponseDatagram) - 1, 0)),
|
| - SYNCHRONOUS,
|
| - static_cast<uint16>(arraysize(kT0ResponseDatagram)));
|
| - // Then return a 0-length read.
|
| - data->AddReadError(0, SYNCHRONOUS);
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPConnectionClosedAsync) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
|
| - data->AddReadError(ERR_CONNECTION_CLOSED, ASYNC);
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, TCPConnectionClosedSynchronous) {
|
| - AddAsyncQueryAndRcode(kT0HostName, kT0Qtype,
|
| - dns_protocol::kRcodeNOERROR | dns_protocol::kFlagTC);
|
| - scoped_ptr<DnsSocketData> data(
|
| - new DnsSocketData(0 /* id */, kT0HostName, kT0Qtype, ASYNC, true));
|
| - data->AddReadError(ERR_CONNECTION_CLOSED, SYNCHRONOUS);
|
| - AddSocketData(data.Pass());
|
| -
|
| - TransactionHelper helper0(kT0HostName, kT0Qtype, ERR_CONNECTION_CLOSED);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -TEST_F(DnsTransactionTest, InvalidQuery) {
|
| - config_.timeout = TestTimeouts::tiny_timeout();
|
| - ConfigureFactory();
|
| -
|
| - TransactionHelper helper0(".", dns_protocol::kTypeA, ERR_INVALID_ARGUMENT);
|
| - EXPECT_TRUE(helper0.Run(transaction_factory_.get()));
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -} // namespace net
|
|
|