| Index: components/certificate_transparency/log_dns_client_unittest.cc
|
| diff --git a/components/certificate_transparency/log_dns_client_unittest.cc b/components/certificate_transparency/log_dns_client_unittest.cc
|
| index a1597137c60469ae923316295c661bdf4206d7d6..684eedf920898690f2aea3e623ac0b2b8d7ed102 100644
|
| --- a/components/certificate_transparency/log_dns_client_unittest.cc
|
| +++ b/components/certificate_transparency/log_dns_client_unittest.cc
|
| @@ -39,27 +39,29 @@ using ::testing::Le;
|
| using ::testing::Not;
|
| using ::testing::NotNull;
|
| using net::test::IsError;
|
| using net::test::IsOk;
|
|
|
| +// Sample Merkle leaf hashes.
|
| const char* const kLeafHashes[] = {
|
| "\x1f\x25\xe1\xca\xba\x4f\xf9\xb8\x27\x24\x83\x0f\xca\x60\xe4\xc2\xbe\xa8"
|
| "\xc3\xa9\x44\x1c\x27\xb0\xb4\x3e\x6a\x96\x94\xc7\xb8\x04",
|
| "\x2c\x26\xb4\x6b\x68\xff\xc6\x8f\xf9\x9b\x45\x3c\x1d\x30\x41\x34\x13\x42"
|
| "\x2d\x70\x64\x83\xbf\xa0\xf9\x8a\x5e\x88\x62\x66\xe7\xae",
|
| "\xfc\xde\x2b\x2e\xdb\xa5\x6b\xf4\x08\x60\x1f\xb7\x21\xfe\x9b\x5c\x33\x8d"
|
| "\x10\xee\x42\x9e\xa0\x4f\xae\x55\x11\xb6\x8f\xbf\x8f\xb9",
|
| };
|
|
|
| -// Assumes log domain is "ct.test"
|
| -const char* const kBase32LeafHashes[] = {
|
| +// DNS query names for looking up the leaf index associated with each hash in
|
| +// |kLeafHashes|. Assumes the log domain is "ct.test".
|
| +const char* const kLeafIndexQnames[] = {
|
| "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.",
|
| "FQTLI23I77DI76M3IU6B2MCBGQJUELLQMSB37IHZRJPIQYTG46XA.hash.ct.test.",
|
| "7TPCWLW3UVV7ICDAD63SD7U3LQZY2EHOIKPKAT5OKUI3ND57R64Q.hash.ct.test.",
|
| };
|
|
|
| -// Leaf indices and tree sizes for use with above leaf hashes.
|
| +// Leaf indices and tree sizes for use with |kLeafHashes|.
|
| const uint64_t kLeafIndices[] = {0, 1, 2};
|
| const uint64_t kTreeSizes[] = {100, 10000, 1000000};
|
|
|
| // Only 7 audit proof nodes can fit into a DNS response, because they are sent
|
| // in a TXT RDATA string, which has a maximum size of 255 bytes, and each node
|
| @@ -82,39 +84,10 @@ std::vector<std::string> GetSampleAuditProof(size_t length) {
|
| }
|
|
|
| return audit_proof;
|
| }
|
|
|
| -class MockLeafIndexCallback {
|
| - public:
|
| - MockLeafIndexCallback() : called_(false) {}
|
| -
|
| - bool called() const { return called_; }
|
| - int net_error() const { return net_error_; }
|
| - uint64_t leaf_index() const { return leaf_index_; }
|
| -
|
| - void Run(int net_error, uint64_t leaf_index) {
|
| - EXPECT_FALSE(called_);
|
| - called_ = true;
|
| - net_error_ = net_error;
|
| - leaf_index_ = leaf_index;
|
| - run_loop_.Quit();
|
| - }
|
| -
|
| - LogDnsClient::LeafIndexCallback AsCallback() {
|
| - return base::Bind(&MockLeafIndexCallback::Run, base::Unretained(this));
|
| - }
|
| -
|
| - void WaitUntilRun() { run_loop_.Run(); }
|
| -
|
| - private:
|
| - bool called_;
|
| - int net_error_;
|
| - uint64_t leaf_index_;
|
| - base::RunLoop run_loop_;
|
| -};
|
| -
|
| class MockAuditProofCallback {
|
| public:
|
| MockAuditProofCallback() : called_(false) {}
|
|
|
| bool called() const { return called_; }
|
| @@ -155,42 +128,25 @@ class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
|
| return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(),
|
| net::NetLogWithSource(),
|
| max_concurrent_queries);
|
| }
|
|
|
| - void QueryLeafIndexAsync(LogDnsClient* log_client,
|
| - base::StringPiece log_domain,
|
| - const char leaf_hash[crypto::kSHA256Length],
|
| - const LogDnsClient::LeafIndexCallback& callback) {
|
| - log_client->QueryLeafIndex(log_domain, leaf_hash, callback);
|
| - }
|
| -
|
| - // Convenience function for calling QueryLeafIndexAsync synchronously.
|
| - void QueryLeafIndex(base::StringPiece log_domain,
|
| - const char leaf_hash[crypto::kSHA256Length],
|
| - MockLeafIndexCallback* callback) {
|
| - std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
|
| - QueryLeafIndexAsync(log_client.get(), log_domain, leaf_hash,
|
| - callback->AsCallback());
|
| - callback->WaitUntilRun();
|
| - }
|
| -
|
| void QueryAuditProofAsync(LogDnsClient* log_client,
|
| - base::StringPiece log_domain,
|
| - uint64_t leaf_index,
|
| + const std::string& log_domain,
|
| + const char leaf_hash[crypto::kSHA256Length],
|
| uint64_t tree_size,
|
| const LogDnsClient::AuditProofCallback& callback) {
|
| - log_client->QueryAuditProof(log_domain, leaf_index, tree_size, callback);
|
| + log_client->QueryAuditProof(log_domain, leaf_hash, tree_size, callback);
|
| }
|
|
|
| // Convenience function for calling QueryAuditProofAsync synchronously.
|
| - void QueryAuditProof(base::StringPiece log_domain,
|
| - uint64_t leaf_index,
|
| + void QueryAuditProof(const std::string& log_domain,
|
| + const char leaf_hash[crypto::kSHA256Length],
|
| uint64_t tree_size,
|
| MockAuditProofCallback* callback) {
|
| std::unique_ptr<LogDnsClient> log_client = CreateLogDnsClient(0);
|
| - QueryAuditProofAsync(log_client.get(), log_domain, leaf_index, tree_size,
|
| + QueryAuditProofAsync(log_client.get(), log_domain, leaf_hash, tree_size,
|
| callback->AsCallback());
|
| callback->WaitUntilRun();
|
| }
|
|
|
| // This will be the NetworkChangeNotifier singleton for the duration of the
|
| @@ -201,198 +157,184 @@ class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> {
|
| base::MessageLoopForIO message_loop_;
|
| // Allows mock DNS sockets to be setup.
|
| MockLogDnsTraffic mock_dns_;
|
| };
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndex) {
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456);
|
| -
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| - ASSERT_TRUE(callback.called());
|
| - EXPECT_THAT(callback.net_error(), IsOk());
|
| - EXPECT_THAT(callback.leaf_index(), Eq(123456u));
|
| -}
|
| -
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsThatLogDomainDoesNotExist) {
|
| - mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
|
| +TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
|
| + mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
|
| net::dns_protocol::kRcodeNXDOMAIN);
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerFailure) {
|
| - mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) {
|
| + mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
|
| net::dns_protocol::kRcodeSERVFAIL);
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsServerRefusal) {
|
| - mock_dns_.ExpectRequestAndErrorResponse(kBase32LeafHashes[0],
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) {
|
| + mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0],
|
| net::dns_protocol::kRcodeREFUSED);
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfContainsNoStrings) {
|
| - mock_dns_.ExpectRequestAndResponse(
|
| - kBase32LeafHashes[0],
|
| - std::vector<base::StringPiece>());
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsNoStrings) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0],
|
| + std::vector<base::StringPiece>());
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfContainsMoreThanOneString) {
|
| - mock_dns_.ExpectRequestAndResponse(
|
| - kBase32LeafHashes[0],
|
| - {"123456", "7"});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexResponseContainsMoreThanOneString) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456", "7"});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfLeafIndexIsNotNumeric) {
|
| - mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"foo"});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo"});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfLeafIndexIsFloatingPoint) {
|
| - mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"123456.0"});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456.0"});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfLeafIndexIsEmpty) {
|
| - mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {""});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {""});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) {
|
| - mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"foo123456"});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"foo123456"});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryLeafIndexReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) {
|
| - mock_dns_.ExpectRequestAndResponse(kBase32LeafHashes[0], {"123456foo"});
|
| + QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) {
|
| + mock_dns_.ExpectRequestAndResponse(kLeafIndexQnames[0], {"123456foo"});
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsEmpty) {
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("", kLeafHashes[0], &callback);
|
| +TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLogDomainIsNull) {
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex(nullptr, kLeafHashes[0], &callback);
|
| +TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsInvalid) {
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", "foo", kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsInvalid) {
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", "foo", &callback);
|
| +TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsEmpty) {
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", "", kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsEmpty) {
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", "", &callback);
|
| +TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLeafHashIsNull) {
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsInvalidArgIfLeafHashIsNull) {
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", nullptr, &callback);
|
| - ASSERT_TRUE(callback.called());
|
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| -}
|
| -
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsSocketError) {
|
| - mock_dns_.ExpectRequestAndSocketError(kBase32LeafHashes[0],
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) {
|
| + mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0],
|
| net::ERR_CONNECTION_REFUSED);
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryLeafIndexReportsTimeout) {
|
| - mock_dns_.ExpectRequestAndTimeout(kBase32LeafHashes[0]);
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) {
|
| + mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]);
|
|
|
| - MockLeafIndexCallback callback;
|
| - QueryLeafIndex("ct.test", kLeafHashes[0], &callback);
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
|
| - EXPECT_THAT(callback.leaf_index(), Eq(0u));
|
| + EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest, QueryAuditProof) {
|
| const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
|
|
|
| + // Expect a leaf index query first, to map the leaf hash to a leaf index.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| // It takes a number of DNS requests to retrieve the entire |audit_proof|
|
| // (see |kMaxProofNodesPerDnsResponse|).
|
| for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
|
| nodes_begin += kMaxProofNodesPerDnsResponse) {
|
| const size_t nodes_end = std::min(
|
| @@ -402,11 +344,11 @@ TEST_P(LogDnsClientTest, QueryAuditProof) {
|
| base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
|
| audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
|
| }
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsOk());
|
| ASSERT_THAT(callback.proof(), NotNull());
|
| EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
|
| // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
|
| @@ -415,10 +357,13 @@ TEST_P(LogDnsClientTest, QueryAuditProof) {
|
| }
|
|
|
| TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
|
| const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
|
|
|
| + // Expect a leaf index query first, to map the leaf hash to a leaf index.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| // Make some of the responses contain fewer proof nodes than they can hold.
|
| mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
|
| audit_proof.begin(),
|
| audit_proof.begin() + 1);
|
| mock_dns_.ExpectAuditProofRequestAndResponse("1.123456.999999.tree.ct.test.",
|
| @@ -436,179 +381,186 @@ TEST_P(LogDnsClientTest, QueryAuditProofHandlesResponsesWithShortAuditPaths) {
|
| mock_dns_.ExpectAuditProofRequestAndResponse("13.123456.999999.tree.ct.test.",
|
| audit_proof.begin() + 13,
|
| audit_proof.end());
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsOk());
|
| ASSERT_THAT(callback.proof(), NotNull());
|
| EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
|
| // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
|
| // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
|
| EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) {
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsThatAuditProofQnameDoesNotExist) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
|
| net::dns_protocol::kRcodeNXDOMAIN);
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsServerFailure) {
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsServerFailureDuringAuditProofRequests) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
|
| net::dns_protocol::kRcodeSERVFAIL);
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsServerRefusal) {
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsServerRefusalDuringAuditProofRequests) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.",
|
| net::dns_protocol::kRcodeREFUSED);
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryAuditProofReportsResponseMalformedIfContainsNoStrings) {
|
| + QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsNoStrings) {
|
| + // Expect a leaf index query first, to map the leaf hash to a leaf index.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| mock_dns_.ExpectRequestAndResponse("0.123456.999999.tree.ct.test.",
|
| std::vector<base::StringPiece>());
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| - QueryAuditProofReportsResponseMalformedIfContainsMoreThanOneString) {
|
| + QueryAuditProofReportsResponseMalformedIfProofNodesResponseContainsMoreThanOneString) {
|
| // The CT-over-DNS draft RFC states that the response will contain "exactly
|
| // one character-string."
|
| const std::vector<std::string> audit_proof = GetSampleAuditProof(10);
|
|
|
| std::string first_chunk_of_proof = std::accumulate(
|
| audit_proof.begin(), audit_proof.begin() + 7, std::string());
|
| std::string second_chunk_of_proof = std::accumulate(
|
| audit_proof.begin() + 7, audit_proof.end(), std::string());
|
|
|
| + // Expect a leaf index query first, to map the leaf hash to a leaf index.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| mock_dns_.ExpectRequestAndResponse(
|
| "0.123456.999999.tree.ct.test.",
|
| {first_chunk_of_proof, second_chunk_of_proof});
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| QueryAuditProofReportsResponseMalformedIfNodeTooShort) {
|
| // node is shorter than a SHA-256 hash (31 vs 32 bytes)
|
| const std::vector<std::string> audit_proof(1, std::string(31, 'a'));
|
|
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectAuditProofRequestAndResponse(
|
| "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) {
|
| // node is longer than a SHA-256 hash (33 vs 32 bytes)
|
| const std::vector<std::string> audit_proof(1, std::string(33, 'a'));
|
|
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectAuditProofRequestAndResponse(
|
| "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) {
|
| const std::vector<std::string> audit_proof;
|
|
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectAuditProofRequestAndResponse(
|
| "0.123456.999999.tree.ct.test.", audit_proof.begin(), audit_proof.end());
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsEmpty) {
|
| - MockAuditProofCallback callback;
|
| - QueryAuditProof("", 123456, 999999, &callback);
|
| - ASSERT_TRUE(callback.called());
|
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.proof(), IsNull());
|
| -}
|
| -
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsInvalidArgIfLogDomainIsNull) {
|
| - MockAuditProofCallback callback;
|
| - QueryAuditProof(nullptr, 123456, 999999, &callback);
|
| - ASSERT_TRUE(callback.called());
|
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| - EXPECT_THAT(callback.proof(), IsNull());
|
| -}
|
| -
|
| TEST_P(LogDnsClientTest,
|
| QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 123456, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| TEST_P(LogDnsClientTest,
|
| QueryAuditProofReportsInvalidArgIfLeafIndexGreaterThanTreeSize) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 999999);
|
| +
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 999999, 123456, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsSocketError) {
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsSocketErrorsDuringAuditProofRequests) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectRequestAndSocketError("0.123456.999999.tree.ct.test.",
|
| net::ERR_CONNECTION_REFUSED);
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, QueryAuditProofReportsTimeout) {
|
| +TEST_P(LogDnsClientTest,
|
| + QueryAuditProofReportsTimeoutsDuringAuditProofRequests) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test.");
|
|
|
| MockAuditProofCallback callback;
|
| - QueryAuditProof("ct.test", 123456, 999999, &callback);
|
| + QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback);
|
| ASSERT_TRUE(callback.called());
|
| EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT));
|
| EXPECT_THAT(callback.proof(), IsNull());
|
| }
|
|
|
| @@ -642,59 +594,81 @@ TEST_P(LogDnsClientTest, IgnoresLatestDnsConfigIfInvalid) {
|
| // Let the DNS config change propogate.
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_THAT(dns_client->GetConfig()->nameservers, Not(IsEmpty()));
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, CanPerformLeafIndexQueriesInParallel) {
|
| - // Test that leaf index queries can be performed in parallel.
|
| - constexpr size_t kNumOfParallelQueries = 3;
|
| - ASSERT_THAT(kNumOfParallelQueries, AllOf(Le(arraysize(kLeafHashes)),
|
| - Le(arraysize(kBase32LeafHashes))))
|
| - << "Not enough test data for this many parallel queries";
|
| -
|
| - std::unique_ptr<LogDnsClient> log_client =
|
| - CreateLogDnsClient(kNumOfParallelQueries);
|
| - MockLeafIndexCallback callbacks[kNumOfParallelQueries];
|
| -
|
| - // Expect multiple queries.
|
| - for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(
|
| - kBase32LeafHashes[i], kLeafIndices[i]);
|
| - }
|
| +// Test that changes to the DNS config after starting a query are adopted and
|
| +// that the query is not disrupted.
|
| +TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigMidQuery) {
|
| + const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
|
|
|
| - // Start the queries.
|
| - for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[i],
|
| - callbacks[i].AsCallback());
|
| - }
|
| + // Expect a leaf index query first, to map the leaf hash to a leaf index.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
|
|
| - // Wait for each query to complete and check its results.
|
| - for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| - MockLeafIndexCallback& callback = callbacks[i];
|
| - callback.WaitUntilRun();
|
| + // It takes a number of DNS requests to retrieve the entire |audit_proof|
|
| + // (see |kMaxProofNodesPerDnsResponse|).
|
| + for (size_t nodes_begin = 0; nodes_begin < audit_proof.size();
|
| + nodes_begin += kMaxProofNodesPerDnsResponse) {
|
| + const size_t nodes_end = std::min(
|
| + nodes_begin + kMaxProofNodesPerDnsResponse, audit_proof.size());
|
|
|
| - SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]");
|
| - ASSERT_TRUE(callback.called());
|
| - EXPECT_THAT(callback.net_error(), IsOk());
|
| - EXPECT_THAT(callback.leaf_index(), Eq(kLeafIndices[i]));
|
| + mock_dns_.ExpectAuditProofRequestAndResponse(
|
| + base::StringPrintf("%zu.123456.999999.tree.ct.test.", nodes_begin),
|
| + audit_proof.begin() + nodes_begin, audit_proof.begin() + nodes_end);
|
| }
|
| +
|
| + std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient();
|
| + net::DnsClient* dns_client = tmp.get();
|
| + LogDnsClient log_client(std::move(tmp), net::NetLogWithSource(), 0);
|
| +
|
| + // Start query.
|
| + MockAuditProofCallback callback;
|
| + QueryAuditProofAsync(&log_client, "ct.test", kLeafHashes[0], 999999,
|
| + callback.AsCallback());
|
| +
|
| + // Get the current DNS config, modify it and broadcast the update.
|
| + net::DnsConfig config(*dns_client->GetConfig());
|
| + ASSERT_NE(123, config.attempts);
|
| + config.attempts = 123;
|
| + mock_dns_.SetDnsConfig(config);
|
| +
|
| + callback.WaitUntilRun();
|
| + // Check that the DNS changes propogated before the query completed.
|
| + EXPECT_EQ(123, dns_client->GetConfig()->attempts);
|
| +
|
| + ASSERT_TRUE(callback.called());
|
| + EXPECT_THAT(callback.net_error(), IsOk());
|
| + ASSERT_THAT(callback.proof(), NotNull());
|
| + EXPECT_THAT(callback.proof()->leaf_index, Eq(123456u));
|
| + // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
|
| + // EXPECT_THAT(callback.proof()->tree_size, Eq(999999));
|
| + EXPECT_THAT(callback.proof()->nodes, Eq(audit_proof));
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, CanPerformAuditProofQueriesInParallel) {
|
| - // Check that 3 audit proof queries can be performed in parallel.
|
| +TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) {
|
| + // Check that 3 queries can be performed in parallel.
|
| constexpr size_t kNumOfParallelQueries = 3;
|
| ASSERT_THAT(kNumOfParallelQueries,
|
| - AllOf(Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes))))
|
| + AllOf(Le(arraysize(kLeafIndexQnames)),
|
| + Le(arraysize(kLeafIndices)), Le(arraysize(kTreeSizes))))
|
| << "Not enough test data for this many parallel queries";
|
|
|
| std::unique_ptr<LogDnsClient> log_client =
|
| CreateLogDnsClient(kNumOfParallelQueries);
|
| MockAuditProofCallback callbacks[kNumOfParallelQueries];
|
|
|
| - // Each query should require one more DNS request than the last.
|
| - // This helps to test that parallel queries do not intefere with each other,
|
| - // e.g. one query causing another to end prematurely.
|
| + // Expect multiple leaf index requests.
|
| + for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(
|
| + kLeafIndexQnames[i], kLeafIndices[i]);
|
| + }
|
| +
|
| + // Make each query require one more audit proof request than the last, by
|
| + // increasing the number of nodes in the audit proof by
|
| + // kMaxProofNodesPerDnsResponse for each query. This helps to test that
|
| + // parallel queries do not intefere with each other, e.g. one query causing
|
| + // another to end prematurely.
|
| std::vector<std::string> audit_proofs[kNumOfParallelQueries];
|
| for (size_t query_i = 0; query_i < kNumOfParallelQueries; ++query_i) {
|
| const size_t dns_requests_required = query_i + 1;
|
| audit_proofs[query_i] = GetSampleAuditProof(dns_requests_required *
|
| kMaxProofNodesPerDnsResponse);
|
| @@ -728,11 +702,11 @@ TEST_P(LogDnsClientTest, CanPerformAuditProofQueriesInParallel) {
|
| }
|
| }
|
|
|
| // Start the queries.
|
| for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", kLeafIndices[i],
|
| + QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[i],
|
| kTreeSizes[i], callbacks[i].AsCallback());
|
| }
|
|
|
| // Wait for each query to complete and check its results.
|
| for (size_t i = 0; i < kNumOfParallelQueries; ++i) {
|
| @@ -748,107 +722,19 @@ TEST_P(LogDnsClientTest, CanPerformAuditProofQueriesInParallel) {
|
| // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]);
|
| EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i]));
|
| }
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, CanPerformLeafIndexAndAuditProofQueriesInParallel) {
|
| - // Check that a leaf index and audit proof query can be performed in parallel.
|
| - constexpr size_t kNumOfParallelQueries = 2;
|
| - std::unique_ptr<LogDnsClient> log_client =
|
| - CreateLogDnsClient(kNumOfParallelQueries);
|
| - MockLeafIndexCallback leaf_index_callback;
|
| - MockAuditProofCallback audit_proof_callback;
|
| - const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
|
| -
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456);
|
| -
|
| - // It should require 3 requests to collect the entire audit proof, as there is
|
| - // only space for 7 nodes per TXT record. One node is 32 bytes long and the
|
| - // TXT RDATA can have a maximum length of 255 bytes (255 / 32).
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
|
| - audit_proof.begin(),
|
| - audit_proof.begin() + 7);
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.",
|
| - audit_proof.begin() + 7,
|
| - audit_proof.begin() + 14);
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
|
| - audit_proof.begin() + 14,
|
| - audit_proof.end());
|
| -
|
| - // Start the queries.
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
|
| - leaf_index_callback.AsCallback());
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
|
| - audit_proof_callback.AsCallback());
|
| -
|
| - // Wait for the queries to complete, then check their results.
|
| - leaf_index_callback.WaitUntilRun();
|
| - audit_proof_callback.WaitUntilRun();
|
| -
|
| - ASSERT_TRUE(leaf_index_callback.called());
|
| - EXPECT_THAT(leaf_index_callback.net_error(), IsOk());
|
| - EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u));
|
| -
|
| - ASSERT_TRUE(audit_proof_callback.called());
|
| - EXPECT_THAT(audit_proof_callback.net_error(), IsOk());
|
| - ASSERT_THAT(audit_proof_callback.proof(), NotNull());
|
| - EXPECT_THAT(audit_proof_callback.proof()->leaf_index, Eq(123456u));
|
| - // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
|
| - // EXPECT_THAT(audit_proof_callback.proof()->tree_size, Eq(999999));
|
| - EXPECT_THAT(audit_proof_callback.proof()->nodes, Eq(audit_proof));
|
| -}
|
| -
|
| -TEST_P(LogDnsClientTest, CanBeThrottledToOneLeafIndexQueryAtATime) {
|
| - // Check that leaf index queries can be rate-limited to one at a time.
|
| - // The second query, initiated while the first is in progress, should fail.
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[0], 123456);
|
| -
|
| - const size_t max_concurrent_queries = 1;
|
| - std::unique_ptr<LogDnsClient> log_client =
|
| - CreateLogDnsClient(max_concurrent_queries);
|
| -
|
| - // Start the queries.
|
| - MockLeafIndexCallback callback1;
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
|
| - callback1.AsCallback());
|
| - MockLeafIndexCallback callback2;
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[1],
|
| - callback2.AsCallback());
|
| -
|
| - callback1.WaitUntilRun();
|
| - callback2.WaitUntilRun();
|
| -
|
| - // Check that the first query succeeded.
|
| - ASSERT_TRUE(callback1.called());
|
| - EXPECT_THAT(callback1.net_error(), IsOk());
|
| - EXPECT_THAT(callback1.leaf_index(), Eq(123456u));
|
| -
|
| - // Check that the second query failed.
|
| - ASSERT_TRUE(callback2.called());
|
| - EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
|
| - EXPECT_THAT(callback2.leaf_index(), Eq(0u));
|
| -
|
| - // Try a third query, which should succeed now that the first is finished.
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(kBase32LeafHashes[2], 666);
|
| -
|
| - MockLeafIndexCallback callback3;
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[2],
|
| - callback3.AsCallback());
|
| -
|
| - callback3.WaitUntilRun();
|
| -
|
| - // Check that the third query succeeded.
|
| - ASSERT_TRUE(callback3.called());
|
| - EXPECT_THAT(callback3.net_error(), IsOk());
|
| - EXPECT_THAT(callback3.leaf_index(), Eq(666u));
|
| -}
|
| -
|
| -TEST_P(LogDnsClientTest, CanBeThrottledToOneAuditProofQueryAtATime) {
|
| - // Check that audit proof queries can be rate-limited to one at a time.
|
| +TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) {
|
| + // Check that queries can be rate-limited to one at a time.
|
| // The second query, initiated while the first is in progress, should fail.
|
| const std::vector<std::string> audit_proof = GetSampleAuditProof(20);
|
|
|
| + // Expect the first query to send leaf index and audit proof requests, but the
|
| + // second should not due to throttling.
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], 123456);
|
| +
|
| // It should require 3 requests to collect the entire audit proof, as there is
|
| // only space for 7 nodes per TXT record. One node is 32 bytes long and the
|
| // TXT RDATA can have a maximum length of 255 bytes (255 / 32).
|
| // Rate limiting should not interfere with these requests.
|
| mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
|
| @@ -859,20 +745,20 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneAuditProofQueryAtATime) {
|
| audit_proof.begin() + 14);
|
| mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
|
| audit_proof.begin() + 14,
|
| audit_proof.end());
|
|
|
| - const size_t max_concurrent_queries = 1;
|
| + const size_t kMaxConcurrentQueries = 1;
|
| std::unique_ptr<LogDnsClient> log_client =
|
| - CreateLogDnsClient(max_concurrent_queries);
|
| + CreateLogDnsClient(kMaxConcurrentQueries);
|
|
|
| // Start the queries.
|
| MockAuditProofCallback callback1;
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
|
| + QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[0], 999999,
|
| callback1.AsCallback());
|
| MockAuditProofCallback callback2;
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
|
| + QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[1], 999999,
|
| callback2.AsCallback());
|
|
|
| callback1.WaitUntilRun();
|
| callback2.WaitUntilRun();
|
|
|
| @@ -889,71 +775,37 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneAuditProofQueryAtATime) {
|
| ASSERT_TRUE(callback2.called());
|
| EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED));
|
| EXPECT_THAT(callback2.proof(), IsNull());
|
|
|
| // Try a third query, which should succeed now that the first is finished.
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("0.123456.999999.tree.ct.test.",
|
| + mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], 666);
|
| + mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.",
|
| audit_proof.begin(),
|
| audit_proof.begin() + 7);
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("7.123456.999999.tree.ct.test.",
|
| + mock_dns_.ExpectAuditProofRequestAndResponse("7.666.999999.tree.ct.test.",
|
| audit_proof.begin() + 7,
|
| audit_proof.begin() + 14);
|
| - mock_dns_.ExpectAuditProofRequestAndResponse("14.123456.999999.tree.ct.test.",
|
| + mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.",
|
| audit_proof.begin() + 14,
|
| audit_proof.end());
|
|
|
| MockAuditProofCallback callback3;
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
|
| + QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[2], 999999,
|
| callback3.AsCallback());
|
|
|
| callback3.WaitUntilRun();
|
|
|
| // Check that the third query succeeded.
|
| ASSERT_TRUE(callback3.called());
|
| EXPECT_THAT(callback3.net_error(), IsOk());
|
| ASSERT_THAT(callback3.proof(), NotNull());
|
| - EXPECT_THAT(callback3.proof()->leaf_index, Eq(123456u));
|
| + EXPECT_THAT(callback3.proof()->leaf_index, Eq(666u));
|
| // TODO(robpercival): Enable this once MerkleAuditProof has tree_size.
|
| // EXPECT_THAT(callback3.proof()->tree_size, Eq(999999));
|
| EXPECT_THAT(callback3.proof()->nodes, Eq(audit_proof));
|
| }
|
|
|
| -TEST_P(LogDnsClientTest, ThrottlingAppliesAcrossQueryTypes) {
|
| - // Check that queries can be rate-limited to one at a time, regardless of the
|
| - // type of query. The second query, initiated while the first is in progress,
|
| - // should fail.
|
| - mock_dns_.ExpectLeafIndexRequestAndResponse(
|
| - "D4S6DSV2J743QJZEQMH4UYHEYK7KRQ5JIQOCPMFUHZVJNFGHXACA.hash.ct.test.",
|
| - 123456);
|
| -
|
| - const size_t max_concurrent_queries = 1;
|
| - std::unique_ptr<LogDnsClient> log_client =
|
| - CreateLogDnsClient(max_concurrent_queries);
|
| -
|
| - // Start the queries.
|
| - MockLeafIndexCallback leaf_index_callback;
|
| - QueryLeafIndexAsync(log_client.get(), "ct.test", kLeafHashes[0],
|
| - leaf_index_callback.AsCallback());
|
| - MockAuditProofCallback audit_proof_callback;
|
| - QueryAuditProofAsync(log_client.get(), "ct.test", 123456, 999999,
|
| - audit_proof_callback.AsCallback());
|
| -
|
| - leaf_index_callback.WaitUntilRun();
|
| - audit_proof_callback.WaitUntilRun();
|
| -
|
| - // Check that the first query succeeded.
|
| - ASSERT_TRUE(leaf_index_callback.called());
|
| - EXPECT_THAT(leaf_index_callback.net_error(), IsOk());
|
| - EXPECT_THAT(leaf_index_callback.leaf_index(), Eq(123456u));
|
| -
|
| - // Check that the second query failed.
|
| - ASSERT_TRUE(audit_proof_callback.called());
|
| - EXPECT_THAT(audit_proof_callback.net_error(),
|
| - IsError(net::ERR_TEMPORARILY_THROTTLED));
|
| - EXPECT_THAT(audit_proof_callback.proof(), IsNull());
|
| -}
|
| -
|
| INSTANTIATE_TEST_CASE_P(ReadMode,
|
| LogDnsClientTest,
|
| ::testing::Values(net::IoMode::ASYNC,
|
| net::IoMode::SYNCHRONOUS));
|
|
|
|
|