Index: net/base/cert_verifier_unittest.cc |
=================================================================== |
--- net/base/cert_verifier_unittest.cc (revision 0) |
+++ net/base/cert_verifier_unittest.cc (revision 0) |
@@ -0,0 +1,260 @@ |
+// Copyright (c) 2010 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/base/cert_verifier.h" |
+ |
+#include "base/callback.h" |
+#include "base/file_path.h" |
+#include "base/stringprintf.h" |
+#include "net/base/cert_test_util.h" |
+#include "net/base/net_errors.h" |
+#include "net/base/test_completion_callback.h" |
+#include "net/base/x509_certificate.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace net { |
+ |
+class TestTimeService : public CertVerifier::TimeService { |
+ public: |
+ // CertVerifier::TimeService methods: |
+ virtual base::Time Now() { return current_time_; } |
+ |
+ void set_current_time(base::Time now) { current_time_ = now; } |
+ |
+ private: |
+ base::Time current_time_; |
+}; |
+ |
+class CertVerifierTest : public testing::Test { |
+}; |
+ |
+class ExplodingCallback : public CallbackRunner<Tuple1<int> > { |
+ public: |
+ virtual void RunWithParams(const Tuple1<int>& params) { |
+ FAIL(); |
+ } |
+}; |
+ |
+// Tests a cache hit, which should results in synchronous completion. |
+TEST_F(CertVerifierTest, CacheHit) { |
+ TestTimeService* time_service = new TestTimeService; |
+ base::Time current_time = base::Time::Now(); |
+ time_service->set_current_time(current_time); |
+ CertVerifier verifier(time_service); |
+ |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert( |
+ ImportCertFromFile(certs_dir, "google.single.der")); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ |
+ int error; |
+ CertVerifyResult verify_result; |
+ TestCompletionCallback callback; |
+ CertVerifier::RequestHandle request_handle; |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(1u, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ // Synchronous completion. |
+ ASSERT_NE(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_TRUE(request_handle == NULL); |
+ ASSERT_EQ(2u, verifier.requests()); |
+ ASSERT_EQ(1u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+} |
+ |
+// Tests an inflight join. |
+TEST_F(CertVerifierTest, InflightJoin) { |
+ TestTimeService* time_service = new TestTimeService; |
+ base::Time current_time = base::Time::Now(); |
+ time_service->set_current_time(current_time); |
+ CertVerifier verifier(time_service); |
+ |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert( |
+ ImportCertFromFile(certs_dir, "google.single.der")); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ |
+ int error; |
+ CertVerifyResult verify_result; |
+ TestCompletionCallback callback; |
+ CertVerifier::RequestHandle request_handle; |
+ CertVerifyResult verify_result2; |
+ TestCompletionCallback callback2; |
+ CertVerifier::RequestHandle request_handle2; |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result2, |
+ &callback2, &request_handle2); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle2 != NULL); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ error = callback2.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(2u, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(1u, verifier.inflight_joins()); |
+} |
+ |
+// Tests cache entry expiration. |
+TEST_F(CertVerifierTest, ExpiredCacheEntry) { |
+ TestTimeService* time_service = new TestTimeService; |
+ base::Time current_time = base::Time::Now(); |
+ time_service->set_current_time(current_time); |
+ CertVerifier verifier(time_service); |
+ |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert( |
+ ImportCertFromFile(certs_dir, "google.single.der")); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ |
+ int error; |
+ CertVerifyResult verify_result; |
+ TestCompletionCallback callback; |
+ CertVerifier::RequestHandle request_handle; |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(1u, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+ |
+ // Before expiration, should have a cache hit. |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ // Synchronous completion. |
+ ASSERT_NE(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_TRUE(request_handle == NULL); |
+ ASSERT_EQ(2u, verifier.requests()); |
+ ASSERT_EQ(1u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+ |
+ // After expiration, should not have a cache hit. |
+ ASSERT_EQ(1u, verifier.GetCacheSize()); |
+ current_time += base::TimeDelta::FromMinutes(60); |
+ time_service->set_current_time(current_time); |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ ASSERT_EQ(0u, verifier.GetCacheSize()); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(3u, verifier.requests()); |
+ ASSERT_EQ(1u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+} |
+ |
+// Tests a full cache. |
+TEST_F(CertVerifierTest, FullCache) { |
+ TestTimeService* time_service = new TestTimeService; |
+ base::Time current_time = base::Time::Now(); |
+ time_service->set_current_time(current_time); |
+ CertVerifier verifier(time_service); |
+ |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert( |
+ ImportCertFromFile(certs_dir, "google.single.der")); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ |
+ int error; |
+ CertVerifyResult verify_result; |
+ TestCompletionCallback callback; |
+ CertVerifier::RequestHandle request_handle; |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(1u, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+ |
+ const unsigned kCacheSize = 256; |
+ |
+ for (unsigned i = 0; i < kCacheSize; i++) { |
+ std::string hostname = base::StringPrintf("www%d.example.com", i + 1); |
+ error = verifier.Verify(google_cert, hostname, 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = callback.WaitForResult(); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ } |
+ ASSERT_EQ(kCacheSize + 1, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+ |
+ ASSERT_EQ(kCacheSize, verifier.GetCacheSize()); |
+ current_time += base::TimeDelta::FromMinutes(60); |
+ time_service->set_current_time(current_time); |
+ error = verifier.Verify(google_cert, "www999.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ ASSERT_EQ(kCacheSize, verifier.GetCacheSize()); |
+ error = callback.WaitForResult(); |
+ ASSERT_EQ(1u, verifier.GetCacheSize()); |
+ ASSERT_TRUE(IsCertificateError(error)); |
+ ASSERT_EQ(kCacheSize + 2, verifier.requests()); |
+ ASSERT_EQ(0u, verifier.cache_hits()); |
+ ASSERT_EQ(0u, verifier.inflight_joins()); |
+} |
+ |
+// Tests that the callback of a canceled request is never made. |
+TEST_F(CertVerifierTest, CancelRequest) { |
+ CertVerifier verifier; |
+ |
+ FilePath certs_dir = GetTestCertsDirectory(); |
+ scoped_refptr<X509Certificate> google_cert( |
+ ImportCertFromFile(certs_dir, "google.single.der")); |
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
+ |
+ int error; |
+ CertVerifyResult verify_result; |
+ ExplodingCallback exploding_callback; |
+ CertVerifier::RequestHandle request_handle; |
+ |
+ error = verifier.Verify(google_cert, "www.example.com", 0, &verify_result, |
+ &exploding_callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ verifier.CancelRequest(request_handle); |
+ |
+ // Issue a few more requests to the worker pool and wait for their |
+ // completion, so that the task of the canceled request (which runs on a |
+ // worker thread) is likely to complete by the end of this test. |
+ TestCompletionCallback callback; |
+ for (int i = 0; i < 5; ++i) { |
+ error = verifier.Verify(google_cert, "www2.example.com", 0, &verify_result, |
+ &callback, &request_handle); |
+ ASSERT_EQ(ERR_IO_PENDING, error); |
+ ASSERT_TRUE(request_handle != NULL); |
+ error = callback.WaitForResult(); |
+ verifier.ClearCache(); |
+ } |
+} |
+ |
+} // namespace net |
Property changes on: net\base\cert_verifier_unittest.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |