| Index: net/cert/internal/cert_issuer_source_collection_unittest.cc
|
| diff --git a/net/cert/internal/cert_issuer_source_collection_unittest.cc b/net/cert/internal/cert_issuer_source_collection_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..23d4120833a2338194226761446f0fdfc4148b78
|
| --- /dev/null
|
| +++ b/net/cert/internal/cert_issuer_source_collection_unittest.cc
|
| @@ -0,0 +1,426 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/cert/internal/cert_issuer_source_collection.h"
|
| +
|
| +//#include "net/cert/internal/cert_issuer_source_static.h"
|
| +#include "base/bind.h"
|
| +#include "net/cert/internal/cert_issuer_source_test_helpers.h"
|
| +#include "net/cert/internal/parsed_certificate.h"
|
| +#include "net/cert/internal/test_helpers.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +
|
| +namespace net {
|
| +
|
| +namespace {
|
| +
|
| +using ::testing::Invoke;
|
| +using ::testing::SaveArg;
|
| +using ::testing::SetArgPointee;
|
| +using ::testing::StrictMock;
|
| +using ::testing::Unused;
|
| +using ::testing::Return;
|
| +using ::testing::_;
|
| +
|
| +// XXX dupe from path_builder_unittest
|
| +::testing::AssertionResult ReadTestPem(const std::string& file_name,
|
| + const std::string& block_name,
|
| + std::string* result) {
|
| + const PemBlockMapping mappings[] = {
|
| + {block_name.c_str(), result},
|
| + };
|
| +
|
| + return ReadTestDataFromPemFile(file_name, mappings);
|
| +}
|
| +
|
| +// XXX dupe from path_builder_unittest
|
| +::testing::AssertionResult ReadTestCert(
|
| + const std::string& file_name,
|
| + scoped_refptr<ParsedCertificate>* result) {
|
| + std::string der;
|
| + ::testing::AssertionResult r = ReadTestPem(
|
| + "net/data/ssl/certificates/" + file_name, "CERTIFICATE", &der);
|
| + if (!r)
|
| + return r;
|
| + *result = ParsedCertificate::CreateFromCertificateCopy(der, {});
|
| + if (!*result)
|
| + return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed";
|
| + return ::testing::AssertionSuccess();
|
| +}
|
| +
|
| +void NotCalled(CertIssuerSource::Request* request) {
|
| + ADD_FAILURE() << "NotCalled was called";
|
| +}
|
| +
|
| +
|
| +class CertIssuerSourceCollectionTest : public ::testing::Test {
|
| + public:
|
| + void SetUp() override {
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert_));
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert2_));
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &cert3_));
|
| + }
|
| + protected:
|
| + scoped_refptr<ParsedCertificate> cert_;
|
| + scoped_refptr<ParsedCertificate> cert2_;
|
| + scoped_refptr<ParsedCertificate> cert3_;
|
| +};
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, EmptyCollection) {
|
| + CertIssuerSourceCollection collection;
|
| + ParsedCertificateList issuers;
|
| + collection.SyncGetIssuersOf(cert_.get(), &issuers);
|
| + EXPECT_TRUE(issuers.empty());
|
| +
|
| + std::unique_ptr<CertIssuerSource::Request> request;
|
| + collection.AsyncGetIssuersOf(cert_.get(), base::Bind(&NotCalled), &request);
|
| + EXPECT_EQ(nullptr, request);
|
| +}
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, SyncNoResults) {
|
| + StrictMock<MockCertIssuerSource> source1;
|
| + StrictMock<MockCertIssuerSource> source2;
|
| + CertIssuerSourceCollection collection;
|
| + collection.AddSource(&source1);
|
| + collection.AddSource(&source2);
|
| +
|
| + ParsedCertificateList issuers;
|
| + EXPECT_CALL(source1, SyncGetIssuersOf(cert_.get(), _));
|
| + EXPECT_CALL(source2, SyncGetIssuersOf(cert_.get(), _));
|
| + collection.SyncGetIssuersOf(cert_.get(), &issuers);
|
| + EXPECT_TRUE(issuers.empty());
|
| +}
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, SyncWithResults) {
|
| + StrictMock<MockCertIssuerSource> source1;
|
| + StrictMock<MockCertIssuerSource> source2;
|
| + CertIssuerSourceCollection collection;
|
| + collection.AddSource(&source1);
|
| + collection.AddSource(&source2);
|
| +
|
| + scoped_refptr<ParsedCertificate> cert2 = cert2_;
|
| + scoped_refptr<ParsedCertificate> cert3 = cert3_;
|
| + ParsedCertificateList issuers;
|
| + EXPECT_CALL(source1, SyncGetIssuersOf(cert_.get(), _))
|
| + .WillOnce(Invoke(
|
| + [cert2](Unused, ParsedCertificateList* out) { out->push_back(cert2); }));
|
| + EXPECT_CALL(source2, SyncGetIssuersOf(cert_.get(), _))
|
| + .WillOnce(Invoke(
|
| + [cert3](Unused, ParsedCertificateList* out) { out->push_back(cert3); }));
|
| + collection.SyncGetIssuersOf(cert_.get(), &issuers);
|
| + EXPECT_EQ(ParsedCertificateList({cert2, cert3}), issuers);
|
| +}
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, AsyncNoAsyncSources) {
|
| + StrictMock<MockCertIssuerSource> source1;
|
| + StrictMock<MockCertIssuerSource> source2;
|
| + CertIssuerSourceCollection collection;
|
| + collection.AddSource(&source1);
|
| + collection.AddSource(&source2);
|
| +
|
| + // When the sub-sources get AsyncGetIssuersOf calls, they don't set the output
|
| + // Request param.
|
| + EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _));
|
| + EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _));
|
| + std::unique_ptr<CertIssuerSource::Request> request;
|
| + collection.AsyncGetIssuersOf(cert_.get(), base::Bind(&NotCalled), &request);
|
| + // The collection should not set it's output Request either.
|
| + EXPECT_EQ(nullptr, request);
|
| +}
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, AsyncReadSubResultsImmediately) {
|
| + StrictMock<MockCertIssuerSource> source1;
|
| + StrictMock<MockCertIssuerSource> source2;
|
| + CertIssuerSourceCollection collection;
|
| + collection.AddSource(&source1);
|
| + collection.AddSource(&source2);
|
| +
|
| +
|
| + // Set up expectations for the sub requests:
|
| +
|
| + CertIssuerSource::IssuerCallback sub_req1_callback;
|
| + // Create a mock CertIssuerSource::Request for source1.
|
| + std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req1_owner(
|
| + new StrictMock<MockCertIssuerSourceRequest>());
|
| + // Keep a raw pointer to the Request...
|
| + StrictMock<MockCertIssuerSourceRequest>* sub_req1 =
|
| + sub_req1_owner.get();
|
| + // Setup helper class to pass ownership of the Request to the
|
| + // CertIssuerSourceCollection when it calls AsyncGetIssuersOf.
|
| + CertIssuerSourceRequestMover sub_req1_mover(std::move(sub_req1_owner));
|
| + EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _))
|
| + .WillOnce(DoAll(
|
| + SaveArg<1>(&sub_req1_callback),
|
| + Invoke(&sub_req1_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| +
|
| + CertIssuerSource::IssuerCallback sub_req2_callback;
|
| + // Create a mock CertIssuerSource::Request for source1.
|
| + std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req2_owner(
|
| + new StrictMock<MockCertIssuerSourceRequest>());
|
| + // Keep a raw pointer to the Request...
|
| + StrictMock<MockCertIssuerSourceRequest>* sub_req2 =
|
| + sub_req2_owner.get();
|
| + // Setup helper class to pass ownership of the Request to the
|
| + // CertIssuerSourceCollection when it calls AsyncGetIssuersOf.
|
| + CertIssuerSourceRequestMover sub_req2_mover(std::move(sub_req1_owner));
|
| + EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _))
|
| + .WillOnce(DoAll(
|
| + SaveArg<1>(&sub_req2_callback),
|
| + Invoke(&sub_req2_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| +
|
| + // Do the collection request:
|
| + std::unique_ptr<CertIssuerSource::Request> collection_request;
|
| + StrictMock<MockIssuerCallback> mock_callback;
|
| + collection.AsyncGetIssuersOf(cert_.get(),
|
| + base::Bind(&MockIssuerCallback::Callback,
|
| + base::Unretained(&mock_callback)),
|
| + &collection_request);
|
| +
|
| + ASSERT_TRUE(collection_request);
|
| + ASSERT_FALSE(sub_req1_callback.is_null());
|
| + ASSERT_FALSE(sub_req2_callback.is_null());
|
| + ::testing::Mock::VerifyAndClearExpectations(&source1);
|
| +
|
| + scoped_refptr<ParsedCertificate> req1cert1;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert1));
|
| + scoped_refptr<ParsedCertificate> req1cert2;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert2));
|
| +
|
| + // source1 will return cert1 and cert2
|
| + EXPECT_CALL(*sub_req1, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert1), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert2), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
|
| + EXPECT_CALL(mock_callback, Callback(collection_request.get()));
|
| +
|
| + sub_req1_callback.Run(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
|
| +
|
| + // Get first results from collection.
|
| + scoped_refptr<ParsedCertificate> result_cert;
|
| + CompletionStatus status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert1, result_cert);
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert2, result_cert);
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::ASYNC, status);
|
| + EXPECT_EQ(nullptr, result_cert);
|
| +
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req1);
|
| +
|
| + scoped_refptr<ParsedCertificate> req2cert1;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert1));
|
| + scoped_refptr<ParsedCertificate> req2cert2;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert2));
|
| +
|
| + // source2 will return some certs, and signal completion.
|
| + EXPECT_CALL(*sub_req2, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req2cert1), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req2cert2), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC)));
|
| + EXPECT_CALL(mock_callback, Callback(collection_request.get()));
|
| +
|
| + sub_req2_callback.Run(sub_req2);
|
| + ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
|
| +
|
| + // Get second set of results from collection.
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req2cert1, result_cert);
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req2cert2, result_cert);
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::ASYNC, status);
|
| + EXPECT_EQ(nullptr, result_cert);
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req2);
|
| +
|
| +
|
| + scoped_refptr<ParsedCertificate> req1cert3;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert3));
|
| + scoped_refptr<ParsedCertificate> req1cert4;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert4));
|
| +
|
| + // source1 will return cert3 and cert4 and signal completion.
|
| + EXPECT_CALL(*sub_req1, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert3), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert4), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC)));
|
| + EXPECT_CALL(mock_callback, Callback(collection_request.get()));
|
| +
|
| + sub_req1_callback.Run(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
|
| +
|
| + // Finally get the results from the CertIssuerSourceCollection.
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert3, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert4, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_FALSE(result_cert);
|
| +}
|
| +
|
| +
|
| +TEST_F(CertIssuerSourceCollectionTest, AsyncFoo) {
|
| + StrictMock<MockCertIssuerSource> source1;
|
| + StrictMock<MockCertIssuerSource> source2;
|
| + CertIssuerSourceCollection collection;
|
| + collection.AddSource(&source1);
|
| + collection.AddSource(&source2);
|
| +
|
| +
|
| + // Set up expectations for the sub requests:
|
| +
|
| + CertIssuerSource::IssuerCallback sub_req1_callback;
|
| + // Create a mock CertIssuerSource::Request for source1.
|
| + std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req1_owner(
|
| + new StrictMock<MockCertIssuerSourceRequest>());
|
| + // Keep a raw pointer to the Request...
|
| + StrictMock<MockCertIssuerSourceRequest>* sub_req1 =
|
| + sub_req1_owner.get();
|
| + // Setup helper class to pass ownership of the Request to the
|
| + // CertIssuerSourceCollection when it calls AsyncGetIssuersOf.
|
| + CertIssuerSourceRequestMover sub_req1_mover(std::move(sub_req1_owner));
|
| + EXPECT_CALL(source1, AsyncGetIssuersOf(_, _, _))
|
| + .WillOnce(DoAll(
|
| + SaveArg<1>(&sub_req1_callback),
|
| + Invoke(&sub_req1_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| +
|
| + CertIssuerSource::IssuerCallback sub_req2_callback;
|
| + // Create a mock CertIssuerSource::Request for source1.
|
| + std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>> sub_req2_owner(
|
| + new StrictMock<MockCertIssuerSourceRequest>());
|
| + // Keep a raw pointer to the Request...
|
| + StrictMock<MockCertIssuerSourceRequest>* sub_req2 =
|
| + sub_req2_owner.get();
|
| + // Setup helper class to pass ownership of the Request to the
|
| + // CertIssuerSourceCollection when it calls AsyncGetIssuersOf.
|
| + CertIssuerSourceRequestMover sub_req2_mover(std::move(sub_req1_owner));
|
| + EXPECT_CALL(source2, AsyncGetIssuersOf(_, _, _))
|
| + .WillOnce(DoAll(
|
| + SaveArg<1>(&sub_req2_callback),
|
| + Invoke(&sub_req2_mover, &CertIssuerSourceRequestMover::MoveIt)));
|
| +
|
| + // Do the collection request:
|
| + std::unique_ptr<CertIssuerSource::Request> collection_request;
|
| + StrictMock<MockIssuerCallback> mock_callback;
|
| + collection.AsyncGetIssuersOf(cert_.get(),
|
| + base::Bind(&MockIssuerCallback::Callback,
|
| + base::Unretained(&mock_callback)),
|
| + &collection_request);
|
| +
|
| + ASSERT_TRUE(collection_request);
|
| + ASSERT_FALSE(sub_req1_callback.is_null());
|
| + ASSERT_FALSE(sub_req2_callback.is_null());
|
| + ::testing::Mock::VerifyAndClearExpectations(&source1);
|
| +
|
| + scoped_refptr<ParsedCertificate> req1cert1;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert1));
|
| + scoped_refptr<ParsedCertificate> req1cert2;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert2));
|
| +
|
| + // source1 will return cert1 and cert2
|
| + EXPECT_CALL(*sub_req1, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert1), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert2), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
|
| + // The collection callback should occur as soon as any results are
|
| + // available. Don't get the results from it yet.
|
| + EXPECT_CALL(mock_callback, Callback(collection_request.get()));
|
| +
|
| + sub_req1_callback.Run(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
|
| +
|
| + scoped_refptr<ParsedCertificate> req2cert1;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert1));
|
| + scoped_refptr<ParsedCertificate> req2cert2;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req2cert2));
|
| +
|
| + // source2 will return some certs, and signal completion.
|
| + EXPECT_CALL(*sub_req2, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req2cert1), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req2cert2), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC)));
|
| +
|
| + sub_req2_callback.Run(sub_req2);
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req2);
|
| +
|
| + scoped_refptr<ParsedCertificate> req1cert3;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert3));
|
| + scoped_refptr<ParsedCertificate> req1cert4;
|
| + ASSERT_TRUE(ReadTestCert("ok_cert.pem", &req1cert4));
|
| +
|
| + // source1 will return cert3 and cert4
|
| + EXPECT_CALL(*sub_req1, GetNext(_))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert3), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(req1cert4), Return(CompletionStatus::SYNC)))
|
| + .WillOnce(
|
| + DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::SYNC)));
|
| +
|
| + sub_req1_callback.Run(sub_req1);
|
| + ::testing::Mock::VerifyAndClearExpectations(sub_req1);
|
| +
|
| + // Finally get the results from the CertIssuerSourceCollection.
|
| + scoped_refptr<ParsedCertificate> result_cert;
|
| + CompletionStatus status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert1, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert2, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req2cert1, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req2cert2, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert3, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_EQ(req1cert4, result_cert);
|
| +
|
| + status = collection_request->GetNext(&result_cert);
|
| + EXPECT_EQ(CompletionStatus::SYNC, status);
|
| + EXPECT_FALSE(result_cert);
|
| +}
|
| +
|
| +// XXX more tests
|
| +//
|
| +} // namespace
|
| +
|
| +} // namespace net
|
|
|