Index: components/certificate_transparency/mock_log_dns_traffic.cc |
diff --git a/components/certificate_transparency/mock_log_dns_traffic.cc b/components/certificate_transparency/mock_log_dns_traffic.cc |
index 22599950dd70a1df0a034adf0d6e230f73dd162b..7a616592caf4b01ebaeced556e79bb4e8c9d352f 100644 |
--- a/components/certificate_transparency/mock_log_dns_traffic.cc |
+++ b/components/certificate_transparency/mock_log_dns_traffic.cc |
@@ -21,10 +21,14 @@ |
namespace certificate_transparency { |
namespace { |
+// This is used for the last mock socket response as a sentinel to prevent |
+// trying to read more data than expected. |
+const net::MockRead kNoMoreData(net::SYNCHRONOUS, net::ERR_UNEXPECTED, 2); |
+ |
// Necessary to expose SetDnsConfig for testing. |
class DnsChangeNotifier : public net::NetworkChangeNotifier { |
public: |
static void SetInitialDnsConfig(const net::DnsConfig& config) { |
net::NetworkChangeNotifier::SetInitialDnsConfig(config); |
@@ -41,11 +45,11 @@ int FakeRandInt(int min, int max) { |
return min; |
} |
std::vector<char> CreateDnsTxtRequest(base::StringPiece qname) { |
std::string encoded_qname; |
- EXPECT_TRUE(net::DNSDomainFromDot(qname, &encoded_qname)); |
+ CHECK(net::DNSDomainFromDot(qname, &encoded_qname)); |
// DNS query section: |
// N bytes - qname |
// 2 bytes - record type |
// 2 bytes - record class |
@@ -58,16 +62,16 @@ std::vector<char> CreateDnsTxtRequest(base::StringPiece qname) { |
// Header |
net::dns_protocol::Header header = {}; |
header.flags = base::HostToNet16(net::dns_protocol::kFlagRD); |
header.qdcount = base::HostToNet16(1); |
- EXPECT_TRUE(writer.WriteBytes(&header, sizeof(header))); |
+ CHECK(writer.WriteBytes(&header, sizeof(header))); |
// Query section |
- EXPECT_TRUE(writer.WriteBytes(encoded_qname.data(), encoded_qname.size())); |
- EXPECT_TRUE(writer.WriteU16(net::dns_protocol::kTypeTXT)); |
- EXPECT_TRUE(writer.WriteU16(net::dns_protocol::kClassIN)); |
- EXPECT_EQ(0, writer.remaining()); |
+ CHECK(writer.WriteBytes(encoded_qname.data(), encoded_qname.size())); |
+ CHECK(writer.WriteU16(net::dns_protocol::kTypeTXT)); |
+ CHECK(writer.WriteU16(net::dns_protocol::kClassIN)); |
+ CHECK_EQ(0, writer.remaining()); |
return request; |
} |
std::vector<char> CreateDnsTxtResponse(const std::vector<char>& request, |
@@ -92,19 +96,19 @@ std::vector<char> CreateDnsTxtResponse(const std::vector<char>& request, |
header->flags |= base::HostToNet16(net::dns_protocol::kFlagResponse); |
// Write the answer section |
base::BigEndianWriter writer(response.data() + request.size(), |
response.size() - request.size()); |
- EXPECT_TRUE(writer.WriteU8(0xc0)); // qname is a pointer |
- EXPECT_TRUE(writer.WriteU8( |
+ CHECK(writer.WriteU8(0xc0)); // qname is a pointer |
+ CHECK(writer.WriteU8( |
sizeof(*header))); // address of qname (start of query section) |
- EXPECT_TRUE(writer.WriteU16(net::dns_protocol::kTypeTXT)); |
- EXPECT_TRUE(writer.WriteU16(net::dns_protocol::kClassIN)); |
- EXPECT_TRUE(writer.WriteU32(ttl)); |
- EXPECT_TRUE(writer.WriteU16(answer.size())); |
- EXPECT_TRUE(writer.WriteBytes(answer.data(), answer.size())); |
- EXPECT_EQ(0, writer.remaining()); |
+ CHECK(writer.WriteU16(net::dns_protocol::kTypeTXT)); |
+ CHECK(writer.WriteU16(net::dns_protocol::kClassIN)); |
+ CHECK(writer.WriteU32(ttl)); |
+ CHECK(writer.WriteU16(answer.size())); |
+ CHECK(writer.WriteBytes(answer.data(), answer.size())); |
+ CHECK_EQ(0, writer.remaining()); |
return response; |
} |
std::vector<char> CreateDnsErrorResponse(const std::vector<char>& request, |
@@ -119,60 +123,85 @@ std::vector<char> CreateDnsErrorResponse(const std::vector<char>& request, |
return response; |
} |
} // namespace |
-namespace internal { |
- |
-MockSocketData::MockSocketData(const std::vector<char>& write, |
- const std::vector<char>& read) |
- : expected_write_payload_(write), |
- expected_read_payload_(read), |
- expected_write_(net::SYNCHRONOUS, |
- expected_write_payload_.data(), |
- expected_write_payload_.size(), |
- 0), |
- expected_reads_{net::MockRead(net::ASYNC, |
- expected_read_payload_.data(), |
- expected_read_payload_.size(), |
- 1), |
- no_more_data_}, |
- socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
- |
-MockSocketData::MockSocketData(const std::vector<char>& write, int net_error) |
- : expected_write_payload_(write), |
- expected_write_(net::SYNCHRONOUS, |
- expected_write_payload_.data(), |
- expected_write_payload_.size(), |
- 0), |
- expected_reads_{net::MockRead(net::ASYNC, net_error, 1), no_more_data_}, |
- socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
- |
-MockSocketData::MockSocketData(const std::vector<char>& write) |
- : expected_write_payload_(write), |
- expected_write_(net::SYNCHRONOUS, |
- expected_write_payload_.data(), |
- expected_write_payload_.size(), |
- 0), |
- expected_reads_{net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING, 1), |
- no_more_data_}, |
- socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
- |
-MockSocketData::~MockSocketData() {} |
- |
-void MockSocketData::AddToFactory( |
- net::MockClientSocketFactory* socket_factory) { |
- socket_factory->AddSocketDataProvider(&socket_data_); |
-} |
- |
-const net::MockRead MockSocketData::no_more_data_(net::SYNCHRONOUS, |
- net::ERR_IO_PENDING, |
- 2); |
- |
-} // namespace internal |
- |
-using internal::MockSocketData; |
+// A container for all of the data needed for simulating a socket. |
+// This is useful because Mock{Read,Write}, SequencedSocketData and |
+// MockClientSocketFactory all do not take ownership of or copy their arguments, |
+// so it is necessary to manage the lifetime of those arguments. Wrapping all |
+// of that up in a single class simplifies this. |
+class MockLogDnsTraffic::MockSocketData { |
+ public: |
+ // A socket that expects one write and one read operation. |
+ MockSocketData(const std::vector<char>& write, const std::vector<char>& read) |
+ : expected_write_payload_(write), |
+ expected_read_payload_(read), |
+ expected_write_(net::SYNCHRONOUS, |
+ expected_write_payload_.data(), |
+ expected_write_payload_.size(), |
+ 0), |
+ expected_reads_{net::MockRead(net::ASYNC, |
+ expected_read_payload_.data(), |
+ expected_read_payload_.size(), |
+ 1), |
+ kNoMoreData}, |
+ socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
+ |
+ // A socket that expects one write and a read error. |
+ MockSocketData(const std::vector<char>& write, net::Error error) |
+ : expected_write_payload_(write), |
+ expected_write_(net::SYNCHRONOUS, |
+ expected_write_payload_.data(), |
+ expected_write_payload_.size(), |
+ 0), |
+ expected_reads_{net::MockRead(net::ASYNC, error, 1), kNoMoreData}, |
+ socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
+ |
+ // A socket that expects one write and no response. |
+ explicit MockSocketData(const std::vector<char>& write) |
+ : expected_write_payload_(write), |
+ expected_write_(net::SYNCHRONOUS, |
+ expected_write_payload_.data(), |
+ expected_write_payload_.size(), |
+ 0), |
+ expected_reads_{net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING, 1), |
+ kNoMoreData}, |
+ socket_data_(expected_reads_, 2, &expected_write_, 1) {} |
+ |
+ ~MockSocketData() {} |
+ |
+ void SetWriteMode(net::IoMode mode) { expected_write_.mode = mode; } |
+ void SetReadMode(net::IoMode mode) { expected_reads_[0].mode = mode; } |
+ |
+ void AddToFactory(net::MockClientSocketFactory* socket_factory) { |
+ socket_factory->AddSocketDataProvider(&socket_data_); |
+ } |
+ |
+ private: |
+ // This class only supports one write and one read, so just need to store one |
+ // payload each. |
+ const std::vector<char> expected_write_payload_; |
+ const std::vector<char> expected_read_payload_; |
+ |
+ // Encapsulates the data that is expected to be written to a socket. |
+ net::MockWrite expected_write_; |
+ |
+ // Encapsulates the data/error that should be returned when reading from a |
+ // socket. The second "expected" read is a sentinel that causes socket reads |
+ // beyond the first to hang until they timeout. This results in better |
+ // test failure messages (rather than a CHECK-fail due to a socket read |
+ // overrunning the MockRead array) and behaviour more like a real socket when |
+ // an unexpected second socket read occurs. |
+ net::MockRead expected_reads_[2]; |
+ |
+ // Holds pointers to |expected_write_| and |expected_reads_|. This is what is |
+ // added to net::MockClientSocketFactory to prepare a mock socket. |
+ net::SequencedSocketData socket_data_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MockSocketData); |
+}; |
MockLogDnsTraffic::MockLogDnsTraffic() : socket_read_mode_(net::ASYNC) {} |
MockLogDnsTraffic::~MockLogDnsTraffic() {} |
@@ -182,12 +211,12 @@ void MockLogDnsTraffic::ExpectRequestAndErrorResponse(base::StringPiece qname, |
EmplaceMockSocketData(CreateDnsTxtRequest(qname), |
CreateDnsErrorResponse(request, rcode)); |
} |
void MockLogDnsTraffic::ExpectRequestAndSocketError(base::StringPiece qname, |
- int net_error) { |
- EmplaceMockSocketData(CreateDnsTxtRequest(qname), net_error); |
+ net::Error error) { |
+ EmplaceMockSocketData(CreateDnsTxtRequest(qname), error); |
} |
void MockLogDnsTraffic::ExpectRequestAndTimeout(base::StringPiece qname) { |
EmplaceMockSocketData(CreateDnsTxtRequest(qname)); |