Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/memory/ptr_util.h" | |
| 12 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 13 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
| 14 #include "components/certificate_transparency/mock_log_dns_traffic.h" | 15 #include "components/certificate_transparency/mock_log_dns_traffic.h" |
| 15 #include "crypto/sha2.h" | 16 #include "crypto/sha2.h" |
| 16 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 17 #include "net/cert/merkle_audit_proof.h" | 18 #include "net/cert/merkle_audit_proof.h" |
| 18 #include "net/cert/signed_certificate_timestamp.h" | 19 #include "net/cert/signed_certificate_timestamp.h" |
| 19 #include "net/dns/dns_client.h" | 20 #include "net/dns/dns_client.h" |
| 20 #include "net/dns/dns_config_service.h" | 21 #include "net/dns/dns_config_service.h" |
| 21 #include "net/dns/dns_protocol.h" | 22 #include "net/dns/dns_protocol.h" |
| 22 #include "net/log/net_log.h" | 23 #include "net/log/net_log.h" |
| 23 #include "net/test/gtest_util.h" | 24 #include "net/test/gtest_util.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | 25 #include "testing/gmock/include/gmock/gmock.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 26 | 27 |
| 27 namespace certificate_transparency { | 28 namespace certificate_transparency { |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 31 using ::testing::Eq; | |
| 30 using ::testing::IsEmpty; | 32 using ::testing::IsEmpty; |
| 31 using ::testing::IsNull; | 33 using ::testing::IsNull; |
| 32 using ::testing::Not; | 34 using ::testing::Not; |
| 33 using ::testing::NotNull; | 35 using ::testing::NotNull; |
| 34 using net::test::IsError; | 36 using net::test::IsError; |
| 35 using net::test::IsOk; | 37 using net::test::IsOk; |
| 36 | 38 |
| 37 constexpr char kLeafHash[] = | 39 constexpr char kLeafHash[] = |
| 38 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8" | 40 "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8" |
| 39 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04"; | 41 "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04"; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 }; | 115 }; |
| 114 | 116 |
| 115 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { | 117 class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { |
| 116 protected: | 118 protected: |
| 117 LogDnsClientTest() | 119 LogDnsClientTest() |
| 118 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) { | 120 : network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) { |
| 119 mock_dns_.SetSocketReadMode(GetParam()); | 121 mock_dns_.SetSocketReadMode(GetParam()); |
| 120 mock_dns_.InitializeDnsConfig(); | 122 mock_dns_.InitializeDnsConfig(); |
| 121 } | 123 } |
| 122 | 124 |
| 125 std::unique_ptr<LogDnsClient> CreateLogDnsClient( | |
| 126 size_t max_concurrent_queries) { | |
| 127 return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(), | |
| 128 net::BoundNetLog(), | |
| 129 max_concurrent_queries); | |
| 130 } | |
| 131 | |
| 132 void QueryLeafIndexAsync(LogDnsClient* log_client, | |
| 133 base::StringPiece log_domain, | |
| 134 base::StringPiece leaf_hash, | |
| 135 const LogDnsClient::LeafIndexCallback& callback) { | |
| 136 log_client->QueryLeafIndex(log_domain, leaf_hash, callback); | |
| 137 } | |
| 138 | |
| 139 // Convenience function for calling QueryLeafIndexAsync synchronously. | |
| 123 void QueryLeafIndex(base::StringPiece log_domain, | 140 void QueryLeafIndex(base::StringPiece log_domain, |
| 124 base::StringPiece leaf_hash, | 141 base::StringPiece leaf_hash, |
| 125 MockLeafIndexCallback* callback) { | 142 MockLeafIndexCallback* callback) { |
| 126 LogDnsClient log_client(mock_dns_.CreateDnsClient(), net::BoundNetLog()); | 143 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0); |
| 127 log_client.QueryLeafIndex(log_domain, leaf_hash, callback->AsCallback()); | 144 QueryLeafIndexAsync(log_client.get(), log_domain, leaf_hash, |
| 145 callback->AsCallback()); | |
| 128 callback->WaitUntilRun(); | 146 callback->WaitUntilRun(); |
| 129 } | 147 } |
| 130 | 148 |
| 149 void QueryAuditProofAsync(LogDnsClient* log_client, | |
| 150 base::StringPiece log_domain, | |
| 151 uint64_t leaf_index, | |
| 152 uint64_t tree_size, | |
| 153 const LogDnsClient::AuditProofCallback& callback) { | |
| 154 log_client->QueryAuditProof(log_domain, leaf_index, tree_size, callback); | |
| 155 } | |
| 156 | |
| 157 // Convenience function for calling QueryAuditProofAsync synchronously. | |
| 131 void QueryAuditProof(base::StringPiece log_domain, | 158 void QueryAuditProof(base::StringPiece log_domain, |
| 132 uint64_t leaf_index, | 159 uint64_t leaf_index, |
| 133 uint64_t tree_size, | 160 uint64_t tree_size, |
| 134 MockAuditProofCallback* callback) { | 161 MockAuditProofCallback* callback) { |
| 135 LogDnsClient log_client(mock_dns_.CreateDnsClient(), net::BoundNetLog()); | 162 std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0); |
| 136 log_client.QueryAuditProof(log_domain, leaf_index, tree_size, | 163 QueryAuditProofAsync(log_client.get(), log_domain, leaf_index, tree_size, |
| 137 callback->AsCallback()); | 164 callback->AsCallback()); |
| 138 callback->WaitUntilRun(); | 165 callback->WaitUntilRun(); |
| 139 } | 166 } |
| 140 | 167 |
| 141 // This will be the NetworkChangeNotifier singleton for the duration of the | 168 // This will be the NetworkChangeNotifier singleton for the duration of the |
| 142 // test. It is accessed statically by LogDnsClient. | 169 // test. It is accessed statically by LogDnsClient. |
| 143 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; | 170 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| 144 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient, | 171 // Queues and handles asynchronous DNS tasks. Indirectly used by LogDnsClient, |
| 145 // the underlying net::DnsClient, and NetworkChangeNotifier. | 172 // the underlying net::DnsClient, and NetworkChangeNotifier. |
| 146 base::MessageLoopForIO message_loop_; | 173 base::MessageLoopForIO message_loop_; |
| 147 // Allows mock DNS sockets to be setup. | 174 // Allows mock DNS sockets to be setup. |
| 148 MockLogDnsTraffic mock_dns_; | 175 MockLogDnsTraffic mock_dns_; |
| 149 }; | 176 }; |
| 150 | 177 |
| 151 TEST_P(LogDnsClientTest, QueryLeafIndex) { | 178 TEST_P(LogDnsClientTest, QueryLeafIndex) { |
| 152 mock_dns_.ExpectLeafIndexRequestAndResponse( | 179 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 153 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 180 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 154 "123456"); | 181 "123456"); |
| 155 | 182 |
| 156 MockLeafIndexCallback callback; | 183 MockLeafIndexCallback callback; |
| 157 QueryLeafIndex("ct.test", kLeafHash, &callback); | 184 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 158 ASSERT_TRUE(callback.called()); | 185 ASSERT_TRUE(callback.called()); |
| 159 EXPECT_THAT(callback.net_error(), IsOk()); | 186 EXPECT_THAT(callback.net_error(), IsOk()); |
| 160 EXPECT_THAT(callback.leaf_index(), 123456); | 187 EXPECT_THAT(callback.leaf_index(), Eq(123456u)); |
| 161 } | 188 } |
| 162 | 189 |
| 163 TEST_P(LogDnsClientTest, QueryLeafIndexReportsThatLogDomainDoesNotExist) { | 190 TEST_P(LogDnsClientTest, QueryLeafIndexReportsThatLogDomainDoesNotExist) { |
| 164 mock_dns_.ExpectRequestAndErrorResponse( | 191 mock_dns_.ExpectRequestAndErrorResponse( |
| 165 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 192 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 166 net::dns_protocol::kRcodeNXDOMAIN); | 193 net::dns_protocol::kRcodeNXDOMAIN); |
| 167 | 194 |
| 168 MockLeafIndexCallback callback; | 195 MockLeafIndexCallback callback; |
| 169 QueryLeafIndex("ct.test", kLeafHash, &callback); | 196 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 170 ASSERT_TRUE(callback.called()); | 197 ASSERT_TRUE(callback.called()); |
| 171 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); | 198 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| 172 EXPECT_THAT(callback.leaf_index(), 0); | 199 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 173 } | 200 } |
| 174 | 201 |
| 175 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerFailure) { | 202 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerFailure) { |
| 176 mock_dns_.ExpectRequestAndErrorResponse( | 203 mock_dns_.ExpectRequestAndErrorResponse( |
| 177 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 204 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 178 net::dns_protocol::kRcodeSERVFAIL); | 205 net::dns_protocol::kRcodeSERVFAIL); |
| 179 | 206 |
| 180 MockLeafIndexCallback callback; | 207 MockLeafIndexCallback callback; |
| 181 QueryLeafIndex("ct.test", kLeafHash, &callback); | 208 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 182 ASSERT_TRUE(callback.called()); | 209 ASSERT_TRUE(callback.called()); |
| 183 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); | 210 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| 184 EXPECT_THAT(callback.leaf_index(), 0); | 211 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 185 } | 212 } |
| 186 | 213 |
| 187 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerRefusal) { | 214 TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerRefusal) { |
| 188 mock_dns_.ExpectRequestAndErrorResponse( | 215 mock_dns_.ExpectRequestAndErrorResponse( |
| 189 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 216 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 190 net::dns_protocol::kRcodeREFUSED); | 217 net::dns_protocol::kRcodeREFUSED); |
| 191 | 218 |
| 192 MockLeafIndexCallback callback; | 219 MockLeafIndexCallback callback; |
| 193 QueryLeafIndex("ct.test", kLeafHash, &callback); | 220 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 194 ASSERT_TRUE(callback.called()); | 221 ASSERT_TRUE(callback.called()); |
| 195 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); | 222 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| 196 EXPECT_THAT(callback.leaf_index(), 0); | 223 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 197 } | 224 } |
| 198 | 225 |
| 199 TEST_P(LogDnsClientTest, | 226 TEST_P(LogDnsClientTest, |
| 200 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsNotNumeric) { | 227 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsNotNumeric) { |
| 201 mock_dns_.ExpectLeafIndexRequestAndResponse( | 228 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 202 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 229 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 203 "foo"); | 230 "foo"); |
| 204 | 231 |
| 205 MockLeafIndexCallback callback; | 232 MockLeafIndexCallback callback; |
| 206 QueryLeafIndex("ct.test", kLeafHash, &callback); | 233 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 207 ASSERT_TRUE(callback.called()); | 234 ASSERT_TRUE(callback.called()); |
| 208 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); | 235 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| 209 EXPECT_THAT(callback.leaf_index(), 0); | 236 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 210 } | 237 } |
| 211 | 238 |
| 212 TEST_P(LogDnsClientTest, | 239 TEST_P(LogDnsClientTest, |
| 213 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsFloatingPoint) { | 240 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsFloatingPoint) { |
| 214 mock_dns_.ExpectLeafIndexRequestAndResponse( | 241 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 215 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 242 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 216 "123456.0"); | 243 "123456.0"); |
| 217 | 244 |
| 218 MockLeafIndexCallback callback; | 245 MockLeafIndexCallback callback; |
| 219 QueryLeafIndex("ct.test", kLeafHash, &callback); | 246 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 220 ASSERT_TRUE(callback.called()); | 247 ASSERT_TRUE(callback.called()); |
| 221 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); | 248 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| 222 EXPECT_THAT(callback.leaf_index(), 0); | 249 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 223 } | 250 } |
| 224 | 251 |
| 225 TEST_P(LogDnsClientTest, | 252 TEST_P(LogDnsClientTest, |
| 226 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsEmpty) { | 253 QueryLeafIndexReportsMalformedResponseIfLeafIndexIsEmpty) { |
| 227 mock_dns_.ExpectLeafIndexRequestAndResponse( | 254 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 228 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", ""); | 255 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", ""); |
| 229 | 256 |
| 230 MockLeafIndexCallback callback; | 257 MockLeafIndexCallback callback; |
| 231 QueryLeafIndex("ct.test", kLeafHash, &callback); | 258 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 232 ASSERT_TRUE(callback.called()); | 259 ASSERT_TRUE(callback.called()); |
| 233 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); | 260 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| 234 EXPECT_THAT(callback.leaf_index(), 0); | 261 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 235 } | 262 } |
| 236 | 263 |
| 237 TEST_P(LogDnsClientTest, | 264 TEST_P(LogDnsClientTest, |
| 238 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { | 265 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { |
| 239 mock_dns_.ExpectLeafIndexRequestAndResponse( | 266 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 240 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 267 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 241 "foo123456"); | 268 "foo123456"); |
| 242 | 269 |
| 243 MockLeafIndexCallback callback; | 270 MockLeafIndexCallback callback; |
| 244 QueryLeafIndex("ct.test", kLeafHash, &callback); | 271 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 245 ASSERT_TRUE(callback.called()); | 272 ASSERT_TRUE(callback.called()); |
| 246 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); | 273 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| 247 EXPECT_THAT(callback.leaf_index(), 0); | 274 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 248 } | 275 } |
| 249 | 276 |
| 250 TEST_P(LogDnsClientTest, | 277 TEST_P(LogDnsClientTest, |
| 251 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { | 278 QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { |
| 252 mock_dns_.ExpectLeafIndexRequestAndResponse( | 279 mock_dns_.ExpectLeafIndexRequestAndResponse( |
| 253 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 280 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 254 "123456foo"); | 281 "123456foo"); |
| 255 | 282 |
| 256 MockLeafIndexCallback callback; | 283 MockLeafIndexCallback callback; |
| 257 QueryLeafIndex("ct.test", kLeafHash, &callback); | 284 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 258 ASSERT_TRUE(callback.called()); | 285 ASSERT_TRUE(callback.called()); |
| 259 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); | 286 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| 260 EXPECT_THAT(callback.leaf_index(), 0); | 287 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 261 } | 288 } |
| 262 | 289 |
| 263 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsEmpty) { | 290 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsEmpty) { |
| 264 MockLeafIndexCallback callback; | 291 MockLeafIndexCallback callback; |
| 265 QueryLeafIndex("", kLeafHash, &callback); | 292 QueryLeafIndex("", kLeafHash, &callback); |
| 266 ASSERT_TRUE(callback.called()); | 293 ASSERT_TRUE(callback.called()); |
| 267 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); | 294 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| 268 EXPECT_THAT(callback.leaf_index(), 0); | 295 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 269 } | 296 } |
| 270 | 297 |
| 271 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsNull) { | 298 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsNull) { |
| 272 MockLeafIndexCallback callback; | 299 MockLeafIndexCallback callback; |
| 273 QueryLeafIndex(nullptr, kLeafHash, &callback); | 300 QueryLeafIndex(nullptr, kLeafHash, &callback); |
| 274 ASSERT_TRUE(callback.called()); | 301 ASSERT_TRUE(callback.called()); |
| 275 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); | 302 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| 276 EXPECT_THAT(callback.leaf_index(), 0); | 303 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 277 } | 304 } |
| 278 | 305 |
| 279 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsInvalid) { | 306 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsInvalid) { |
| 280 MockLeafIndexCallback callback; | 307 MockLeafIndexCallback callback; |
| 281 QueryLeafIndex("ct.test", "foo", &callback); | 308 QueryLeafIndex("ct.test", "foo", &callback); |
| 282 ASSERT_TRUE(callback.called()); | 309 ASSERT_TRUE(callback.called()); |
| 283 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); | 310 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| 284 EXPECT_THAT(callback.leaf_index(), 0); | 311 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 285 } | 312 } |
| 286 | 313 |
| 287 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsEmpty) { | 314 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsEmpty) { |
| 288 MockLeafIndexCallback callback; | 315 MockLeafIndexCallback callback; |
| 289 QueryLeafIndex("ct.test", "", &callback); | 316 QueryLeafIndex("ct.test", "", &callback); |
| 290 ASSERT_TRUE(callback.called()); | 317 ASSERT_TRUE(callback.called()); |
| 291 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); | 318 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| 292 EXPECT_THAT(callback.leaf_index(), 0); | 319 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 293 } | 320 } |
| 294 | 321 |
| 295 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsNull) { | 322 TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsNull) { |
| 296 MockLeafIndexCallback callback; | 323 MockLeafIndexCallback callback; |
| 297 QueryLeafIndex("ct.test", nullptr, &callback); | 324 QueryLeafIndex("ct.test", nullptr, &callback); |
| 298 ASSERT_TRUE(callback.called()); | 325 ASSERT_TRUE(callback.called()); |
| 299 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); | 326 EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| 300 EXPECT_THAT(callback.leaf_index(), 0); | 327 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 301 } | 328 } |
| 302 | 329 |
| 303 TEST_P(LogDnsClientTest, QueryLeafIndexReportsSocketError) { | 330 TEST_P(LogDnsClientTest, QueryLeafIndexReportsSocketError) { |
| 304 mock_dns_.ExpectRequestAndSocketError( | 331 mock_dns_.ExpectRequestAndSocketError( |
| 305 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | 332 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", |
| 306 net::ERR_CONNECTION_REFUSED); | 333 net::ERR_CONNECTION_REFUSED); |
| 307 | 334 |
| 308 MockLeafIndexCallback callback; | 335 MockLeafIndexCallback callback; |
| 309 QueryLeafIndex("ct.test", kLeafHash, &callback); | 336 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 310 ASSERT_TRUE(callback.called()); | 337 ASSERT_TRUE(callback.called()); |
| 311 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED)); | 338 EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED)); |
| 312 EXPECT_THAT(callback.leaf_index(), 0); | 339 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 313 } | 340 } |
| 314 | 341 |
| 315 TEST_P(LogDnsClientTest, QueryLeafIndexReportsTimeout) { | 342 TEST_P(LogDnsClientTest, QueryLeafIndexReportsTimeout) { |
| 316 mock_dns_.ExpectRequestAndTimeout( | 343 mock_dns_.ExpectRequestAndTimeout( |
| 317 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test."); | 344 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test."); |
| 318 | 345 |
| 319 MockLeafIndexCallback callback; | 346 MockLeafIndexCallback callback; |
| 320 QueryLeafIndex("ct.test", kLeafHash, &callback); | 347 QueryLeafIndex("ct.test", kLeafHash, &callback); |
| 321 ASSERT_TRUE(callback.called()); | 348 ASSERT_TRUE(callback.called()); |
| 322 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); | 349 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); |
| 323 EXPECT_THAT(callback.leaf_index(), 0); | 350 EXPECT_THAT(callback.leaf_index(), Eq(0u)); |
| 324 } | 351 } |
| 325 | 352 |
| 326 TEST_P(LogDnsClientTest, QueryAuditProof) { | 353 TEST_P(LogDnsClientTest, QueryAuditProof) { |
| 327 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); | 354 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); |
| 328 | 355 |
| 329 // It should require 3 queries to collect the entire audit proof, as there is | 356 // It should require 3 requests to collect the entire audit proof, as there is |
| 330 // only space for 7 nodes per UDP packet. | 357 // only space for 7 nodes per TXT record. One node is 32 bytes long and the |
| 358 // TXT RDATA can have a maximum length of 255 bytes (255 / 32). | |
| 331 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", | 359 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", |
| 332 audit_proof.begin(), | 360 audit_proof.begin(), |
| 333 audit_proof.begin() + 7); | 361 audit_proof.begin() + 7); |
| 334 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", | 362 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", |
| 335 audit_proof.begin() + 7, | 363 audit_proof.begin() + 7, |
| 336 audit_proof.begin() + 14); | 364 audit_proof.begin() + 14); |
| 337 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", | 365 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", |
| 338 audit_proof.begin() + 14, | 366 audit_proof.begin() + 14, |
| 339 audit_proof.end()); | 367 audit_proof.end()); |
| 340 | 368 |
| 341 MockAuditProofCallback callback; | 369 MockAuditProofCallback callback; |
| 342 QueryAuditProof("ct.test", 123456, 999999, &callback); | 370 QueryAuditProof("ct.test", 123456, 999999, &callback); |
| 343 ASSERT_TRUE(callback.called()); | 371 ASSERT_TRUE(callback.called()); |
| 344 EXPECT_THAT(callback.net_error(), IsOk()); | 372 EXPECT_THAT(callback.net_error(), IsOk()); |
| 345 ASSERT_THAT(callback.proof(), NotNull()); | 373 ASSERT_THAT(callback.proof(), NotNull()); |
| 346 EXPECT_THAT(callback.proof()->leaf_index, 123456); | 374 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u)); |
| 347 // EXPECT_THAT(callback.proof()->tree_size, 999999); | 375 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. |
| 348 EXPECT_THAT(callback.proof()->nodes, audit_proof); | 376 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); |
| 377 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); | |
| 349 } | 378 } |
| 350 | 379 |
| 351 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) { | 380 TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) { |
| 352 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); | 381 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); |
| 353 | 382 |
| 354 // Make some of the responses contain fewer proof nodes than they can hold. | 383 // Make some of the responses contain fewer proof nodes than they can hold. |
| 355 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", | 384 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", |
| 356 audit_proof.begin(), | 385 audit_proof.begin(), |
| 357 audit_proof.begin() + 1); | 386 audit_proof.begin() + 1); |
| 358 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.", | 387 mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.", |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 369 audit_proof.begin() + 13); | 398 audit_proof.begin() + 13); |
| 370 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.", | 399 mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.", |
| 371 audit_proof.begin() + 13, | 400 audit_proof.begin() + 13, |
| 372 audit_proof.end()); | 401 audit_proof.end()); |
| 373 | 402 |
| 374 MockAuditProofCallback callback; | 403 MockAuditProofCallback callback; |
| 375 QueryAuditProof("ct.test", 123456, 999999, &callback); | 404 QueryAuditProof("ct.test", 123456, 999999, &callback); |
| 376 ASSERT_TRUE(callback.called()); | 405 ASSERT_TRUE(callback.called()); |
| 377 EXPECT_THAT(callback.net_error(), IsOk()); | 406 EXPECT_THAT(callback.net_error(), IsOk()); |
| 378 ASSERT_THAT(callback.proof(), NotNull()); | 407 ASSERT_THAT(callback.proof(), NotNull()); |
| 379 EXPECT_THAT(callback.proof()->leaf_index, 123456); | 408 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u)); |
| 380 // EXPECT_THAT(callback.proof()->tree_size, 999999); | 409 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. |
| 381 EXPECT_THAT(callback.proof()->nodes, audit_proof); | 410 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); |
| 411 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); | |
| 382 } | 412 } |
| 383 | 413 |
| 384 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { | 414 TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { |
| 385 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", | 415 mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", |
| 386 net::dns_protocol::kRcodeNXDOMAIN); | 416 net::dns_protocol::kRcodeNXDOMAIN); |
| 387 | 417 |
| 388 MockAuditProofCallback callback; | 418 MockAuditProofCallback callback; |
| 389 QueryAuditProof("ct.test", 123456, 999999, &callback); | 419 QueryAuditProof("ct.test", 123456, 999999, &callback); |
| 390 ASSERT_TRUE(callback.called()); | 420 ASSERT_TRUE(callback.called()); |
| 391 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); | 421 EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 MockAuditProofCallback callback; | 537 MockAuditProofCallback callback; |
| 508 QueryAuditProof("ct.test", 123456, 999999, &callback); | 538 QueryAuditProof("ct.test", 123456, 999999, &callback); |
| 509 ASSERT_TRUE(callback.called()); | 539 ASSERT_TRUE(callback.called()); |
| 510 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); | 540 EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); |
| 511 EXPECT_THAT(callback.proof(), IsNull()); | 541 EXPECT_THAT(callback.proof(), IsNull()); |
| 512 } | 542 } |
| 513 | 543 |
| 514 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { | 544 TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { |
| 515 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); | 545 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); |
| 516 net::DnsClient* dns_client = tmp.get(); | 546 net::DnsClient* dns_client = tmp.get(); |
| 517 LogDnsClient log_client(std::move(tmp), net::BoundNetLog()); | 547 LogDnsClient log_client(std::move(tmp), net::BoundNetLog(), 0); |
| 518 | 548 |
| 519 // Get the current DNS config, modify it and broadcast the update. | 549 // Get the current DNS config, modify it and broadcast the update. |
| 520 net::DnsConfig config(*dns_client->GetConfig()); | 550 net::DnsConfig config(*dns_client->GetConfig()); |
| 521 ASSERT_NE(123, config.attempts); | 551 ASSERT_NE(123, config.attempts); |
| 522 config.attempts = 123; | 552 config.attempts = 123; |
| 523 mock_dns_.SetDnsConfig(config); | 553 mock_dns_.SetDnsConfig(config); |
| 524 | 554 |
| 525 // Let the DNS config change propogate. | 555 // Let the DNS config change propogate. |
| 526 base::RunLoop().RunUntilIdle(); | 556 base::RunLoop().RunUntilIdle(); |
| 527 EXPECT_EQ(123, dns_client->GetConfig()->attempts); | 557 EXPECT_EQ(123, dns_client->GetConfig()->attempts); |
| 528 } | 558 } |
| 529 | 559 |
| 530 TEST_P(LogDnsClientTest, IgnoresLatestDnsConfigIfInvalid) { | 560 TEST_P(LogDnsClientTest, IgnoresLatestDnsConfigIfInvalid) { |
| 531 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); | 561 std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); |
| 532 net::DnsClient* dns_client = tmp.get(); | 562 net::DnsClient* dns_client = tmp.get(); |
| 533 LogDnsClient log_client(std::move(tmp), net::BoundNetLog()); | 563 LogDnsClient log_client(std::move(tmp), net::BoundNetLog(), 0); |
| 534 | 564 |
| 535 // Get the current DNS config, modify it and broadcast the update. | 565 // Get the current DNS config, modify it and broadcast the update. |
| 536 net::DnsConfig config(*dns_client->GetConfig()); | 566 net::DnsConfig config(*dns_client->GetConfig()); |
| 537 ASSERT_THAT(config.nameservers, Not(IsEmpty())); | 567 ASSERT_THAT(config.nameservers, Not(IsEmpty())); |
| 538 config.nameservers.clear(); // Makes config invalid | 568 config.nameservers.clear(); // Makes config invalid |
| 539 mock_dns_.SetDnsConfig(config); | 569 mock_dns_.SetDnsConfig(config); |
| 540 | 570 |
| 541 // Let the DNS config change propogate. | 571 // Let the DNS config change propogate. |
| 542 base::RunLoop().RunUntilIdle(); | 572 base::RunLoop().RunUntilIdle(); |
| 543 EXPECT_THAT(dns_client->GetConfig()->nameservers, Not(IsEmpty())); | 573 EXPECT_THAT(dns_client->GetConfig()->nameservers, Not(IsEmpty())); |
| 544 } | 574 } |
| 545 | 575 |
| 576 TEST_P(LogDnsClientTest, CanPerformLeafIndexQueriesInParallel) { | |
| 577 // Test that 3 leaf index queries can be performed in parallel. | |
| 578 constexpr size_t kNumOfParallelQueries = 3; | |
| 579 std::unique_ptr<LogDnsClient> log_client = | |
| 580 CreateLogDnsClient(kNumOfParallelQueries); | |
| 581 MockLeafIndexCallback callbacks[kNumOfParallelQueries]; | |
| 582 | |
| 583 // Expect 3 requests. | |
| 584 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 585 mock_dns_.ExpectLeafIndexRequestAndResponse( | |
| 586 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | |
| 587 "123456"); | |
|
Ryan Sleevi
2016/09/16 02:11:03
Is this value necessary as part of the test? The s
Rob Percival
2016/09/16 16:28:19
They're required to test that nothing goes quietly
Ryan Sleevi
2016/09/17 01:51:52
Right, with the current structure (using the same
Rob Percival
2016/09/20 18:54:42
Done.
| |
| 588 } | |
| 589 | |
| 590 // Start the queries. | |
| 591 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 592 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHash, | |
| 593 callbacks[i].AsCallback()); | |
| 594 } | |
| 595 | |
| 596 // Wait for each query to complete and check its results. | |
| 597 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 598 MockLeafIndexCallback& callback = callbacks[i]; | |
| 599 callback.WaitUntilRun(); | |
| 600 | |
| 601 SCOPED_TRACE(i); | |
| 602 EXPECT_TRUE(callback.called()); | |
| 603 if (callback.called()) { | |
| 604 EXPECT_THAT(callback.net_error(), IsOk()); | |
| 605 EXPECT_THAT(callback.leaf_index(), Eq(123456u)); | |
| 606 } | |
| 607 } | |
|
Ryan Sleevi
2016/09/16 02:11:03
For what it's worth, I spent 20 minutes digging th
Rob Percival
2016/09/16 16:28:19
This is another thing that was only added as a res
Ryan Sleevi
2016/09/17 01:51:52
Link to previous CL?
Rob Percival
2016/09/20 18:54:42
https://codereview.chromium.org/2066553002/#ps1800
Ryan Sleevi
2016/09/22 04:37:07
Thanks. I think there was a breakdown in communica
Rob Percival
2016/09/22 11:33:23
Ah I see, TestCompletionCallback has a unique_ptr<
| |
| 608 } | |
| 609 | |
| 610 TEST_P(LogDnsClientTest, CanPerformAuditProofQueriesInParallel) { | |
| 611 // Check that 3 audit proof queries can be performed in parallel. | |
| 612 constexpr size_t kNumOfParallelQueries = 3; | |
| 613 std::unique_ptr<LogDnsClient> log_client = | |
| 614 CreateLogDnsClient(kNumOfParallelQueries); | |
| 615 MockAuditProofCallback callbacks[kNumOfParallelQueries]; | |
| 616 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); | |
| 617 | |
| 618 // It should require 3 requests to collect the entire audit proof, as there is | |
| 619 // only space for 7 nodes per TXT record. One node is 32 bytes long and the | |
| 620 // TXT RDATA can have a maximum length of 255 bytes (255 / 32). Expect each of | |
| 621 // these queries to occur once for each call to QueryAuditProof. | |
| 622 | |
| 623 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 624 mock_dns_.ExpectAuditProofRequestAndResponse( | |
| 625 "0.123456.999999.tree.ct.test.", audit_proof.begin(), | |
| 626 audit_proof.begin() + 7); | |
| 627 } | |
| 628 | |
| 629 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 630 mock_dns_.ExpectAuditProofRequestAndResponse( | |
| 631 "7.123456.999999.tree.ct.test.", audit_proof.begin() + 7, | |
| 632 audit_proof.begin() + 14); | |
| 633 } | |
| 634 | |
| 635 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 636 mock_dns_.ExpectAuditProofRequestAndResponse( | |
| 637 "14.123456.999999.tree.ct.test.", audit_proof.begin() + 14, | |
| 638 audit_proof.end()); | |
| 639 } | |
| 640 | |
| 641 // Start the queries. | |
| 642 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 643 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, | |
| 644 callbacks[i].AsCallback()); | |
| 645 } | |
| 646 | |
| 647 // Wait for each query to complete and check its results. | |
| 648 for (size_t i = 0; i < kNumOfParallelQueries; ++i) { | |
| 649 MockAuditProofCallback& callback = callbacks[i]; | |
| 650 callbacks[i].WaitUntilRun(); | |
| 651 | |
| 652 SCOPED_TRACE(i); | |
| 653 EXPECT_TRUE(callback.called()); | |
| 654 if (callback.called()) { | |
| 655 EXPECT_THAT(callback.net_error(), IsOk()); | |
| 656 EXPECT_THAT(callback.proof(), NotNull()); | |
| 657 if (callback.proof() != nullptr) { | |
| 658 EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u)); | |
| 659 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. | |
| 660 // EXPECT_THAT(callback.proof()->tree_size, Eq(999999)); | |
| 661 EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof)); | |
| 662 } | |
| 663 } | |
| 664 } | |
| 665 } | |
| 666 | |
| 667 TEST_P(LogDnsClientTest, CanPerformLeafIndexAndAuditProofQueriesInParallel) { | |
| 668 // Check that a leaf index and audit proof query can be performed in parallel. | |
| 669 constexpr size_t kNumOfParallelQueries = 2; | |
| 670 std::unique_ptr<LogDnsClient> log_client = | |
| 671 CreateLogDnsClient(kNumOfParallelQueries); | |
| 672 MockLeafIndexCallback leaf_index_callback; | |
| 673 MockAuditProofCallback audit_proof_callback; | |
| 674 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); | |
| 675 | |
| 676 mock_dns_.ExpectLeafIndexRequestAndResponse( | |
| 677 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | |
| 678 "123456"); | |
| 679 | |
| 680 // It should require 3 requests to collect the entire audit proof, as there is | |
| 681 // only space for 7 nodes per TXT record. One node is 32 bytes long and the | |
| 682 // TXT RDATA can have a maximum length of 255 bytes (255 / 32). | |
| 683 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", | |
| 684 audit_proof.begin(), | |
| 685 audit_proof.begin() + 7); | |
| 686 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", | |
| 687 audit_proof.begin() + 7, | |
| 688 audit_proof.begin() + 14); | |
| 689 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", | |
| 690 audit_proof.begin() + 14, | |
| 691 audit_proof.end()); | |
| 692 | |
| 693 // Start the queries. | |
| 694 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHash, | |
| 695 leaf_index_callback.AsCallback()); | |
| 696 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, | |
| 697 audit_proof_callback.AsCallback()); | |
| 698 | |
| 699 // Wait for the queries to complete, then check their results. | |
| 700 leaf_index_callback.WaitUntilRun(); | |
| 701 audit_proof_callback.WaitUntilRun(); | |
| 702 | |
| 703 EXPECT_TRUE(leaf_index_callback.called()); | |
| 704 if (leaf_index_callback.called()) { | |
| 705 EXPECT_THAT(leaf_index_callback.net_error(), IsOk()); | |
| 706 EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u)); | |
| 707 } | |
| 708 | |
| 709 EXPECT_TRUE(audit_proof_callback.called()); | |
| 710 if (audit_proof_callback.called()) { | |
| 711 EXPECT_THAT(audit_proof_callback.net_error(), IsOk()); | |
| 712 EXPECT_THAT(audit_proof_callback.proof(), NotNull()); | |
| 713 if (audit_proof_callback.proof() != nullptr) { | |
| 714 EXPECT_THAT(audit_proof_callback.proof()->leaf_index, Eq(123456u)); | |
| 715 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. | |
| 716 // EXPECT_THAT(audit_proof_callback.proof()->tree_size, Eq(999999)); | |
| 717 EXPECT_THAT(audit_proof_callback.proof()->nodes, Eq(audit_proof)); | |
| 718 } | |
| 719 } | |
| 720 } | |
| 721 | |
| 722 TEST_P(LogDnsClientTest, CanBeThrottledToOneLeafIndexQueryAtATime) { | |
| 723 // Check that leaf index queries can be rate-limited to one at a time. | |
| 724 // The second query, initiated while the first is in progress, should fail. | |
| 725 mock_dns_.ExpectLeafIndexRequestAndResponse( | |
| 726 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | |
| 727 "123456"); | |
| 728 | |
| 729 const size_t max_concurrent_queries = 1; | |
| 730 std::unique_ptr<LogDnsClient> log_client = | |
| 731 CreateLogDnsClient(max_concurrent_queries); | |
| 732 | |
| 733 // Start the queries. | |
| 734 MockLeafIndexCallback callback1; | |
| 735 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHash, | |
| 736 callback1.AsCallback()); | |
| 737 MockLeafIndexCallback callback2; | |
| 738 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHash, | |
| 739 callback2.AsCallback()); | |
| 740 | |
| 741 callback1.WaitUntilRun(); | |
| 742 callback2.WaitUntilRun(); | |
| 743 | |
| 744 // Check that the first query succeeded. | |
| 745 EXPECT_TRUE(callback1.called()); | |
| 746 if (callback1.called()) { | |
|
Ryan Sleevi
2016/09/16 02:11:03
This is non-obvious to me why you have an EXPECT_T
Rob Percival
2016/09/16 16:28:19
It's actually "Expect that this code will be calle
Ryan Sleevi
2016/09/17 01:51:52
Why?
In the face of failure, what new and additio
Rob Percival
2016/09/20 18:54:42
As discussed in https://testing.googleblog.com/200
Ryan Sleevi
2016/09/22 04:37:07
Apologies that I worded the question poorly, and p
Rob Percival
2016/09/22 11:33:23
Very well. I'm not entirely convinced, but I'll de
| |
| 747 EXPECT_THAT(callback1.net_error(), IsOk()); | |
| 748 EXPECT_THAT(callback1.leaf_index(), Eq(123456u)); | |
| 749 } | |
| 750 | |
| 751 // Check that the second query failed. | |
| 752 EXPECT_TRUE(callback2.called()); | |
| 753 if (callback2.called()) { | |
| 754 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED)); | |
| 755 EXPECT_THAT(callback2.leaf_index(), Eq(0u)); | |
| 756 } | |
| 757 } | |
| 758 | |
| 759 TEST_P(LogDnsClientTest, CanBeThrottledToOneAuditProofQueryAtATime) { | |
| 760 // Check that audit proof queries can be rate-limited to one at a time. | |
| 761 // The second query, initiated while the first is in progress, should fail. | |
| 762 const std::vector<std::string> audit_proof = GetSampleAuditProof(20); | |
| 763 | |
| 764 // It should require 3 requests to collect the entire audit proof, as there is | |
| 765 // only space for 7 nodes per TXT record. One node is 32 bytes long and the | |
| 766 // TXT RDATA can have a maximum length of 255 bytes (255 / 32). | |
| 767 // Rate limiting should not interfere with these requests. | |
| 768 mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.", | |
| 769 audit_proof.begin(), | |
| 770 audit_proof.begin() + 7); | |
| 771 mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.", | |
| 772 audit_proof.begin() + 7, | |
| 773 audit_proof.begin() + 14); | |
| 774 mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.", | |
| 775 audit_proof.begin() + 14, | |
| 776 audit_proof.end()); | |
| 777 | |
| 778 const size_t max_concurrent_queries = 1; | |
| 779 std::unique_ptr<LogDnsClient> log_client = | |
| 780 CreateLogDnsClient(max_concurrent_queries); | |
| 781 | |
| 782 // Start the queries. | |
| 783 MockAuditProofCallback callback1; | |
| 784 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, | |
| 785 callback1.AsCallback()); | |
| 786 MockAuditProofCallback callback2; | |
| 787 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, | |
| 788 callback2.AsCallback()); | |
| 789 | |
| 790 callback1.WaitUntilRun(); | |
| 791 callback2.WaitUntilRun(); | |
| 792 | |
| 793 // Check that the first query succeeded. | |
| 794 EXPECT_TRUE(callback1.called()); | |
| 795 if (callback1.called()) { | |
| 796 EXPECT_THAT(callback1.net_error(), IsOk()); | |
| 797 EXPECT_THAT(callback1.proof(), NotNull()); | |
| 798 if (callback1.proof() != nullptr) { | |
| 799 EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u)); | |
| 800 // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. | |
| 801 // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999)); | |
| 802 EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof)); | |
| 803 } | |
| 804 } | |
| 805 | |
| 806 // Check that the second query failed. | |
| 807 EXPECT_TRUE(callback2.called()); | |
| 808 if (callback2.called()) { | |
| 809 EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED)); | |
| 810 EXPECT_THAT(callback2.proof(), IsNull()); | |
| 811 } | |
| 812 } | |
| 813 | |
| 814 TEST_P(LogDnsClientTest, ThrottlingAppliesAcrossQueryTypes) { | |
| 815 // Check that queries can be rate-limited to one at a time, regardless of the | |
| 816 // type of query. The second query, initiated while the first is in progress, | |
| 817 // should fail. | |
| 818 mock_dns_.ExpectLeafIndexRequestAndResponse( | |
| 819 "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.", | |
| 820 "123456"); | |
| 821 | |
| 822 const size_t max_concurrent_queries = 1; | |
| 823 std::unique_ptr<LogDnsClient> log_client = | |
| 824 CreateLogDnsClient(max_concurrent_queries); | |
| 825 | |
| 826 // Start the queries. | |
| 827 MockLeafIndexCallback leaf_index_callback; | |
| 828 QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHash, | |
| 829 leaf_index_callback.AsCallback()); | |
| 830 MockAuditProofCallback audit_proof_callback; | |
| 831 QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999, | |
| 832 audit_proof_callback.AsCallback()); | |
| 833 | |
| 834 leaf_index_callback.WaitUntilRun(); | |
| 835 audit_proof_callback.WaitUntilRun(); | |
| 836 | |
| 837 // Check that the first query succeeded. | |
| 838 EXPECT_TRUE(leaf_index_callback.called()); | |
| 839 if (leaf_index_callback.called()) { | |
| 840 EXPECT_THAT(leaf_index_callback.net_error(), IsOk()); | |
| 841 EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u)); | |
| 842 } | |
| 843 | |
| 844 // Check that the second query failed. | |
| 845 EXPECT_TRUE(audit_proof_callback.called()); | |
| 846 if (audit_proof_callback.called()) { | |
| 847 EXPECT_THAT(audit_proof_callback.net_error(), | |
| 848 IsError(net::ERR_TEMPORARILY_THROTTLED)); | |
| 849 EXPECT_THAT(audit_proof_callback.proof(), IsNull()); | |
| 850 } | |
| 851 } | |
| 852 | |
| 546 INSTANTIATE_TEST_CASE_P(ReadMode, | 853 INSTANTIATE_TEST_CASE_P(ReadMode, |
| 547 LogDnsClientTest, | 854 LogDnsClientTest, |
| 548 ::testing::Values(net::IoMode::ASYNC, | 855 ::testing::Values(net::IoMode::ASYNC, |
| 549 net::IoMode::SYNCHRONOUS)); | 856 net::IoMode::SYNCHRONOUS)); |
| 550 | 857 |
| 551 } // namespace | 858 } // namespace |
| 552 } // namespace certificate_transparency | 859 } // namespace certificate_transparency |
| OLD | NEW |