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 |