Index: net/cert/internal/cert_issuer_source_aia_unittest.cc |
diff --git a/net/cert/internal/cert_issuer_source_aia_unittest.cc b/net/cert/internal/cert_issuer_source_aia_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7d62bbc9c9e41bbe5d7549da12fb2236bee56a85 |
--- /dev/null |
+++ b/net/cert/internal/cert_issuer_source_aia_unittest.cc |
@@ -0,0 +1,918 @@ |
+// 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_aia.h" |
+ |
+#include "base/bind.h" |
+#include "net/cert/internal/parsed_certificate.h" |
+#include "net/cert/internal/test_helpers.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "url/gurl.h" |
+ |
+namespace net { |
+ |
+namespace { |
+ |
+using ::testing::Mock; |
+using ::testing::StrictMock; |
+ |
+::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); |
+} |
+ |
+::testing::AssertionResult ReadTestCert( |
+ const std::string& file_name, |
+ scoped_refptr<ParsedCertificate>* result) { |
+ std::string der; |
+ ::testing::AssertionResult r = |
+ ReadTestPem("net/data/cert_issuer_source_aia_unittest/" + file_name, |
+ "CERTIFICATE", &der); |
+ if (!r) |
+ return r; |
+ *result = ParsedCertificate::CreateFromCertificateCopy(der); |
+ if (!*result) |
+ return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed"; |
+ return ::testing::AssertionSuccess(); |
+} |
+ |
+std::vector<uint8_t> CertDataVector(const ParsedCertificate* cert) { |
+ std::vector<uint8_t> data( |
+ cert->der_cert().UnsafeData(), |
+ cert->der_cert().UnsafeData() + cert->der_cert().Length()); |
+ return data; |
+} |
+ |
+class RequestManager { |
eroman
2016/06/04 01:08:48
Please add a comment for this class.
mattm
2016/06/04 03:24:08
Done.
|
+ public: |
+ class Request : public CertNetFetcher::Request { |
+ public: |
+ Request(RequestManager* manager, |
+ const CertNetFetcher::FetchCallback& callback) |
+ : manager_(manager), callback_(callback) {} |
+ ~Request() override { manager_->RequestWasDestroyed(); } |
+ |
+ CertNetFetcher::FetchCallback get_callback() const { return callback_; } |
+ |
+ private: |
+ RequestManager* manager_; |
+ CertNetFetcher::FetchCallback callback_; |
+ }; |
+ |
+ ~RequestManager() { CHECK_EQ(nullptr, request_); } |
eroman
2016/06/04 01:08:48
ASSERT_FALSE ?
mattm
2016/06/04 03:24:08
If the request is still alive it'll try to access
|
+ |
+ std::unique_ptr<Request> CreateRequest( |
+ const CertNetFetcher::FetchCallback& callback) { |
+ CHECK_EQ(nullptr, request_); |
eroman
2016/06/04 01:08:47
EXPECT_FALSE() ?
mattm
2016/06/04 03:24:08
Done.
|
+ std::unique_ptr<Request> request(new Request(this, callback)); |
+ request_ = request.get(); |
+ return request; |
+ } |
+ |
+ bool is_request_alive() const { return request_; } |
+ |
+ CertNetFetcher::FetchCallback get_callback() const { |
+ CHECK(is_request_alive()); |
+ return request_->get_callback(); |
+ } |
+ |
+ private: |
+ void RequestWasDestroyed() { |
+ CHECK_NE(nullptr, request_); |
+ request_ = nullptr; |
+ } |
+ |
+ Request* request_; |
+}; |
+ |
+// MockCertNetFetcherImpl is an implementation of CertNetFetcher for testing. |
+class MockCertNetFetcherImpl : public CertNetFetcher { |
+ public: |
+ MockCertNetFetcherImpl() = default; |
+ ~MockCertNetFetcherImpl() override = default; |
+ |
+ RequestManager* GetRequestManagerForURL(const GURL& url) { |
+ auto it = request_map_.find(url); |
+ if (it == request_map_.end()) |
+ return nullptr; |
+ return it->second.get(); |
+ } |
+ |
+ WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCaIssuers( |
+ const GURL& url, |
+ int timeout_milliseconds, |
+ int max_response_bytes, |
+ const FetchCallback& callback) override { |
+ CHECK(request_map_.find(url) == request_map_.end()); |
eroman
2016/06/04 01:08:48
I think the ASSERT_* / EXPECT_* stuff is preferabl
mattm
2016/06/04 03:24:08
Done.
|
+ |
+ std::unique_ptr<RequestManager> request_manager(new RequestManager()); |
+ |
+ std::unique_ptr<Request> request = request_manager->CreateRequest(callback); |
+ |
+ request_map_[url] = std::move(request_manager); |
+ |
+ return request; |
+ } |
+ |
+ WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCrl( |
+ const GURL& url, |
+ int timeout_milliseconds, |
+ int max_response_bytes, |
+ const FetchCallback& callback) override { |
+ NOTREACHED(); |
+ return nullptr; |
+ } |
+ |
+ WARN_UNUSED_RESULT std::unique_ptr<Request> FetchOcsp( |
+ const GURL& url, |
+ int timeout_milliseconds, |
+ int max_response_bytes, |
+ const FetchCallback& callback) override { |
+ NOTREACHED(); |
+ return nullptr; |
+ } |
+ |
+ private: |
+ // std::map<GURL, RequestImpl*> request_map_; |
eroman
2016/06/04 01:08:48
uncomment or delete.
mattm
2016/06/04 03:24:08
Done.
|
+ std::map<GURL, std::unique_ptr<RequestManager>> request_map_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MockCertNetFetcherImpl); |
+}; |
+ |
+class MockIssuerCallback { |
+ public: |
+ MOCK_METHOD1(Callback, void(CertIssuerSource::Request*)); |
+}; |
+ |
+void NotCalled(CertIssuerSource::Request* request) { |
+ ADD_FAILURE() << "NotCalled was called"; |
+} |
+ |
+// CertIssuerSourceAia does not return results for SyncGetIssuersOf. |
+TEST(CertIssuerSourceAiaUnittest, NoSyncResults) { |
eroman
2016/06/04 01:08:47
nit: Rather than suffix of Unittest --> suffix of
mattm
2016/06/04 03:24:08
Done.
|
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::vector<scoped_refptr<ParsedCertificate>> issuers; |
+ aia_source.SyncGetIssuersOf(cert.get(), &issuers); |
+ EXPECT_EQ(0U, issuers.size()); |
+} |
+ |
+// If the AuthorityInfoAccess extension is not present, AsyncGetIssuersOf should |
+// synchronously indicate no results. |
+TEST(CertIssuerSourceAiaUnittest, NoAia) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_no_aia.pem", &cert)); |
+ |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request); |
+ EXPECT_EQ(nullptr, request); |
+} |
+ |
+// If the AuthorityInfoAccess extension only contains non-http URIs, |
+// AsyncGetIssuersOf should create a Request object. The URL scheme check is |
+// part of the specific CertNetFetcher implementation, this tests that we handle |
+// ERR_DISALLOWED_URL_SCHEME properly. If FetchCaIssuers is modified to fail |
+// synchronously in that case, this test will be more interesting. |
+TEST(CertIssuerSourceAiaUnittest, FileAia) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_file_aia.pem", &cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ // CertNetFetcher rejects the URL scheme. |
+ req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME, |
+ std::vector<uint8_t>()); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // No results. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// If the AuthorityInfoAccess extension contains an invalid URL, |
+// AsyncGetIssuersOf should synchronously indicate no results. |
+TEST(CertIssuerSourceAiaUnittest, OneInvalidURL) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_invalid_url_aia.pem", &cert)); |
+ |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request); |
+ EXPECT_EQ(nullptr, request); |
+} |
+ |
+// AuthorityInfoAccess with a single HTTP url pointing to a single DER cert. |
+TEST(CertIssuerSourceAiaUnittest, OneAia) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ EXPECT_TRUE(req_manager->is_request_alive()); |
+ cert_source_request.reset(); |
+ EXPECT_FALSE(req_manager->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with two URIs, one a FILE, the other a HTTP. |
+// Simulate a ERR_DISALLOWED_URL_SCHEME for the file URL. If FetchCaIssuers is |
+// modified to synchronously reject disallowed schemes, this test will be more |
+// interesting. |
+TEST(CertIssuerSourceAiaUnittest, OneFileOneHttpAia) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_file_and_http_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Request for file URL completes with disallowed scheme failure. Callback is |
+ // NOT called. |
+ req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME, |
+ std::vector<uint8_t>()); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Request for I2.foo completes. Callback should be called now. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager2->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ EXPECT_TRUE(req_manager2->is_request_alive()); |
+ cert_source_request.reset(); |
+ EXPECT_FALSE(req_manager2->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with two URIs, one is invalid, the other HTTP. |
+TEST(CertIssuerSourceAiaUnittest, OneInvalidOneHttpAia) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_invalid_and_http_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ EXPECT_TRUE(req_manager->is_request_alive()); |
+ cert_source_request.reset(); |
+ EXPECT_FALSE(req_manager->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert. |
+// One request completes, results are retrieved, then the next request completes |
+// and the results are retrieved. |
+TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeries) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert2; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Request for I.cer completes first. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Results are retrieved before the other request completes. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ // The other http request is still pending, status should be ASYNC to signify |
+ // the need to wait for another callback. |
+ ASSERT_EQ(CompletionStatus::ASYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ // Request for I2.foo completes. |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager2->get_callback().Run(OK, |
+ CertDataVector(intermediate_cert2.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Results from the second http request are retrieved. |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert()); |
+ |
+ // No more results. |
+ status = cert_source_request->GetNext(&result_cert); |
+ ASSERT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ EXPECT_TRUE(req_manager->is_request_alive()); |
+ EXPECT_TRUE(req_manager2->is_request_alive()); |
+ cert_source_request.reset(); |
+ EXPECT_FALSE(req_manager->is_request_alive()); |
+ EXPECT_FALSE(req_manager2->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert. |
+// Both HTTP requests complete before the results are retrieved from the |
+// CertIssuerSourceAia. There should only be a single callback since the 2nd |
+// HTTP request completed before GetNext was called, so both requests can be |
+// supplied to the caller in the same batch. |
+TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedBeforeGetNext) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert2; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // First HTTP request completes. Callback is called as soon as the first |
+ // request completes. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Second HTTP request completes before any results were retrieved from the |
+ // CertIssuerSourceAia. The callback should not be called again. |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ req_manager2->get_callback().Run(OK, |
+ CertDataVector(intermediate_cert2.get())); |
+ |
+ // Caller retrieves results. Both certs should be supplied. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ // 2nd cert is retrieved. |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert()); |
+ |
+ // All results are done, SYNC signals completion. |
+ status = cert_source_request->GetNext(&result_cert); |
+ ASSERT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with three HTTP urls, each pointing to a single DER cert. |
+// |
+// 1) Two HTTP requests complete before the results are retrieved from the |
+// CertIssuerSourceAia. |
+// 2) A single cert result is retrieved via GetNext. |
+// 3) The third HTTP request completes. |
+// 4) The remaining two certs are retrieved. |
+// |
+// Only one callback should occur (after the first HTTP request completed), |
+// since the pending cert results weren't exhausted before the 3rd request |
+// completed. |
+TEST(CertIssuerSourceAiaUnittest, AiaRequestCompletesDuringGetNextSequence) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_three_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert2; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert3; |
+ ASSERT_TRUE(ReadTestCert("i3.pem", &intermediate_cert3)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ RequestManager* req_manager3 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia3/I3.foo")); |
+ ASSERT_TRUE(req_manager3); |
+ ASSERT_TRUE(req_manager3->is_request_alive()); |
+ |
+ // First HTTP request completes. Callback is called as soon as the first |
+ // request completes. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Second HTTP request completes before any results were retrieved from the |
+ // CertIssuerSourceAia. The callback should not be called again. |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ req_manager2->get_callback().Run(OK, |
+ CertDataVector(intermediate_cert2.get())); |
+ |
+ // Caller retrieves a single result. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ // Third HTTP request completes. |
+ // The callback should not be called again, since the last GetNext call had |
+ // indicated more results were pending still. |
+ ASSERT_TRUE(req_manager3->is_request_alive()); |
+ req_manager3->get_callback().Run(OK, |
+ CertDataVector(intermediate_cert3.get())); |
+ |
+ // 2nd cert is retrieved. |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert()); |
+ |
+ // 3rd cert is retrieved. |
+ status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert3->der_cert()); |
+ |
+ // All results are done, SYNC signals completion. |
+ status = cert_source_request->GetNext(&result_cert); |
+ ASSERT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with a single HTTP url pointing to a single DER cert, |
eroman
2016/06/04 01:08:47
nice set of test cases btw!
mattm
2016/06/04 03:24:08
Thanks :)
|
+// CertNetFetcher request fails. The callback should be called to indicate the |
+// request is complete, but no results should be provided. |
+TEST(CertIssuerSourceAiaUnittest, OneAiaHttpError) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ // HTTP request returns with an error. |
+ req_manager->get_callback().Run(ERR_FAILED, std::vector<uint8_t>()); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with a single HTTP url pointing to a single DER cert, |
+// CertNetFetcher request completes, but the DER cert fails to parse. The |
+// callback should be called to indicate the request is complete, but no results |
+// should be provided. |
+TEST(CertIssuerSourceAiaUnittest, OneAiaParseError) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ // HTTP request returns with an error. |
+ uint8_t data[] = {1, 2, 3, 4, 5}; |
+ req_manager->get_callback().Run( |
+ OK, std::vector<uint8_t>(data, data + arraysize(data))); |
eroman
2016/06/04 01:08:47
i believe you can use uniform initialization notat
mattm
2016/06/04 03:24:08
Ah, cool. Done.
|
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert. |
+// One request fails. No callback should be generated yet. Once the second |
+// request completes, the callback should occur. |
+TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeriesFirstFails) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert2; |
+ ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Request for I.cer completes first, but fails. Callback is NOT called. |
+ req_manager->get_callback().Run(ERR_INVALID_RESPONSE, std::vector<uint8_t>()); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Request for I2.foo completes. Callback should be called now. |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager2->get_callback().Run(OK, |
+ CertDataVector(intermediate_cert2.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Results from the second http request are retrieved. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert()); |
+ |
+ // No more results. |
+ status = cert_source_request->GetNext(&result_cert); |
+ ASSERT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert. |
+// First request completes, result is retrieved, then the second request fails. |
+// The second callback should occur to indicate that the results are exhausted, |
+// even though no more results are available. |
+TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeriesSecondFails) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Request for I.cer completes first. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Results are retrieved before the other request completes. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ // The other http request is still pending, status should be ASYNC to signify |
+ // the need to wait for another callback. |
+ ASSERT_EQ(CompletionStatus::ASYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ // Request for I2.foo fails. Callback should be called to indicate that |
+ // results are exhausted. |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager2->get_callback().Run(ERR_INVALID_RESPONSE, |
+ std::vector<uint8_t>()); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // GetNext has no more results. |
+ status = cert_source_request->GetNext(&result_cert); |
+ ASSERT_EQ(CompletionStatus::SYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls. Request is cancelled before any HTTP |
+// requests finish. |
+TEST(CertIssuerSourceAiaUnittest, CertSourceRequestCancelled) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Delete The CertIssuerSource::Request, cancelling it. |
+ cert_source_request.reset(); |
+ // Both CertNetFetcher::Requests should be cancelled. |
+ EXPECT_FALSE(req_manager->is_request_alive()); |
+ EXPECT_FALSE(req_manager2->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert. |
+// One request completes, results are retrieved, then request is cancelled |
+// before the second HTTP request completes. |
+TEST(CertIssuerSourceAiaUnittest, TwoAiaOneCompletedThenRequestCancelled) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert)); |
+ scoped_refptr<ParsedCertificate> intermediate_cert; |
+ ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ ASSERT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ ASSERT_TRUE(req_manager2->is_request_alive()); |
+ |
+ // Request for I.cer completes first. |
+ EXPECT_CALL(mock_callback, Callback(cert_source_request.get())); |
+ req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get())); |
+ Mock::VerifyAndClearExpectations(&mock_callback); |
+ |
+ // Results are retrieved before the other request completes. |
+ scoped_refptr<ParsedCertificate> result_cert; |
+ CompletionStatus status = cert_source_request->GetNext(&result_cert); |
+ EXPECT_EQ(CompletionStatus::SYNC, status); |
+ ASSERT_TRUE(result_cert.get()); |
+ ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert()); |
+ |
+ status = cert_source_request->GetNext(&result_cert); |
+ // The other http request is still pending, status should be ASYNC to signify |
+ // the need to wait for another callback. |
+ ASSERT_EQ(CompletionStatus::ASYNC, status); |
+ EXPECT_FALSE(result_cert.get()); |
+ |
+ // Delete The CertIssuerSource::Request, cancelling it. |
+ cert_source_request.reset(); |
+ // Both CertNetFetcher::Requests should be cancelled. |
+ EXPECT_FALSE(req_manager->is_request_alive()); |
+ EXPECT_FALSE(req_manager2->is_request_alive()); |
+} |
+ |
+// AuthorityInfoAccess with six HTTP URLs. kMaxFetchesPerCert is 5, so the |
+// sixth URL should be ignored. |
+TEST(CertIssuerSourceAiaUnittest, MaxFetchesPerCert) { |
+ scoped_refptr<ParsedCertificate> cert; |
+ ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert)); |
+ |
+ StrictMock<MockIssuerCallback> mock_callback; |
+ StrictMock<MockCertNetFetcherImpl> mock_fetcher; |
+ CertIssuerSourceAia aia_source(&mock_fetcher); |
+ std::unique_ptr<CertIssuerSource::Request> cert_source_request; |
+ aia_source.AsyncGetIssuersOf(cert.get(), |
+ base::Bind(&MockIssuerCallback::Callback, |
+ base::Unretained(&mock_callback)), |
+ &cert_source_request); |
+ ASSERT_NE(nullptr, cert_source_request); |
+ |
+ RequestManager* req_manager = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer")); |
+ ASSERT_TRUE(req_manager); |
+ EXPECT_TRUE(req_manager->is_request_alive()); |
+ |
+ RequestManager* req_manager2 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo")); |
+ ASSERT_TRUE(req_manager2); |
+ EXPECT_TRUE(req_manager2->is_request_alive()); |
+ |
+ RequestManager* req_manager3 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia3/I3.foo")); |
+ ASSERT_TRUE(req_manager3); |
+ EXPECT_TRUE(req_manager3->is_request_alive()); |
+ |
+ RequestManager* req_manager4 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia4/I4.foo")); |
+ ASSERT_TRUE(req_manager4); |
+ EXPECT_TRUE(req_manager4->is_request_alive()); |
+ |
+ RequestManager* req_manager5 = |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia5/I5.foo")); |
+ ASSERT_TRUE(req_manager5); |
+ EXPECT_TRUE(req_manager5->is_request_alive()); |
+ |
+ // Sixth URL should not have created a request. |
+ EXPECT_FALSE( |
+ mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia6/I6.foo"))); |
+} |
+ |
+} // namespace |
+ |
+} // namespace net |