diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 21:13:19 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 21:13:19 +0000 |
commit | 5bab49ecbba6a218d848c1f03ab2eb9f828a18bd (patch) | |
tree | cd7b5f09c86c204e5c192ed778647ff673722bd4 | |
parent | 0a1e9ad53f2f7f2fc6139644da122e272b88fb80 (diff) | |
download | chromium_src-5bab49ecbba6a218d848c1f03ab2eb9f828a18bd.zip chromium_src-5bab49ecbba6a218d848c1f03ab2eb9f828a18bd.tar.gz chromium_src-5bab49ecbba6a218d848c1f03ab2eb9f828a18bd.tar.bz2 |
Make ServerBoundCertService use TaskRunner interface instead of using WorkerPool directly.
Use SequencedWorkerPool for OriginBoundCertServiceTest. Should fix OriginBoundCertServiceTest.CancelRequest flake.
BUG=114726
TEST=trybots
Review URL: http://codereview.chromium.org/10005033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135435 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/io_thread.cc | 4 | ||||
-rw-r--r-- | chrome/browser/profiles/off_the_record_profile_io_data.cc | 4 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_impl_io_data.cc | 7 | ||||
-rw-r--r-- | content/shell/shell_url_request_context_getter.cc | 4 | ||||
-rw-r--r-- | net/base/server_bound_cert_service.cc | 16 | ||||
-rw-r--r-- | net/base/server_bound_cert_service.h | 14 | ||||
-rw-r--r-- | net/base/server_bound_cert_service_unittest.cc | 263 | ||||
-rw-r--r-- | net/spdy/spdy_http_stream_spdy3_unittest.cc | 8 | ||||
-rw-r--r-- | net/url_request/url_request_test_util.cc | 4 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_request_context.cc | 4 |
10 files changed, 233 insertions, 95 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 1c0717b..b354e32 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -17,6 +17,7 @@ #include "base/string_split.h" #include "base/string_util.h" #include "base/threading/thread.h" +#include "base/threading/worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/extension_event_router_forwarder.h" @@ -418,7 +419,8 @@ void IOThread::Init() { // In-memory server bound cert store. globals_->system_server_bound_cert_service.reset( new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL))); + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true))); net::HttpNetworkSession::Params session_params; session_params.host_resolver = globals_->host_resolver.get(); session_params.cert_verifier = globals_->cert_verifier.get(); diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 7d0af1db..e90b5ac 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/stl_util.h" +#include "base/threading/worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/io_thread.h" @@ -194,7 +195,8 @@ void OffTheRecordProfileIOData::LazyInitializeInternal( // For incognito, we use a non-persistent server bound cert store. net::ServerBoundCertService* server_bound_cert_service = new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL)); + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true)); set_server_bound_cert_service(server_bound_cert_service); main_context->set_server_bound_cert_service(server_bound_cert_service); diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 45ee907..12355f7 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -9,6 +9,7 @@ #include "base/file_util.h" #include "base/logging.h" #include "base/stl_util.h" +#include "base/threading/worker_pool.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" @@ -332,7 +333,8 @@ void ProfileImplIOData::LazyInitializeInternal( NULL, profile_params->cookie_monster_delegate); // Don't use existing server-bound certs and use an in-memory store. server_bound_cert_service = new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL)); + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true)); } // setup cookie store @@ -375,7 +377,8 @@ void ProfileImplIOData::LazyInitializeInternal( server_bound_cert_db->SetClearLocalStateOnExit( profile_params->clear_local_state_on_exit); server_bound_cert_service = new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(server_bound_cert_db.get())); + new net::DefaultServerBoundCertStore(server_bound_cert_db.get()), + base::WorkerPool::GetTaskRunner(true)); } set_server_bound_cert_service(server_bound_cert_service); diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc index 23da214..e0438a2 100644 --- a/content/shell/shell_url_request_context_getter.cc +++ b/content/shell/shell_url_request_context_getter.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/string_split.h" +#include "base/threading/worker_pool.h" #include "content/public/browser/browser_thread.h" #include "content/shell/shell_network_delegate.h" #include "net/base/cert_verifier.h" @@ -55,7 +56,8 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() { storage_.reset(new net::URLRequestContextStorage(url_request_context_)); storage_->set_cookie_store(new net::CookieMonster(NULL, NULL)); storage_->set_server_bound_cert_service(new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL))); + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true))); url_request_context_->set_accept_language("en-us,en"); url_request_context_->set_accept_charset("iso-8859-1,*,utf-8"); diff --git a/net/base/server_bound_cert_service.cc b/net/base/server_bound_cert_service.cc index 9c33e02..58c28e8 100644 --- a/net/base/server_bound_cert_service.cc +++ b/net/base/server_bound_cert_service.cc @@ -18,7 +18,7 @@ #include "base/metrics/histogram.h" #include "base/rand_util.h" #include "base/stl_util.h" -#include "base/threading/worker_pool.h" +#include "base/task_runner.h" #include "crypto/ec_private_key.h" #include "googleurl/src/gurl.h" #include "net/base/net_errors.h" @@ -164,6 +164,7 @@ class ServerBoundCertServiceRequest { // ServerBoundCertServiceWorker runs on a worker thread and takes care of the // blocking process of performing key generation. Deletes itself eventually // if Start() succeeds. +// TODO(mattm): don't use locking and explicit cancellation. class ServerBoundCertServiceWorker { public: ServerBoundCertServiceWorker( @@ -179,13 +180,12 @@ class ServerBoundCertServiceWorker { error_(ERR_FAILED) { } - bool Start() { + bool Start(const scoped_refptr<base::TaskRunner>& task_runner) { DCHECK_EQ(MessageLoop::current(), origin_loop_); - return base::WorkerPool::PostTask( + return task_runner->PostTask( FROM_HERE, - base::Bind(&ServerBoundCertServiceWorker::Run, base::Unretained(this)), - true /* task is slow */); + base::Bind(&ServerBoundCertServiceWorker::Run, base::Unretained(this))); } // Cancel is called from the origin loop when the ServerBoundCertService is @@ -353,8 +353,10 @@ class ServerBoundCertServiceJob { const char ServerBoundCertService::kEPKIPassword[] = ""; ServerBoundCertService::ServerBoundCertService( - ServerBoundCertStore* server_bound_cert_store) + ServerBoundCertStore* server_bound_cert_store, + const scoped_refptr<base::TaskRunner>& task_runner) : server_bound_cert_store_(server_bound_cert_store), + task_runner_(task_runner), requests_(0), cert_store_hits_(0), inflight_joins_(0) {} @@ -470,7 +472,7 @@ int ServerBoundCertService::GetDomainBoundCert( preferred_type, this); job = new ServerBoundCertServiceJob(worker, preferred_type); - if (!worker->Start()) { + if (!worker->Start(task_runner_)) { delete job; delete worker; // TODO(rkn): Log to the NetLog. diff --git a/net/base/server_bound_cert_service.h b/net/base/server_bound_cert_service.h index 33b94fe..3d3eea8 100644 --- a/net/base/server_bound_cert_service.h +++ b/net/base/server_bound_cert_service.h @@ -18,6 +18,10 @@ #include "net/base/net_export.h" #include "net/base/ssl_client_cert_type.h" +namespace base { +class TaskRunner; +} + namespace net { class ServerBoundCertServiceJob; @@ -38,9 +42,12 @@ class NET_EXPORT ServerBoundCertService // being unable to import unencrypted PrivateKeyInfo for EC keys.) static const char kEPKIPassword[]; - // This object owns server_bound_cert_store. - explicit ServerBoundCertService( - ServerBoundCertStore* server_bound_cert_store); + // This object owns |server_bound_cert_store|. |task_runner| will + // be used to post certificate generation worker tasks. The tasks are + // safe for use with WorkerPool and SequencedWorkerPool::CONTINUE_ON_SHUTDOWN. + ServerBoundCertService( + ServerBoundCertStore* server_bound_cert_store, + const scoped_refptr<base::TaskRunner>& task_runner); ~ServerBoundCertService(); @@ -118,6 +125,7 @@ class NET_EXPORT ServerBoundCertService const std::string& cert); scoped_ptr<ServerBoundCertStore> server_bound_cert_store_; + scoped_refptr<base::TaskRunner> task_runner_; // inflight_ maps from a server to an active generation which is taking // place. diff --git a/net/base/server_bound_cert_service_unittest.cc b/net/base/server_bound_cert_service_unittest.cc index 4804b70..f09b47c 100644 --- a/net/base/server_bound_cert_service_unittest.cc +++ b/net/base/server_bound_cert_service_unittest.cc @@ -9,6 +9,8 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "base/threading/sequenced_worker_pool.h" #include "crypto/ec_private_key.h" #include "net/base/asn1_util.h" #include "net/base/default_server_bound_cert_store.h" @@ -25,7 +27,24 @@ void FailTest(int /* result */) { FAIL(); } -TEST(ServerBoundCertServiceTest, GetDomainForHost) { +class ServerBoundCertServiceTest : public testing::Test { + protected: + virtual void SetUp() OVERRIDE { + sequenced_worker_pool_ = new base::SequencedWorkerPool( + 3, "ServerBoundCertServiceTest"); + service_.reset(new ServerBoundCertService( + new DefaultServerBoundCertStore(NULL), sequenced_worker_pool_)); + } + + virtual void TearDown() OVERRIDE { + sequenced_worker_pool_->Shutdown(); + } + + scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_; + scoped_ptr<ServerBoundCertService> service_; +}; + +TEST_F(ServerBoundCertServiceTest, GetDomainForHost) { EXPECT_EQ("google.com", ServerBoundCertService::GetDomainForHost("google.com")); EXPECT_EQ("google.com", @@ -46,9 +65,7 @@ TEST(ServerBoundCertServiceTest, GetDomainForHost) { // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned. #if !defined(USE_OPENSSL) -TEST(ServerBoundCertServiceTest, CacheHit) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, CacheHit) { std::string origin("https://encrypted.google.com:443"); int error; @@ -60,15 +77,15 @@ TEST(ServerBoundCertServiceTest, CacheHit) { // Asynchronous completion. SSLClientCertType type1; std::string private_key_info1, der_cert1; - EXPECT_EQ(0, service->cert_count()); - error = service->GetDomainBoundCert( + EXPECT_EQ(0, service_->cert_count()); + error = service_->GetDomainBoundCert( origin, types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(1, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_FALSE(private_key_info1.empty()); EXPECT_FALSE(der_cert1.empty()); @@ -76,24 +93,22 @@ TEST(ServerBoundCertServiceTest, CacheHit) { // Synchronous completion. SSLClientCertType type2; std::string private_key_info2, der_cert2; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_TRUE(request_handle == NULL); EXPECT_EQ(OK, error); - EXPECT_EQ(1, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_EQ(private_key_info1, private_key_info2); EXPECT_EQ(der_cert1, der_cert2); - EXPECT_EQ(2u, service->requests()); - EXPECT_EQ(1u, service->cert_store_hits()); - EXPECT_EQ(0u, service->inflight_joins()); + EXPECT_EQ(2u, service_->requests()); + EXPECT_EQ(1u, service_->cert_store_hits()); + EXPECT_EQ(0u, service_->inflight_joins()); } -TEST(ServerBoundCertServiceTest, UnsupportedTypes) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) { std::string origin("https://encrypted.google.com:443"); int error; @@ -104,7 +119,7 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { // Empty requested_types. SSLClientCertType type1; std::string private_key_info1, der_cert1; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_INVALID_ARGUMENT, error); @@ -114,7 +129,7 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { types.push_back(CLIENT_CERT_RSA_SIGN); types.push_back(2); types.push_back(3); - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); @@ -123,15 +138,15 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { // Supported types after unsupported ones in requested_types. types.push_back(CLIENT_CERT_ECDSA_SIGN); // Asynchronous completion. - EXPECT_EQ(0, service->cert_count()); - error = service->GetDomainBoundCert( + EXPECT_EQ(0, service_->cert_count()); + error = service_->GetDomainBoundCert( origin, types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(1, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_FALSE(private_key_info1.empty()); EXPECT_FALSE(der_cert1.empty()); @@ -142,7 +157,7 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { types.clear(); SSLClientCertType type2; std::string private_key_info2, der_cert2; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(ERR_INVALID_ARGUMENT, error); @@ -152,7 +167,7 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { types.push_back(CLIENT_CERT_RSA_SIGN); types.push_back(2); types.push_back(3); - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); @@ -160,20 +175,18 @@ TEST(ServerBoundCertServiceTest, UnsupportedTypes) { // If we request EC, the cert we created before should still be there. types.push_back(CLIENT_CERT_ECDSA_SIGN); - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_TRUE(request_handle == NULL); EXPECT_EQ(OK, error); - EXPECT_EQ(1, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_EQ(private_key_info1, private_key_info2); EXPECT_EQ(der_cert1, der_cert2); } -TEST(ServerBoundCertServiceTest, StoreCerts) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, StoreCerts) { int error; std::vector<uint8> types; types.push_back(CLIENT_CERT_ECDSA_SIGN); @@ -183,39 +196,39 @@ TEST(ServerBoundCertServiceTest, StoreCerts) { std::string origin1("https://encrypted.google.com:443"); SSLClientCertType type1; std::string private_key_info1, der_cert1; - EXPECT_EQ(0, service->cert_count()); - error = service->GetDomainBoundCert( + EXPECT_EQ(0, service_->cert_count()); + error = service_->GetDomainBoundCert( origin1, types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(1, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); std::string origin2("https://www.verisign.com:443"); SSLClientCertType type2; std::string private_key_info2, der_cert2; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin2, types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(2, service->cert_count()); + EXPECT_EQ(2, service_->cert_count()); std::string origin3("https://www.twitter.com:443"); SSLClientCertType type3; std::string private_key_info3, der_cert3; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin3, types, &type3, &private_key_info3, &der_cert3, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(3, service->cert_count()); + EXPECT_EQ(3, service_->cert_count()); EXPECT_NE(private_key_info1, private_key_info2); EXPECT_NE(der_cert1, der_cert2); @@ -229,9 +242,7 @@ TEST(ServerBoundCertServiceTest, StoreCerts) { } // Tests an inflight join. -TEST(ServerBoundCertServiceTest, InflightJoin) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, InflightJoin) { std::string origin("https://encrypted.google.com:443"); int error; std::vector<uint8> types; @@ -247,7 +258,7 @@ TEST(ServerBoundCertServiceTest, InflightJoin) { TestCompletionCallback callback2; ServerBoundCertService::RequestHandle request_handle2; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type1, &private_key_info1, &der_cert1, callback1.callback(), &request_handle1); EXPECT_EQ(ERR_IO_PENDING, error); @@ -255,7 +266,7 @@ TEST(ServerBoundCertServiceTest, InflightJoin) { // If we request RSA and EC in the 2nd request, should still join with the // original request. types.insert(types.begin(), CLIENT_CERT_RSA_SIGN); - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type2, &private_key_info2, &der_cert2, callback2.callback(), &request_handle2); EXPECT_EQ(ERR_IO_PENDING, error); @@ -268,14 +279,12 @@ TEST(ServerBoundCertServiceTest, InflightJoin) { EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); - EXPECT_EQ(2u, service->requests()); - EXPECT_EQ(0u, service->cert_store_hits()); - EXPECT_EQ(1u, service->inflight_joins()); + EXPECT_EQ(2u, service_->requests()); + EXPECT_EQ(0u, service_->cert_store_hits()); + EXPECT_EQ(1u, service_->inflight_joins()); } -TEST(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { std::string origin("https://encrypted.google.com:443"); SSLClientCertType type; std::string private_key_info, der_cert; @@ -285,7 +294,7 @@ TEST(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { TestCompletionCallback callback; ServerBoundCertService::RequestHandle request_handle; - error = service->GetDomainBoundCert( + error = service_->GetDomainBoundCert( origin, types, &type, &private_key_info, &der_cert, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); @@ -313,9 +322,7 @@ TEST(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { } // Tests that the callback of a canceled request is never made. -TEST(ServerBoundCertServiceTest, CancelRequest) { - scoped_ptr<ServerBoundCertService> service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); +TEST_F(ServerBoundCertServiceTest, CancelRequest) { std::string origin("https://encrypted.google.com:443"); SSLClientCertType type; std::string private_key_info, der_cert; @@ -324,7 +331,7 @@ TEST(ServerBoundCertServiceTest, CancelRequest) { types.push_back(CLIENT_CERT_ECDSA_SIGN); ServerBoundCertService::RequestHandle request_handle; - error = service->GetDomainBoundCert(origin, + error = service_->GetDomainBoundCert(origin, types, &type, &private_key_info, @@ -333,33 +340,136 @@ TEST(ServerBoundCertServiceTest, CancelRequest) { &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); - service->CancelRequest(request_handle); + service_->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 = service->GetDomainBoundCert( - "https://foo" + std::string(1, (char) ('1' + i)), - types, - &type, - &private_key_info, - &der_cert, - callback.callback(), - &request_handle); - EXPECT_EQ(ERR_IO_PENDING, error); - EXPECT_TRUE(request_handle != NULL); - error = callback.WaitForResult(); - } + // Wait for generation to finish. + sequenced_worker_pool_->FlushForTesting(); + // Wait for reply from ServerBoundCertServiceWorker to be posted back to the + // ServerBoundCertService. + MessageLoop::current()->RunAllPending(); // Even though the original request was cancelled, the service will still // store the result, it just doesn't call the callback. - EXPECT_EQ(6, service->cert_count()); + EXPECT_EQ(1, service_->cert_count()); +} + +TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) { + std::string origin("https://encrypted.google.com:443"); + SSLClientCertType type; + std::string private_key_info, der_cert; + int error; + std::vector<uint8> types; + types.push_back(CLIENT_CERT_ECDSA_SIGN); + ServerBoundCertService::RequestHandle request_handle; + + error = service_->GetDomainBoundCert(origin, + types, + &type, + &private_key_info, + &der_cert, + base::Bind(&FailTest), + &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle != NULL); + + // Cancel request and destroy the ServerBoundCertService. + service_->CancelRequest(request_handle); + service_.reset(); + + // Wait for generation to finish. + sequenced_worker_pool_->FlushForTesting(); + // ServerBoundCertServiceWorker should not post anything back to the + // non-existant ServerBoundCertService, but run the loop just to be sure it + // doesn't. + MessageLoop::current()->RunAllPending(); + + // If we got here without crashing or a valgrind error, it worked. +} + +// Tests that simultaneous creation of different certs works. +TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) { + int error; + std::vector<uint8> types; + types.push_back(CLIENT_CERT_ECDSA_SIGN); + ServerBoundCertService::RequestHandle request_handle; + + std::string origin1("https://encrypted.google.com:443"); + SSLClientCertType type1; + std::string private_key_info1, der_cert1; + TestCompletionCallback callback1; + + std::string origin2("https://foo.com:443"); + SSLClientCertType type2; + std::string private_key_info2, der_cert2; + TestCompletionCallback callback2; + + std::string origin3("https://bar.com:443"); + SSLClientCertType type3; + std::string private_key_info3, der_cert3; + TestCompletionCallback callback3; + + error = service_->GetDomainBoundCert(origin1, + types, + &type1, + &private_key_info1, + &der_cert1, + callback1.callback(), + &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle != NULL); + + error = service_->GetDomainBoundCert(origin2, + types, + &type2, + &private_key_info2, + &der_cert2, + callback2.callback(), + &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle != NULL); + + error = service_->GetDomainBoundCert(origin3, + types, + &type3, + &private_key_info3, + &der_cert3, + callback3.callback(), + &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle != NULL); + + error = callback1.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); + EXPECT_FALSE(private_key_info1.empty()); + EXPECT_FALSE(der_cert1.empty()); + + error = callback2.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); + EXPECT_FALSE(private_key_info2.empty()); + EXPECT_FALSE(der_cert2.empty()); + + error = callback3.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3); + EXPECT_FALSE(private_key_info3.empty()); + EXPECT_FALSE(der_cert3.empty()); + + EXPECT_NE(private_key_info1, private_key_info2); + EXPECT_NE(der_cert1, der_cert2); + + EXPECT_NE(private_key_info1, private_key_info3); + EXPECT_NE(der_cert1, der_cert3); + + EXPECT_NE(private_key_info2, private_key_info3); + EXPECT_NE(der_cert2, der_cert3); + + EXPECT_EQ(3, service_->cert_count()); } -TEST(ServerBoundCertServiceTest, Expiration) { - ServerBoundCertStore* store = new DefaultServerBoundCertStore(NULL); +TEST_F(ServerBoundCertServiceTest, Expiration) { + ServerBoundCertStore* store = service_->GetCertStore(); base::Time now = base::Time::Now(); store->SetServerBoundCert("good", CLIENT_CERT_ECDSA_SIGN, @@ -373,8 +483,7 @@ TEST(ServerBoundCertServiceTest, Expiration) { now - base::TimeDelta::FromDays(1), "c", "d"); - ServerBoundCertService service(store); - EXPECT_EQ(2, service.cert_count()); + EXPECT_EQ(2, service_->cert_count()); int error; std::vector<uint8> types; @@ -385,12 +494,12 @@ TEST(ServerBoundCertServiceTest, Expiration) { // Cert still valid - synchronous completion. SSLClientCertType type1; std::string private_key_info1, der_cert1; - error = service.GetDomainBoundCert( + error = service_->GetDomainBoundCert( "https://good", types, &type1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(OK, error); EXPECT_TRUE(request_handle == NULL); - EXPECT_EQ(2, service.cert_count()); + EXPECT_EQ(2, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_STREQ("a", private_key_info1.c_str()); EXPECT_STREQ("b", der_cert1.c_str()); @@ -398,14 +507,14 @@ TEST(ServerBoundCertServiceTest, Expiration) { // Cert expired - New cert will be generated, asynchronous completion. SSLClientCertType type2; std::string private_key_info2, der_cert2; - error = service.GetDomainBoundCert( + error = service_->GetDomainBoundCert( "https://expired", types, &type2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle != NULL); error = callback.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(2, service.cert_count()); + EXPECT_EQ(2, service_->cert_count()); EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_LT(1U, private_key_info2.size()); EXPECT_LT(1U, der_cert2.size()); diff --git a/net/spdy/spdy_http_stream_spdy3_unittest.cc b/net/spdy/spdy_http_stream_spdy3_unittest.cc index 460215e..4307ddc 100644 --- a/net/spdy/spdy_http_stream_spdy3_unittest.cc +++ b/net/spdy/spdy_http_stream_spdy3_unittest.cc @@ -4,6 +4,7 @@ #include "net/spdy/spdy_http_stream.h" +#include "base/threading/sequenced_worker_pool.h" #include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" #include "crypto/signature_creator.h" @@ -506,8 +507,11 @@ TEST_F(SpdyHttpStreamSpdy3Test, SendCredentialsEC) { crypto::ECSignatureCreator::SetFactoryForTesting( ec_signature_creator_factory.get()); + scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool = + new base::SequencedWorkerPool(1, "SpdyHttpStreamSpdy3Test"); scoped_ptr<ServerBoundCertService> server_bound_cert_service( - new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); + new ServerBoundCertService(new DefaultServerBoundCertStore(NULL), + sequenced_worker_pool)); std::string cert; std::string proof; GetECServerBoundCertAndProof("http://www.gmail.com/", @@ -516,6 +520,8 @@ TEST_F(SpdyHttpStreamSpdy3Test, SendCredentialsEC) { TestSendCredentials(server_bound_cert_service.get(), cert, proof, CLIENT_CERT_ECDSA_SIGN); + + sequenced_worker_pool->Shutdown(); } #endif // !defined(USE_OPENSSL) diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 5fc4f72..7e565e4 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" #include "base/message_loop.h" +#include "base/message_loop_proxy.h" #include "base/threading/thread.h" #include "net/base/cert_verifier.h" #include "net/base/default_server_bound_cert_store.h" @@ -148,7 +149,8 @@ void TestURLRequestContext::Init() { if (!server_bound_cert_service()) { context_storage_.set_server_bound_cert_service( new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL))); + new net::DefaultServerBoundCertStore(NULL), + base::MessageLoopProxy::current())); } if (accept_language().empty()) set_accept_language("en-us,fr"); diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc index 7286193..71c46fc 100644 --- a/webkit/tools/test_shell/test_shell_request_context.cc +++ b/webkit/tools/test_shell/test_shell_request_context.cc @@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/file_path.h" +#include "base/threading/worker_pool.h" #include "net/base/cert_verifier.h" #include "net/base/default_server_bound_cert_store.h" #include "net/base/host_resolver.h" @@ -50,7 +51,8 @@ void TestShellRequestContext::Init( bool no_proxy) { storage_.set_cookie_store(new net::CookieMonster(NULL, NULL)); storage_.set_server_bound_cert_service(new net::ServerBoundCertService( - new net::DefaultServerBoundCertStore(NULL))); + new net::DefaultServerBoundCertStore(NULL), + base::WorkerPool::GetTaskRunner(true))); // hard-code A-L and A-C for test shells set_accept_language("en-us,en"); |