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

Side by Side Diff: components/certificate_transparency/log_dns_client_unittest.cc

Issue 2369373002: LogDnsClient now returns some errors synchronously (Closed)
Patch Set: Emulate HostResolver more closely Created 4 years, 2 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/certificate_transparency/log_dns_client.h" 5 #include "components/certificate_transparency/log_dns_client.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <numeric> 8 #include <numeric>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h" 16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/test/test_timeouts.h"
19 #include "components/certificate_transparency/mock_log_dns_traffic.h" 20 #include "components/certificate_transparency/mock_log_dns_traffic.h"
20 #include "crypto/sha2.h" 21 #include "crypto/sha2.h"
21 #include "net/base/net_errors.h" 22 #include "net/base/net_errors.h"
22 #include "net/cert/merkle_audit_proof.h" 23 #include "net/cert/merkle_audit_proof.h"
23 #include "net/cert/signed_certificate_timestamp.h" 24 #include "net/cert/signed_certificate_timestamp.h"
24 #include "net/dns/dns_client.h" 25 #include "net/dns/dns_client.h"
25 #include "net/dns/dns_config_service.h" 26 #include "net/dns/dns_config_service.h"
26 #include "net/dns/dns_protocol.h" 27 #include "net/dns/dns_protocol.h"
28 #include "net/log/net_log.h"
27 #include "net/test/gtest_util.h" 29 #include "net/test/gtest_util.h"
28 #include "testing/gmock/include/gmock/gmock.h" 30 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
30 32
31 namespace certificate_transparency { 33 namespace certificate_transparency {
32 namespace { 34 namespace {
33 35
34 using ::testing::AllOf; 36 using ::testing::AllOf;
35 using ::testing::Eq; 37 using ::testing::Eq;
36 using ::testing::IsEmpty; 38 using ::testing::IsEmpty;
(...skipping 26 matching lines...) Expand all
63 const uint64_t kLeafIndices[] = {0, 1, 2}; 65 const uint64_t kLeafIndices[] = {0, 1, 2};
64 const uint64_t kTreeSizes[] = {100, 10000, 1000000}; 66 const uint64_t kTreeSizes[] = {100, 10000, 1000000};
65 67
66 // Only 7 audit proof nodes can fit into a DNS response, because they are sent 68 // Only 7 audit proof nodes can fit into a DNS response, because they are sent
67 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node 69 // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node
68 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7. 70 // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7.
69 // This means audit proofs consisting of more than 7 nodes require multiple DNS 71 // This means audit proofs consisting of more than 7 nodes require multiple DNS
70 // requests to retrieve. 72 // requests to retrieve.
71 const size_t kMaxProofNodesPerDnsResponse = 7; 73 const size_t kMaxProofNodesPerDnsResponse = 7;
72 74
75 // Returns an example Merkle audit proof containing |length| nodes.
76 // The proof cannot be used for cryptographic purposes; it is merely a
77 // placeholder.
73 std::vector<std::string> GetSampleAuditProof(size_t length) { 78 std::vector<std::string> GetSampleAuditProof(size_t length) {
74 std::vector<std::string> audit_proof(length); 79 std::vector<std::string> audit_proof(length);
75 // Makes each node of the audit proof different, so that tests are able to 80 // Makes each node of the audit proof different, so that tests are able to
76 // confirm that the audit proof is reconstructed in the correct order. 81 // confirm that the audit proof is reconstructed in the correct order.
77 for (size_t i = 0; i < length; ++i) { 82 for (size_t i = 0; i < length; ++i) {
78 std::string node(crypto::kSHA256Length, '\0'); 83 std::string node(crypto::kSHA256Length, '\0');
79 // Each node is 32 bytes, with each byte having a different value. 84 // Each node is 32 bytes, with each byte having a different value.
80 for (size_t j = 0; j < crypto::kSHA256Length; ++j) { 85 for (size_t j = 0; j < crypto::kSHA256Length; ++j) {
81 node[j] = static_cast<char>((-127 + i + j) % 128); 86 node[j] = static_cast<char>((-127 + i + j) % 128);
82 } 87 }
83 audit_proof[i].assign(std::move(node)); 88 audit_proof[i].assign(std::move(node));
84 } 89 }
85 90
86 return audit_proof; 91 return audit_proof;
87 } 92 }
88 93
89 class MockAuditProofCallback {
90 public:
91 MockAuditProofCallback() : called_(false) {}
92
93 bool called() const { return called_; }
94 int net_error() const { return net_error_; }
95 const net::ct::MerkleAuditProof* proof() const { return proof_.get(); }
96
97 void Run(int net_error, std::unique_ptr<net::ct::MerkleAuditProof> proof) {
98 EXPECT_FALSE(called_);
99 called_ = true;
100 net_error_ = net_error;
101 proof_ = std::move(proof);
102 run_loop_.Quit();
103 }
104
105 LogDnsClient::AuditProofCallback AsCallback() {
106 return base::Bind(&MockAuditProofCallback::Run, base::Unretained(this));
107 }
108
109 void WaitUntilRun() { run_loop_.Run(); }
110
111 private:
112 bool called_;
113 int net_error_;
114 std::unique_ptr<net::ct::MerkleAuditProof> proof_;
115 base::RunLoop run_loop_;
116 };
117
118 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { 94 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
119 protected: 95 protected:
120 LogDnsClientTest() 96 LogDnsClientTest()
121 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) { 97 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
122 mock_dns_.SetSocketReadMode(GetParam()); 98 mock_dns_.SetSocketReadMode(GetParam());
123 mock_dns_.InitializeDnsConfig(); 99 mock_dns_.InitializeDnsConfig();
124 } 100 }
125 101
126 std::unique_ptr<LogDnsClient> CreateLogDnsClient( 102 std::unique_ptr<LogDnsClient> CreateLogDnsClient(
127 size_t max_concurrent_queries) { 103 size_t max_concurrent_queries) {
128 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(), 104 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(),
129 net::NetLogWithSource(), 105 net::NetLogWithSource(),
130 max_concurrent_queries); 106 max_concurrent_queries);
131 } 107 }
132 108
133 void QueryAuditProofAsync(LogDnsClient* log_client, 109 // Convenience function for calling QueryAuditProof synchronously.
134 const std::string& log_domain, 110 template <typename... Types>
Eran Messeri 2016/10/14 11:05:13 According to https://chromium-cpp.appspot.com/, us
Rob Percival 2016/10/20 10:49:07 That's correct. This is mostly just forwarding to
135 const char leaf_hash[crypto::kSHA256Length], 111 net::Error QueryAuditProof(Types... args) {
136 uint64_t tree_size, 112 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
137 const LogDnsClient::AuditProofCallback& callback) { 113 net::TestCompletionCallback callback;
138 log_client->QueryAuditProof(log_domain, leaf_hash, tree_size, callback); 114 const net::Error result = log_client->QueryAuditProof(
139 } 115 std::forward<Types>(args)..., callback.callback());
140 116
141 // Convenience function for calling QueryAuditProofAsync synchronously. 117 return result != net::ERR_IO_PENDING
142 void QueryAuditProof(const std::string& log_domain, 118 ? result
143 const char leaf_hash[crypto::kSHA256Length], 119 : static_cast<net::Error>(callback.WaitForResult());
144 uint64_t tree_size,
145 MockAuditProofCallback* callback) {
146 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
147 QueryAuditProofAsync(log_client.get(), log_domain, leaf_hash, tree_size,
148 callback->AsCallback());
149 callback->WaitUntilRun();
150 } 120 }
151 121
152 // This will be the NetworkChangeNotifier singleton for the duration of the 122 // This will be the NetworkChangeNotifier singleton for the duration of the
153 // test. It is accessed statically by LogDnsClient. 123 // test. It is accessed statically by LogDnsClient.
154 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; 124 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
155 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient, 125 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient,
156 // the underlying net::DnsClient, and NetworkChangeNotifier. 126 // the underlying net::DnsClient, and NetworkChangeNotifier.
157 base::MessageLoopForIO message_loop_; 127 base::MessageLoopForIO message_loop_;
158 // Allows mock DNS sockets to be setup. 128 // Allows mock DNS sockets to be setup.
159 MockLogDnsTraffic mock_dns_; 129 MockLogDnsTraffic mock_dns_;
160 }; 130 };
161 131
162 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { 132 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
163 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 133 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
164 net::dns_protocol::kRcodeNXDOMAIN); 134 net::dns_protocol::kRcodeNXDOMAIN);
165 135
166 MockAuditProofCallback callback; 136 net::ct::MerkleAuditProof proof;
167 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 137 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
168 ASSERT_TRUE(callback.called()); 138 IsError(net::ERR_NAME_NOT_RESOLVED));
169 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
170 EXPECT_THAT(callback.proof(), IsNull());
171 } 139 }
172 140
173 TEST_P(LogDnsClientTest, 141 TEST_P(LogDnsClientTest,
174 QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) { 142 QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) {
175 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 143 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
176 net::dns_protocol::kRcodeSERVFAIL); 144 net::dns_protocol::kRcodeSERVFAIL);
177 145
178 MockAuditProofCallback callback; 146 net::ct::MerkleAuditProof proof;
179 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 147 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
180 ASSERT_TRUE(callback.called()); 148 IsError(net::ERR_DNS_SERVER_FAILED));
181 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
182 EXPECT_THAT(callback.proof(), IsNull());
183 } 149 }
184 150
185 TEST_P(LogDnsClientTest, 151 TEST_P(LogDnsClientTest,
186 QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) { 152 QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) {
187 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], 153 mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
188 net::dns_protocol::kRcodeREFUSED); 154 net::dns_protocol::kRcodeREFUSED);
189 155
190 MockAuditProofCallback callback; 156 net::ct::MerkleAuditProof proof;
191 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 157 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
192 ASSERT_TRUE(callback.called()); 158 IsError(net::ERR_DNS_SERVER_FAILED));
193 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
194 EXPECT_THAT(callback.proof(), IsNull());
195 } 159 }
196 160
197 TEST_P(LogDnsClientTest, 161 TEST_P(
198 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrin gs) { 162 LogDnsClientTest,
163 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrings) {
199 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], 164 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0],
200 std::vector<base::StringPiece>()); 165 std::vector<base::StringPiece>());
201 166
202 MockAuditProofCallback callback; 167 net::ct::MerkleAuditProof proof;
203 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 168 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
204 ASSERT_TRUE(callback.called()); 169 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
205 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
206 EXPECT_THAT(callback.proof(), IsNull());
207 } 170 }
208 171
209 TEST_P(LogDnsClientTest, 172 TEST_P(
210 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreTha nOneString) { 173 LogDnsClientTest,
174 QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreThanOn eString) {
211 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"}); 175 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"});
212 176
213 MockAuditProofCallback callback; 177 net::ct::MerkleAuditProof proof;
214 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 178 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
215 ASSERT_TRUE(callback.called()); 179 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
216 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
217 EXPECT_THAT(callback.proof(), IsNull());
218 } 180 }
219 181
220 TEST_P(LogDnsClientTest, 182 TEST_P(LogDnsClientTest,
221 QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) { 183 QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) {
222 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"}); 184 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"});
223 185
224 MockAuditProofCallback callback; 186 net::ct::MerkleAuditProof proof;
225 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 187 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
226 ASSERT_TRUE(callback.called()); 188 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
227 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
228 EXPECT_THAT(callback.proof(), IsNull());
229 } 189 }
230 190
231 TEST_P(LogDnsClientTest, 191 TEST_P(LogDnsClientTest,
232 QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) { 192 QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) {
233 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"}); 193 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"});
234 194
235 MockAuditProofCallback callback; 195 net::ct::MerkleAuditProof proof;
236 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 196 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
237 ASSERT_TRUE(callback.called()); 197 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
238 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
239 EXPECT_THAT(callback.proof(), IsNull());
240 } 198 }
241 199
242 TEST_P(LogDnsClientTest, 200 TEST_P(LogDnsClientTest,
243 QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) { 201 QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) {
244 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""}); 202 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""});
245 203
246 MockAuditProofCallback callback; 204 net::ct::MerkleAuditProof proof;
247 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 205 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
248 ASSERT_TRUE(callback.called()); 206 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
249 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
250 EXPECT_THAT(callback.proof(), IsNull());
251 } 207 }
252 208
253 TEST_P(LogDnsClientTest, 209 TEST_P(LogDnsClientTest,
254 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { 210 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) {
255 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"}); 211 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"});
256 212
257 MockAuditProofCallback callback; 213 net::ct::MerkleAuditProof proof;
258 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 214 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
259 ASSERT_TRUE(callback.called()); 215 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
260 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
261 EXPECT_THAT(callback.proof(), IsNull());
262 } 216 }
263 217
264 TEST_P(LogDnsClientTest, 218 TEST_P(LogDnsClientTest,
265 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { 219 QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) {
266 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"}); 220 mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"});
267 221
268 MockAuditProofCallback callback; 222 net::ct::MerkleAuditProof proof;
269 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 223 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
270 ASSERT_TRUE(callback.called()); 224 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
271 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
272 EXPECT_THAT(callback.proof(), IsNull());
273 } 225 }
274 226
275 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) { 227 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
276 MockAuditProofCallback callback; 228 net::ct::MerkleAuditProof proof;
277 QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &callback); 229 ASSERT_THAT(QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &proof),
278 ASSERT_TRUE(callback.called()); 230 IsError(net::ERR_INVALID_ARGUMENT));
279 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
280 EXPECT_THAT(callback.proof(), IsNull());
281 } 231 }
282 232
283 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) { 233 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) {
284 MockAuditProofCallback callback; 234 net::ct::MerkleAuditProof proof;
285 QueryAuditProof("ct.test", "foo", kTreeSizes[0], &callback); 235 ASSERT_THAT(QueryAuditProof("ct.test", "foo", kTreeSizes[0], &proof),
286 ASSERT_TRUE(callback.called()); 236 IsError(net::ERR_INVALID_ARGUMENT));
287 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
288 EXPECT_THAT(callback.proof(), IsNull());
289 } 237 }
290 238
291 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) { 239 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) {
292 MockAuditProofCallback callback; 240 net::ct::MerkleAuditProof proof;
293 QueryAuditProof("ct.test", "", kTreeSizes[0], &callback); 241 ASSERT_THAT(QueryAuditProof("ct.test", "", kTreeSizes[0], &proof),
294 ASSERT_TRUE(callback.called()); 242 IsError(net::ERR_INVALID_ARGUMENT));
295 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
296 EXPECT_THAT(callback.proof(), IsNull());
297 } 243 }
298 244
299 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsNull) { 245 TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsNull) {
300 MockAuditProofCallback callback; 246 net::ct::MerkleAuditProof proof;
301 QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &callback); 247 ASSERT_THAT(QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &proof),
302 ASSERT_TRUE(callback.called()); 248 IsError(net::ERR_INVALID_ARGUMENT));
303 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
304 EXPECT_THAT(callback.proof(), IsNull());
305 } 249 }
306 250
307 TEST_P(LogDnsClientTest, 251 TEST_P(LogDnsClientTest,
308 QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) { 252 QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) {
309 mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0], 253 mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0],
310 net::ERR_CONNECTION_REFUSED); 254 net::ERR_CONNECTION_REFUSED);
311 255
312 MockAuditProofCallback callback; 256 net::ct::MerkleAuditProof proof;
313 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 257 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
314 ASSERT_TRUE(callback.called()); 258 IsError(net::ERR_CONNECTION_REFUSED));
315 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
316 EXPECT_THAT(callback.proof(), IsNull());
317 } 259 }
318 260
319 TEST_P(LogDnsClientTest, 261 TEST_P(LogDnsClientTest,
320 QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) { 262 QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) {
321 mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]); 263 mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]);
322 264
323 MockAuditProofCallback callback; 265 net::ct::MerkleAuditProof proof;
324 QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); 266 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &proof),
325 ASSERT_TRUE(callback.called()); 267 IsError(net::ERR_DNS_TIMED_OUT));
326 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
327 EXPECT_THAT(callback.proof(), IsNull());
328 } 268 }
329 269
330 TEST_P(LogDnsClientTest, QueryAuditProof) { 270 TEST_P(LogDnsClientTest, QueryAuditProof) {
331 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 271 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
332 272
333 // Expect a leaf index query first, to map the leaf hash to a leaf index. 273 // Expect a leaf index query first, to map the leaf hash to a leaf index.
334 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 274 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
335 275
336 // It takes a number of DNS requests to retrieve the entire |audit_proof| 276 // It takes a number of DNS requests to retrieve the entire |audit_proof|
337 // (see |kMaxProofNodesPerDnsResponse|). 277 // (see |kMaxProofNodesPerDnsResponse|).
338 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size(); 278 for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
339 nodes_begin += kMaxProofNodesPerDnsResponse) { 279 nodes_begin += kMaxProofNodesPerDnsResponse) {
340 const size_t nodes_end = std::min( 280 const size_t nodes_end = std::min(
341 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size()); 281 nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
342 282
343 mock_dns_.ExpectAuditProofRequestAndResponse( 283 mock_dns_.ExpectAuditProofRequestAndResponse(
344 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), 284 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
345 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end); 285 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
346 } 286 }
347 287
348 MockAuditProofCallback callback; 288 net::ct::MerkleAuditProof proof;
349 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 289 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
350 ASSERT_TRUE(callback.called()); 290 IsOk());
351 EXPECT_THAT(callback.net_error(), IsOk()); 291 EXPECT_THAT(proof.leaf_index, Eq(123456u));
352 ASSERT_THAT(callback.proof(), NotNull());
353 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
354 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 292 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
355 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 293 // EXPECT_THAT(proof.tree_size, Eq(999999));
356 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 294 EXPECT_THAT(proof.nodes, Eq(audit_proof));
357 } 295 }
358 296
359 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) { 297 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
360 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 298 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
361 299
362 // Expect a leaf index query first, to map the leaf hash to a leaf index. 300 // Expect a leaf index query first, to map the leaf hash to a leaf index.
363 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 301 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
364 302
365 // Make some of the responses contain fewer proof nodes than they can hold. 303 // Make some of the responses contain fewer proof nodes than they can hold.
366 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", 304 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
367 audit_proof.begin(), 305 audit_proof.begin(),
368 audit_proof.begin() + 1); 306 audit_proof.begin() + 1);
369 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.", 307 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.",
370 audit_proof.begin() + 1, 308 audit_proof.begin() + 1,
371 audit_proof.begin() + 3); 309 audit_proof.begin() + 3);
372 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.", 310 mock_dns_.ExpectAuditProofRequestAndResponse("3.123456.999999.tree.ct.test.",
373 audit_proof.begin() + 3, 311 audit_proof.begin() + 3,
374 audit_proof.begin() + 6); 312 audit_proof.begin() + 6);
375 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.", 313 mock_dns_.ExpectAuditProofRequestAndResponse("6.123456.999999.tree.ct.test.",
376 audit_proof.begin() + 6, 314 audit_proof.begin() + 6,
377 audit_proof.begin() + 10); 315 audit_proof.begin() + 10);
378 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.", 316 mock_dns_.ExpectAuditProofRequestAndResponse("10.123456.999999.tree.ct.test.",
379 audit_proof.begin() + 10, 317 audit_proof.begin() + 10,
380 audit_proof.begin() + 13); 318 audit_proof.begin() + 13);
381 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.", 319 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.",
382 audit_proof.begin() + 13, 320 audit_proof.begin() + 13,
383 audit_proof.end()); 321 audit_proof.end());
384 322
385 MockAuditProofCallback callback; 323 net::ct::MerkleAuditProof proof;
386 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 324 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
387 ASSERT_TRUE(callback.called()); 325 IsOk());
388 EXPECT_THAT(callback.net_error(), IsOk()); 326 EXPECT_THAT(proof.leaf_index, Eq(123456u));
389 ASSERT_THAT(callback.proof(), NotNull());
390 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
391 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 327 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
392 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); 328 // EXPECT_THAT(proof.tree_size, Eq(999999));
393 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); 329 EXPECT_THAT(proof.nodes, Eq(audit_proof));
394 } 330 }
395 331
396 TEST_P(LogDnsClientTest, 332 TEST_P(LogDnsClientTest,
397 QueryAuditProofReportsThatAuditProofQnameDoesNotExist) { 333 QueryAuditProofReportsThatAuditProofQnameDoesNotExist) {
398 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 334 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
399 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 335 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
400 net::dns_protocol::kRcodeNXDOMAIN); 336 net::dns_protocol::kRcodeNXDOMAIN);
401 337
402 MockAuditProofCallback callback; 338 net::ct::MerkleAuditProof proof;
403 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 339 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
404 ASSERT_TRUE(callback.called()); 340 IsError(net::ERR_NAME_NOT_RESOLVED));
405 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
406 EXPECT_THAT(callback.proof(), IsNull());
407 } 341 }
408 342
409 TEST_P(LogDnsClientTest, 343 TEST_P(LogDnsClientTest,
410 QueryAuditProofReportsServerFailureDuringAuditProofRequests) { 344 QueryAuditProofReportsServerFailuresDuringAuditProofRequests) {
411 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 345 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
412 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 346 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
413 net::dns_protocol::kRcodeSERVFAIL); 347 net::dns_protocol::kRcodeSERVFAIL);
414 348
415 MockAuditProofCallback callback; 349 net::ct::MerkleAuditProof proof;
416 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 350 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
417 ASSERT_TRUE(callback.called()); 351 IsError(net::ERR_DNS_SERVER_FAILED));
418 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
419 EXPECT_THAT(callback.proof(), IsNull());
420 } 352 }
421 353
422 TEST_P(LogDnsClientTest, 354 TEST_P(LogDnsClientTest,
423 QueryAuditProofReportsServerRefusalDuringAuditProofRequests) { 355 QueryAuditProofReportsServerRefusalsDuringAuditProofRequests) {
424 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 356 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
425 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", 357 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
426 net::dns_protocol::kRcodeREFUSED); 358 net::dns_protocol::kRcodeREFUSED);
427 359
428 MockAuditProofCallback callback; 360 net::ct::MerkleAuditProof proof;
429 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 361 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
430 ASSERT_TRUE(callback.called()); 362 IsError(net::ERR_DNS_SERVER_FAILED));
431 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
432 EXPECT_THAT(callback.proof(), IsNull());
433 } 363 }
434 364
435 TEST_P(LogDnsClientTest, 365 TEST_P(
436 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStri ngs) { 366 LogDnsClientTest,
367 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStrings ) {
437 // Expect a leaf index query first, to map the leaf hash to a leaf index. 368 // Expect a leaf index query first, to map the leaf hash to a leaf index.
438 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 369 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
439 370
440 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.", 371 mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.",
441 std::vector<base::StringPiece>()); 372 std::vector<base::StringPiece>());
442 373
443 MockAuditProofCallback callback; 374 net::ct::MerkleAuditProof proof;
444 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 375 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
445 ASSERT_TRUE(callback.called()); 376 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
446 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
447 EXPECT_THAT(callback.proof(), IsNull());
448 } 377 }
449 378
450 TEST_P(LogDnsClientTest, 379 TEST_P(
451 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreTh anOneString) { 380 LogDnsClientTest,
381 QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreThanO neString) {
452 // The CT-over-DNS draft RFC states that the response will contain "exactly 382 // The CT-over-DNS draft RFC states that the response will contain "exactly
453 // one character-string." 383 // one character-string."
454 const std::vector<std::string> audit_proof = GetSampleAuditProof(10); 384 const std::vector<std::string> audit_proof = GetSampleAuditProof(10);
455 385
456 std::string first_chunk_of_proof = std::accumulate( 386 std::string first_chunk_of_proof = std::accumulate(
457 audit_proof.begin(), audit_proof.begin() + 7, std::string()); 387 audit_proof.begin(), audit_proof.begin() + 7, std::string());
458 std::string second_chunk_of_proof = std::accumulate( 388 std::string second_chunk_of_proof = std::accumulate(
459 audit_proof.begin() + 7, audit_proof.end(), std::string()); 389 audit_proof.begin() + 7, audit_proof.end(), std::string());
460 390
461 // Expect a leaf index query first, to map the leaf hash to a leaf index. 391 // Expect a leaf index query first, to map the leaf hash to a leaf index.
462 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 392 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
463 393
464 mock_dns_.ExpectRequestAndResponse( 394 mock_dns_.ExpectRequestAndResponse(
465 "0.123456.999999.tree.ct.test.", 395 "0.123456.999999.tree.ct.test.",
466 {first_chunk_of_proof, second_chunk_of_proof}); 396 {first_chunk_of_proof, second_chunk_of_proof});
467 397
468 MockAuditProofCallback callback; 398 net::ct::MerkleAuditProof proof;
469 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 399 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
470 ASSERT_TRUE(callback.called()); 400 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
471 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
472 EXPECT_THAT(callback.proof(), IsNull());
473 } 401 }
474 402
475 TEST_P(LogDnsClientTest, 403 TEST_P(LogDnsClientTest,
476 QueryAuditProofReportsResponseMalformedIfNodeTooShort) { 404 QueryAuditProofReportsResponseMalformedIfNodeTooShort) {
477 // node is shorter than a SHA-256 hash (31 vs 32 bytes) 405 // node is shorter than a SHA-256 hash (31 vs 32 bytes)
478 const std::vector<std::string> audit_proof(1, std::string(31, 'a')); 406 const std::vector<std::string> audit_proof(1, std::string(31, 'a'));
479 407
480 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 408 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
481 mock_dns_.ExpectAuditProofRequestAndResponse( 409 mock_dns_.ExpectAuditProofRequestAndResponse(
482 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 410 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
483 411
484 MockAuditProofCallback callback; 412 net::ct::MerkleAuditProof proof;
485 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 413 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
486 ASSERT_TRUE(callback.called()); 414 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
487 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
488 EXPECT_THAT(callback.proof(), IsNull());
489 } 415 }
490 416
491 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) { 417 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) {
492 // node is longer than a SHA-256 hash (33 vs 32 bytes) 418 // node is longer than a SHA-256 hash (33 vs 32 bytes)
493 const std::vector<std::string> audit_proof(1, std::string(33, 'a')); 419 const std::vector<std::string> audit_proof(1, std::string(33, 'a'));
494 420
495 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 421 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
496 mock_dns_.ExpectAuditProofRequestAndResponse( 422 mock_dns_.ExpectAuditProofRequestAndResponse(
497 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 423 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
498 424
499 MockAuditProofCallback callback; 425 net::ct::MerkleAuditProof proof;
500 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 426 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
501 ASSERT_TRUE(callback.called()); 427 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
502 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
503 EXPECT_THAT(callback.proof(), IsNull());
504 } 428 }
505 429
506 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) { 430 TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) {
507 const std::vector<std::string> audit_proof; 431 const std::vector<std::string> audit_proof;
508 432
509 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 433 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
510 mock_dns_.ExpectAuditProofRequestAndResponse( 434 mock_dns_.ExpectAuditProofRequestAndResponse(
511 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end()); 435 "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
512 436
513 MockAuditProofCallback callback; 437 net::ct::MerkleAuditProof proof;
514 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 438 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
515 ASSERT_TRUE(callback.called()); 439 IsError(net::ERR_DNS_MALFORMED_RESPONSE));
516 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
517 EXPECT_THAT(callback.proof(), IsNull());
518 } 440 }
519 441
520 TEST_P(LogDnsClientTest, 442 TEST_P(LogDnsClientTest,
521 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) { 443 QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) {
522 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 444 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
523 445
524 MockAuditProofCallback callback; 446 net::ct::MerkleAuditProof proof;
525 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback); 447 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &proof),
526 ASSERT_TRUE(callback.called()); 448 IsError(net::ERR_INVALID_ARGUMENT));
527 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
528 EXPECT_THAT(callback.proof(), IsNull());
529 } 449 }
530 450
531 TEST_P(LogDnsClientTest, 451 TEST_P(LogDnsClientTest,
532 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) { 452 QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) {
533 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999); 453 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999);
534 454
535 MockAuditProofCallback callback; 455 net::ct::MerkleAuditProof proof;
536 QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback); 456 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &proof),
537 ASSERT_TRUE(callback.called()); 457 IsError(net::ERR_INVALID_ARGUMENT));
538 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
539 EXPECT_THAT(callback.proof(), IsNull());
540 } 458 }
541 459
542 TEST_P(LogDnsClientTest, 460 TEST_P(LogDnsClientTest,
543 QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) { 461 QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) {
544 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 462 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
545 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.", 463 mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.",
546 net::ERR_CONNECTION_REFUSED); 464 net::ERR_CONNECTION_REFUSED);
547 465
548 MockAuditProofCallback callback; 466 net::ct::MerkleAuditProof proof;
549 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 467 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
550 ASSERT_TRUE(callback.called()); 468 IsError(net::ERR_CONNECTION_REFUSED));
551 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
552 EXPECT_THAT(callback.proof(), IsNull());
553 } 469 }
554 470
555 TEST_P(LogDnsClientTest, 471 TEST_P(LogDnsClientTest,
556 QueryAuditProofReportsTimeoutsDuringAuditProofRequests) { 472 QueryAuditProofReportsTimeoutsDuringAuditProofRequests) {
557 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456); 473 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
558 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test."); 474 mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test.");
559 475
560 MockAuditProofCallback callback; 476 net::ct::MerkleAuditProof proof;
561 QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); 477 ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &proof),
562 ASSERT_TRUE(callback.called()); 478 IsError(net::ERR_DNS_TIMED_OUT));
563 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
564 EXPECT_THAT(callback.proof(), IsNull());
565 } 479 }
566 480
567 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { 481 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) {
568 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); 482 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
569 net::DnsClient* dns_client = tmp.get(); 483 net::DnsClient* dns_client = tmp.get();
570 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0); 484 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
571 485
572 // Get the current DNS config, modify it and broadcast the update. 486 // Get the current DNS config, modify it and broadcast the update.
573 net::DnsConfig config(*dns_client->GetConfig()); 487 net::DnsConfig config(*dns_client->GetConfig());
574 ASSERT_NE(123, config.attempts); 488 ASSERT_NE(123, config.attempts);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 mock_dns_.ExpectAuditProofRequestAndResponse( 528 mock_dns_.ExpectAuditProofRequestAndResponse(
615 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin), 529 base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
616 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end); 530 audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
617 } 531 }
618 532
619 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); 533 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
620 net::DnsClient* dns_client = tmp.get(); 534 net::DnsClient* dns_client = tmp.get();
621 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0); 535 LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
622 536
623 // Start query. 537 // Start query.
624 MockAuditProofCallback callback; 538 net::ct::MerkleAuditProof proof;
625 QueryAuditProofAsync(&log_client, "ct.test", kLeafHashes[0], 999999, 539 net::TestCompletionCallback callback;
626 callback.AsCallback()); 540 ASSERT_THAT(log_client.QueryAuditProof("ct.test", kLeafHashes[0], 999999,
541 &proof, callback.callback()),
542 IsError(net::ERR_IO_PENDING));
627 543
628 // Get the current DNS config, modify it and broadcast the update. 544 // Get the current DNS config, modify it and publish the update.
545 // The new config is distributed asynchronously via NetworkChangeNotifier.
629 net::DnsConfig config(*dns_client->GetConfig()); 546 net::DnsConfig config(*dns_client->GetConfig());
630 ASSERT_NE(123, config.attempts); 547 ASSERT_NE(123, config.attempts);
631 config.attempts = 123; 548 config.attempts = 123;
632 mock_dns_.SetDnsConfig(config); 549 mock_dns_.SetDnsConfig(config);
550 // The new config is distributed asynchronously via NetworkChangeNotifier.
551 // Config change shouldn't have taken effect yet.
552 ASSERT_NE(123, dns_client->GetConfig()->attempts);
633 553
634 callback.WaitUntilRun(); 554 // Wait for the query to complete, then check that it was successful.
635 // Check that the DNS changes propogated before the query completed. 555 // The DNS config should be updated during this time.
636 EXPECT_EQ(123, dns_client->GetConfig()->attempts); 556 ASSERT_THAT(callback.WaitForResult(), IsOk());
557 EXPECT_THAT(proof.leaf_index, Eq(123456u));
558 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
559 // EXPECT_THAT(proof.tree_size, Eq(999999));
560 EXPECT_THAT(proof.nodes, Eq(audit_proof));
637 561
638 ASSERT_TRUE(callback.called()); 562 // Check that the DNS config change was adopted.
639 EXPECT_THAT(callback.net_error(), IsOk()); 563 ASSERT_EQ(123, dns_client->GetConfig()->attempts);
640 ASSERT_THAT(callback.proof(), NotNull());
641 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
642 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
643 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
644 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
645 } 564 }
646 565
647 TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) { 566 TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) {
648 // Check that 3 queries can be performed in parallel. 567 // Check that 3 queries can be performed in parallel.
649 constexpr size_t kNumOfParallelQueries = 3; 568 constexpr size_t kNumOfParallelQueries = 3;
650 ASSERT_THAT(kNumOfParallelQueries, 569 ASSERT_THAT(kNumOfParallelQueries,
651 AllOf(Le(arraysize(kLeafIndexQnames)), 570 AllOf(Le(arraysize(kLeafIndexQnames)),
652 Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes)))) 571 Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes))))
653 << "Not enough test data for this many parallel queries"; 572 << "Not enough test data for this many parallel queries";
654 573
655 std::unique_ptr<LogDnsClient> log_client = 574 std::unique_ptr<LogDnsClient> log_client =
656 CreateLogDnsClient(kNumOfParallelQueries); 575 CreateLogDnsClient(kNumOfParallelQueries);
657 MockAuditProofCallback callbacks[kNumOfParallelQueries]; 576 net::TestCompletionCallback callbacks[kNumOfParallelQueries];
658 577
659 // Expect multiple leaf index requests. 578 // Expect multiple leaf index requests.
660 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 579 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
661 mock_dns_.ExpectLeafIndexRequestAndResponse( 580 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[i],
662 kLeafIndexQnames[i], kLeafIndices[i]); 581 kLeafIndices[i]);
663 } 582 }
664 583
665 // Make each query require one more audit proof request than the last, by 584 // Make each query require one more audit proof request than the last, by
666 // increasing the number of nodes in the audit proof by 585 // increasing the number of nodes in the audit proof by
667 // kMaxProofNodesPerDnsResponse for each query. This helps to test that 586 // kMaxProofNodesPerDnsResponse for each query. This helps to test that
668 // parallel queries do not intefere with each other, e.g. one query causing 587 // parallel queries do not intefere with each other, e.g. one query causing
669 // another to end prematurely. 588 // another to end prematurely.
670 std::vector<std::string> audit_proofs[kNumOfParallelQueries]; 589 std::vector<std::string> audit_proofs[kNumOfParallelQueries];
671 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) { 590 for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) {
672 const size_t dns_requests_required = query_i + 1; 591 const size_t dns_requests_required = query_i + 1;
(...skipping 22 matching lines...) Expand all
695 if (start_node < end_node) { 614 if (start_node < end_node) {
696 mock_dns_.ExpectAuditProofRequestAndResponse( 615 mock_dns_.ExpectAuditProofRequestAndResponse(
697 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.", 616 base::StringPrintf("%zu.%" PRIu64 ".%" PRIu64 ".tree.ct.test.",
698 start_node, kLeafIndices[query_i], 617 start_node, kLeafIndices[query_i],
699 kTreeSizes[query_i]), 618 kTreeSizes[query_i]),
700 proof.begin() + start_node, proof.begin() + end_node); 619 proof.begin() + start_node, proof.begin() + end_node);
701 } 620 }
702 } 621 }
703 } 622 }
704 623
624 net::ct::MerkleAuditProof proofs[kNumOfParallelQueries];
625
705 // Start the queries. 626 // Start the queries.
706 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 627 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
707 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[i], 628 ASSERT_THAT(
708 kTreeSizes[i], callbacks[i].AsCallback()); 629 log_client->QueryAuditProof("ct.test", kLeafHashes[i], kTreeSizes[i],
630 &proofs[i], callbacks[i].callback()),
631 IsError(net::ERR_IO_PENDING))
632 << "query #" << i;
709 } 633 }
710 634
711 // Wait for each query to complete and check its results. 635 // Wait for each query to complete and check its results.
712 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { 636 for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
713 MockAuditProofCallback& callback = callbacks[i]; 637 net::TestCompletionCallback& callback = callbacks[i];
714 callbacks[i].WaitUntilRun();
715 638
716 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]"); 639 SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]");
717 ASSERT_TRUE(callback.called()); 640 EXPECT_THAT(callback.WaitForResult(), IsOk());
718 EXPECT_THAT(callback.net_error(), IsOk()); 641 EXPECT_THAT(proofs[i].leaf_index, Eq(kLeafIndices[i]));
719 ASSERT_THAT(callback.proof(), NotNull());
720 EXPECT_THAT(callback.proof()->leaf_index, Eq(kLeafIndices[i]));
721 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 642 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
722 // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]); 643 // EXPECT_THAT(proofs[i].tree_size, kTreeSizes[i]);
723 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i])); 644 EXPECT_THAT(proofs[i].nodes, Eq(audit_proofs[i]));
724 } 645 }
725 } 646 }
726 647
727 TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) { 648 TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
728 // Check that queries can be rate-limited to one at a time. 649 // Check that queries can be rate-limited to one at a time.
729 // The second query, initiated while the first is in progress, should fail. 650 // The second query, initiated while the first is in progress, should fail.
730 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); 651 const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
731 652
732 // Expect the first query to send leaf index and audit proof requests, but the 653 // Expect the first query to send leaf index and audit proof requests, but the
733 // second should not due to throttling. 654 // second should not due to throttling.
(...skipping 10 matching lines...) Expand all
744 audit_proof.begin() + 7, 665 audit_proof.begin() + 7,
745 audit_proof.begin() + 14); 666 audit_proof.begin() + 14);
746 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", 667 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
747 audit_proof.begin() + 14, 668 audit_proof.begin() + 14,
748 audit_proof.end()); 669 audit_proof.end());
749 670
750 const size_t kMaxConcurrentQueries = 1; 671 const size_t kMaxConcurrentQueries = 1;
751 std::unique_ptr<LogDnsClient> log_client = 672 std::unique_ptr<LogDnsClient> log_client =
752 CreateLogDnsClient(kMaxConcurrentQueries); 673 CreateLogDnsClient(kMaxConcurrentQueries);
753 674
754 // Start the queries. 675 // Try to start the queries.
755 MockAuditProofCallback callback1; 676 net::ct::MerkleAuditProof proof1;
756 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[0], 999999, 677 net::TestCompletionCallback callback1;
757 callback1.AsCallback()); 678 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999,
758 MockAuditProofCallback callback2; 679 &proof1, callback1.callback()),
759 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[1], 999999, 680 IsError(net::ERR_IO_PENDING));
760 callback2.AsCallback());
761 681
762 callback1.WaitUntilRun(); 682 net::ct::MerkleAuditProof proof2;
763 callback2.WaitUntilRun(); 683 net::TestCompletionCallback callback2;
684 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999,
685 &proof2, callback2.callback()),
686 IsError(net::ERR_TEMPORARILY_THROTTLED));
764 687
765 // Check that the first query succeeded. 688 // Check that the first query succeeded.
766 ASSERT_TRUE(callback1.called()); 689 EXPECT_THAT(callback1.WaitForResult(), IsOk());
767 EXPECT_THAT(callback1.net_error(), IsOk()); 690 EXPECT_THAT(proof1.leaf_index, Eq(123456u));
768 ASSERT_THAT(callback1.proof(), NotNull());
769 EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u));
770 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 691 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
771 // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999)); 692 // EXPECT_THAT(proof1.tree_size, Eq(999999));
772 EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof)); 693 EXPECT_THAT(proof1.nodes, Eq(audit_proof));
773
774 // Check that the second query failed.
775 ASSERT_TRUE(callback2.called());
776 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
777 EXPECT_THAT(callback2.proof(), IsNull());
778 694
779 // Try a third query, which should succeed now that the first is finished. 695 // Try a third query, which should succeed now that the first is finished.
780 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666); 696 mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666);
781 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.", 697 mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.",
782 audit_proof.begin(), 698 audit_proof.begin(),
783 audit_proof.begin() + 7); 699 audit_proof.begin() + 7);
784 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.", 700 mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.",
785 audit_proof.begin() + 7, 701 audit_proof.begin() + 7,
786 audit_proof.begin() + 14); 702 audit_proof.begin() + 14);
787 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.", 703 mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.",
788 audit_proof.begin() + 14, 704 audit_proof.begin() + 14,
789 audit_proof.end()); 705 audit_proof.end());
790 706
791 MockAuditProofCallback callback3; 707 net::ct::MerkleAuditProof proof3;
792 QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[2], 999999, 708 net::TestCompletionCallback callback3;
793 callback3.AsCallback()); 709 ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[2], 999999,
794 710 &proof3, callback3.callback()),
795 callback3.WaitUntilRun(); 711 IsError(net::ERR_IO_PENDING));
796 712
797 // Check that the third query succeeded. 713 // Check that the third query succeeded.
798 ASSERT_TRUE(callback3.called()); 714 EXPECT_THAT(callback3.WaitForResult(), IsOk());
799 EXPECT_THAT(callback3.net_error(), IsOk()); 715 EXPECT_THAT(proof3.leaf_index, Eq(666u));
800 ASSERT_THAT(callback3.proof(), NotNull());
801 EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u));
802 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. 716 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
803 // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999)); 717 // EXPECT_THAT(proof3.tree_size, Eq(999999));
804 EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof)); 718 EXPECT_THAT(proof3.nodes, Eq(audit_proof));
805 } 719 }
806 720
807 INSTANTIATE_TEST_CASE_P(ReadMode, 721 INSTANTIATE_TEST_CASE_P(ReadMode,
808 LogDnsClientTest, 722 LogDnsClientTest,
809 ::testing::Values(net::IoMode::ASYNC, 723 ::testing::Values(net::IoMode::ASYNC,
810 net::IoMode::SYNCHRONOUS)); 724 net::IoMode::SYNCHRONOUS));
811 725
812 } // namespace 726 } // namespace
813 } // namespace certificate_transparency 727 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698