Chromium Code Reviews| 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,252 @@ |
| +// 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/stringprintf.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/base/test_certificate_data.h" |
| +#include "net/base/test_completion_callback.h" |
| +#include "net/base/x509_certificate.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace net { |
| + |
|
willchan no longer on Chromium
2010/12/13 09:30:53
Can this code go into an anonymous namespace?
|
| +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 { |
|
willchan no longer on Chromium
2010/12/13 09:30:53
If we don't need the fixture, can we just use 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); |
| + |
| + scoped_refptr<X509Certificate> google_cert( |
| + X509Certificate::CreateFromBytes( |
| + reinterpret_cast<const char*>(google_der), sizeof(google_der))); |
| + |
| + 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); |
| + |
| + scoped_refptr<X509Certificate> google_cert( |
| + X509Certificate::CreateFromBytes( |
| + reinterpret_cast<const char*>(google_der), sizeof(google_der))); |
| + |
| + 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); |
| + |
| + scoped_refptr<X509Certificate> google_cert( |
| + X509Certificate::CreateFromBytes( |
| + reinterpret_cast<const char*>(google_der), sizeof(google_der))); |
| + |
| + 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(1, 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(0, 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); |
| + |
| + scoped_refptr<X509Certificate> google_cert( |
| + X509Certificate::CreateFromBytes( |
| + reinterpret_cast<const char*>(google_der), sizeof(google_der))); |
| + |
| + 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 int kCacheSize = 64; |
| + |
| + for (int 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, "www100.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(1, 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; |
| + scoped_refptr<X509Certificate> google_cert( |
| + X509Certificate::CreateFromBytes( |
| + reinterpret_cast<const char*>(google_der), sizeof(google_der))); |
| + 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 |