Chromium Code Reviews| 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 5bf0281ed44c809d4378c3e200f881de68c75169..8530b0f22d4e9d28b9c9330dff25c77a88cb9df7 100644 |
| --- a/components/certificate_transparency/log_dns_client_unittest.cc |
| +++ b/components/certificate_transparency/log_dns_client_unittest.cc |
| @@ -13,10 +13,11 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| +#include "base/test/test_timeouts.h" |
| #include "components/certificate_transparency/mock_log_dns_traffic.h" |
| #include "crypto/sha2.h" |
| #include "net/base/net_errors.h" |
| #include "net/cert/merkle_audit_proof.h" |
| #include "net/cert/signed_certificate_timestamp.h" |
| @@ -68,10 +69,13 @@ const uint64_t kTreeSizes[] = {100, 10000, 1000000}; |
| // is a SHA-256 hash (32 bytes), i.e. (255 / 32) == 7. |
| // This means audit proofs consisting of more than 7 nodes require multiple DNS |
| // requests to retrieve. |
| const size_t kMaxProofNodesPerDnsResponse = 7; |
| +// Returns an example Merkle audit proof containing |length| nodes. |
| +// The proof cannot be used for cryptographic purposes; it is merely a |
| +// placeholder. |
| std::vector<std::string> GetSampleAuditProof(size_t length) { |
| std::vector<std::string> audit_proof(length); |
| // Makes each node of the audit proof different, so that tests are able to |
| // confirm that the audit proof is reconstructed in the correct order. |
| for (size_t i = 0; i < length; ++i) { |
| @@ -84,37 +88,64 @@ std::vector<std::string> GetSampleAuditProof(size_t length) { |
| } |
| return audit_proof; |
| } |
| +// MockAuditProofCallback can be used as an AuditProofCallback. |
| +// It will record the arguments it is invoked with and provides a helpful |
| +// method for pumping the message loop until it is invoked. |
| class MockAuditProofCallback { |
| public: |
| MockAuditProofCallback() : called_(false) {} |
| bool called() const { return called_; } |
| - int net_error() const { return net_error_; } |
| + net::Error result() const { return result_; } |
| const net::ct::MerkleAuditProof* proof() const { return proof_.get(); } |
| - void Run(int net_error, std::unique_ptr<net::ct::MerkleAuditProof> proof) { |
| - EXPECT_TRUE(!called_) << "Callback invoked more than once"; |
| - called_ = true; |
| - net_error_ = net_error; |
| - proof_ = std::move(proof); |
| - run_loop_.Quit(); |
| - } |
| - |
| + // Get this callback as an AuditProofCallback. |
| LogDnsClient::AuditProofCallback AsCallback() { |
| return base::Bind(&MockAuditProofCallback::Run, base::Unretained(this)); |
| } |
| - void WaitUntilRun() { run_loop_.Run(); } |
| + // Wait until either the callback is invoked or the message loop goes idle |
| + // (after a specified |timeout|). Returns immediately if the callback has |
| + // already been invoked. |
| + void WaitUntilRun(base::TimeDelta timeout) { |
| + if (called_) { |
| + return; |
| + } |
| + |
| + // Pump the message loop until the the callback is invoked, which quits the |
| + // RunLoop, or a timeout expires and the message loop goes idle. |
| + run_loop_.reset(new base::RunLoop()); |
| + base::Closure quit_closure = run_loop_->QuitWhenIdleClosure(); |
| + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, |
| + quit_closure, timeout); |
| + run_loop_->Run(); |
| + run_loop_.reset(); |
| + } |
| private: |
| + void Run(net::Error result, |
| + std::unique_ptr<net::ct::MerkleAuditProof> proof) { |
| + EXPECT_FALSE(called_) << "Callback invoked more than once"; |
| + called_ = true; |
| + result_ = result; |
| + proof_ = std::move(proof); |
| + if (run_loop_) { |
| + run_loop_->Quit(); |
| + } |
| + } |
| + |
| + // True if the callback has been invoked. |
| bool called_; |
| - int net_error_; |
| + // The arguments that the callback was invoked with. |
| + net::Error result_; |
| std::unique_ptr<net::ct::MerkleAuditProof> proof_; |
| - base::RunLoop run_loop_; |
| + // The RunLoop currently being used to pump the message loop, as a means to |
| + // execute this callback. |
| + std::unique_ptr<base::RunLoop> run_loop_; |
| }; |
| class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { |
| protected: |
| LogDnsClientTest() |
| @@ -128,27 +159,29 @@ class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { |
| return base::MakeUnique<LogDnsClient>(mock_dns_.CreateDnsClient(), |
| net::NetLogWithSource(), |
| kMaxConcurrentQueries); |
| } |
| - void QueryAuditProofAsync(LogDnsClient* log_client, |
| - 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_hash, tree_size, callback); |
| - } |
| - |
| - // Convenience function for calling QueryAuditProofAsync synchronously. |
| - void QueryAuditProof(const std::string& log_domain, |
| - const char leaf_hash[crypto::kSHA256Length], |
| - uint64_t tree_size, |
| - MockAuditProofCallback* callback) { |
| + // Convenience function for calling QueryAuditProof synchronously. |
| + net::Error 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_hash, tree_size, |
| - callback->AsCallback()); |
| - callback->WaitUntilRun(); |
| + net::Error result = log_client->QueryAuditProof( |
| + log_domain, leaf_hash, tree_size, callback->AsCallback()); |
| + |
| + if (result == net::ERR_IO_PENDING) { |
| + callback->WaitUntilRun(TestTimeouts::action_max_timeout()); |
| + } else { |
| + // The callback isn't expected to be invoked, but pump the message loop |
| + // anyway to confirm that it indeed isn't run. Give up as soon as the |
| + // message loop is empty (zero timeout). |
| + callback->WaitUntilRun(base::TimeDelta()); |
| + } |
|
Ryan Sleevi
2016/10/03 23:38:47
This (the else condition) is really hard to wrap m
Rob Percival
2016/10/04 18:35:40
Without it, tests wouldn't detect when a callback
|
| + |
| + return result; |
| } |
| // This will be the NetworkChangeNotifier singleton for the duration of the |
| // test. It is accessed statically by LogDnsClient. |
| std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| @@ -162,147 +195,165 @@ class LogDnsClientTest : public ::testing::TestWithParam<net::IoMode> { |
| TEST_P(LogDnsClientTest, QueryAuditProofReportsThatLogDomainDoesNotExist) { |
| mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], |
| net::dns_protocol::kRcodeNXDOMAIN); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsServerFailuresDuringLeafIndexRequests) { |
| mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], |
| net::dns_protocol::kRcodeSERVFAIL); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsServerRefusalsDuringLeafIndexRequests) { |
| mock_dns_.ExpectRequestAndErrorResponse(kLeafIndexQnames[0], |
| net::dns_protocol::kRcodeREFUSED); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsMalformedResponseIfLeafIndexIsNotNumeric) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "foo"); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsMalformedResponseIfLeafIndexIsFloatingPoint) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456.0"); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsMalformedResponseIfLeafIndexIsEmpty) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], ""); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericPrefix) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "foo123456"); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsMalformedResponseIfLeafIndexHasNonNumericSuffix) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456foo"); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| 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.proof(), IsNull()); |
| + ASSERT_THAT(QueryAuditProof("", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_INVALID_ARGUMENT)); |
| + ASSERT_FALSE(callback.called()); |
| } |
| 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.proof(), IsNull()); |
| + ASSERT_THAT(QueryAuditProof("ct.test", "foo", kTreeSizes[0], &callback), |
| + IsError(net::ERR_INVALID_ARGUMENT)); |
| + ASSERT_FALSE(callback.called()); |
| } |
| 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.proof(), IsNull()); |
| + ASSERT_THAT(QueryAuditProof("ct.test", "", kTreeSizes[0], &callback), |
| + IsError(net::ERR_INVALID_ARGUMENT)); |
| + ASSERT_FALSE(callback.called()); |
| } |
| 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.proof(), IsNull()); |
| + ASSERT_THAT(QueryAuditProof("ct.test", nullptr, kTreeSizes[0], &callback), |
| + IsError(net::ERR_INVALID_ARGUMENT)); |
| + ASSERT_FALSE(callback.called()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsSocketErrorsDuringLeafIndexRequests) { |
| mock_dns_.ExpectRequestAndSocketError(kLeafIndexQnames[0], |
| net::ERR_CONNECTION_REFUSED); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_CONNECTION_REFUSED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsTimeoutsDuringLeafIndexRequests) { |
| mock_dns_.ExpectRequestAndTimeout(kLeafIndexQnames[0]); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback); |
| + ASSERT_THAT( |
| + QueryAuditProof("ct.test", kLeafHashes[0], kTreeSizes[0], &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| + |
| + callback.WaitUntilRun(TestTimeouts::action_max_timeout()); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_TIMED_OUT)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, QueryAuditProof) { |
| const std::vector<std::string> audit_proof = GetSampleAuditProof(20); |
| @@ -321,13 +372,14 @@ 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsOk()); |
| + EXPECT_THAT(callback.result(), 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)); |
| @@ -358,13 +410,14 @@ 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsOk()); |
| + EXPECT_THAT(callback.result(), 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)); |
| @@ -375,39 +428,42 @@ TEST_P(LogDnsClientTest, |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456"); |
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", |
| net::dns_protocol::kRcodeNXDOMAIN); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_NAME_NOT_RESOLVED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| - QueryAuditProofReportsServerFailureDuringAuditProofRequests) { |
| + QueryAuditProofReportsServerFailuresDuringAuditProofRequests) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456"); |
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", |
| net::dns_protocol::kRcodeSERVFAIL); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| - QueryAuditProofReportsServerRefusalDuringAuditProofRequests) { |
| + QueryAuditProofReportsServerRefusalsDuringAuditProofRequests) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456"); |
| mock_dns_.ExpectRequestAndErrorResponse("0.123456.999999.tree.ct.test.", |
| net::dns_protocol::kRcodeREFUSED); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_SERVER_FAILED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsResponseMalformedIfNodeTooShort) { |
| @@ -417,13 +473,14 @@ TEST_P(LogDnsClientTest, |
| 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), 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) |
| @@ -432,13 +489,14 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfNodeTooLong) { |
| 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) { |
| const std::vector<std::string> audit_proof; |
| @@ -446,60 +504,67 @@ TEST_P(LogDnsClientTest, QueryAuditProofReportsResponseMalformedIfEmpty) { |
| 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_MALFORMED_RESPONSE)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsInvalidArgIfLeafIndexEqualToTreeSize) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456"); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| + EXPECT_THAT(callback.result(), 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", kLeafHashes[0], 123456, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 123456, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_INVALID_ARGUMENT)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_INVALID_ARGUMENT)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| 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", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_CONNECTION_REFUSED)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_CONNECTION_REFUSED)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, |
| QueryAuditProofReportsTimeoutsDuringAuditProofRequests) { |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[0], "123456"); |
| mock_dns_.ExpectRequestAndTimeout("0.123456.999999.tree.ct.test."); |
| MockAuditProofCallback callback; |
| - QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback); |
| + ASSERT_THAT(QueryAuditProof("ct.test", kLeafHashes[0], 999999, &callback), |
| + IsError(net::ERR_IO_PENDING)); |
| + |
| + callback.WaitUntilRun(TestTimeouts::action_max_timeout()); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsError(net::ERR_DNS_TIMED_OUT)); |
| + EXPECT_THAT(callback.result(), IsError(net::ERR_DNS_TIMED_OUT)); |
| EXPECT_THAT(callback.proof(), IsNull()); |
| } |
| TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigIfValid) { |
| std::unique_ptr<net::DnsClient> tmp = mock_dns_.CreateDnsClient(); |
| @@ -557,25 +622,26 @@ TEST_P(LogDnsClientTest, AdoptsLatestDnsConfigMidQuery) { |
| 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()); |
| + ASSERT_THAT(log_client.QueryAuditProof("ct.test", kLeafHashes[0], 999999, |
| + callback.AsCallback()), |
| + IsError(net::ERR_IO_PENDING)); |
| // 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(); |
| + callback.WaitUntilRun(TestTimeouts::action_max_timeout()); |
| // 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()); |
| + EXPECT_THAT(callback.result(), 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)); |
| @@ -639,22 +705,25 @@ TEST_P(LogDnsClientTest, CanPerformQueriesInParallel) { |
| } |
| } |
| // Start the queries. |
| for (size_t i = 0; i < kNumOfParallelQueries; ++i) { |
| - QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[i], |
| - kTreeSizes[i], callbacks[i].AsCallback()); |
| + ASSERT_THAT( |
| + log_client->QueryAuditProof("ct.test", kLeafHashes[i], kTreeSizes[i], |
| + callbacks[i].AsCallback()), |
| + IsError(net::ERR_IO_PENDING)) |
| + << "query #" << i; |
| } |
| // Wait for each query to complete and check its results. |
| for (size_t i = 0; i < kNumOfParallelQueries; ++i) { |
| MockAuditProofCallback& callback = callbacks[i]; |
| - callbacks[i].WaitUntilRun(); |
| + callbacks[i].WaitUntilRun(TestTimeouts::action_max_timeout()); |
| SCOPED_TRACE(testing::Message() << "callbacks[" << i << "]"); |
| ASSERT_TRUE(callback.called()); |
| - EXPECT_THAT(callback.net_error(), IsOk()); |
| + EXPECT_THAT(callback.result(), IsOk()); |
| ASSERT_THAT(callback.proof(), NotNull()); |
| EXPECT_THAT(callback.proof()->leaf_index, Eq(kLeafIndices[i])); |
| // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. |
| // EXPECT_THAT(callback.proof()->tree_size, kTreeSizes[i]); |
| EXPECT_THAT(callback.proof()->nodes, Eq(audit_proofs[i])); |
| @@ -686,34 +755,34 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) { |
| const size_t kMaxConcurrentQueries = 1; |
| std::unique_ptr<LogDnsClient> log_client = |
| CreateLogDnsClient(kMaxConcurrentQueries); |
| - // Start the queries. |
| + // Try to start the queries. |
| MockAuditProofCallback callback1; |
| - QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[0], 999999, |
| - callback1.AsCallback()); |
| + ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[0], 999999, |
| + callback1.AsCallback()), |
| + IsError(net::ERR_IO_PENDING)); |
| + |
| MockAuditProofCallback callback2; |
| - QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[1], 999999, |
| - callback2.AsCallback()); |
| - |
| - callback1.WaitUntilRun(); |
| - callback2.WaitUntilRun(); |
| + ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[1], 999999, |
| + callback2.AsCallback()), |
| + IsError(net::ERR_TEMPORARILY_THROTTLED)); |
| // Check that the first query succeeded. |
| + callback1.WaitUntilRun(TestTimeouts::action_max_timeout()); |
| ASSERT_TRUE(callback1.called()); |
| - EXPECT_THAT(callback1.net_error(), IsOk()); |
| + EXPECT_THAT(callback1.result(), IsOk()); |
| ASSERT_THAT(callback1.proof(), NotNull()); |
| EXPECT_THAT(callback1.proof()->leaf_index, Eq(123456u)); |
| // TODO(robpercival): Enable this once MerkleAuditProof has tree_size. |
| // EXPECT_THAT(callback1.proof()->tree_size, Eq(999999)); |
| EXPECT_THAT(callback1.proof()->nodes, Eq(audit_proof)); |
| - // Check that the second query failed. |
| - ASSERT_TRUE(callback2.called()); |
| - EXPECT_THAT(callback2.net_error(), IsError(net::ERR_TEMPORARILY_THROTTLED)); |
| - EXPECT_THAT(callback2.proof(), IsNull()); |
| + // This callback shouldn't run, so don't wait much longer for it. |
| + callback2.WaitUntilRun(TestTimeouts::tiny_timeout()); |
|
Ryan Sleevi
2016/10/03 23:38:47
Why do you do tiny_timeout here, but a 0 timeout i
Rob Percival
2016/10/04 18:35:40
Good point, this should be the same as in the othe
|
| + ASSERT_FALSE(callback2.called()); |
| // Try a third query, which should succeed now that the first is finished. |
| mock_dns_.ExpectLeafIndexRequestAndResponse(kLeafIndexQnames[2], "666"); |
| mock_dns_.ExpectAuditProofRequestAndResponse("0.666.999999.tree.ct.test.", |
| audit_proof.begin(), |
| @@ -724,18 +793,18 @@ TEST_P(LogDnsClientTest, CanBeThrottledToOneQueryAtATime) { |
| mock_dns_.ExpectAuditProofRequestAndResponse("14.666.999999.tree.ct.test.", |
| audit_proof.begin() + 14, |
| audit_proof.end()); |
| MockAuditProofCallback callback3; |
| - QueryAuditProofAsync(log_client.get(), "ct.test", kLeafHashes[2], 999999, |
| - callback3.AsCallback()); |
| - |
| - callback3.WaitUntilRun(); |
| + ASSERT_THAT(log_client->QueryAuditProof("ct.test", kLeafHashes[2], 999999, |
| + callback3.AsCallback()), |
| + IsError(net::ERR_IO_PENDING)); |
| // Check that the third query succeeded. |
| + callback3.WaitUntilRun(TestTimeouts::action_max_timeout()); |
| ASSERT_TRUE(callback3.called()); |
| - EXPECT_THAT(callback3.net_error(), IsOk()); |
| + EXPECT_THAT(callback3.result(), IsOk()); |
| ASSERT_THAT(callback3.proof(), NotNull()); |
| 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)); |