summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 21:13:19 +0000
committermattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-04 21:13:19 +0000
commit5bab49ecbba6a218d848c1f03ab2eb9f828a18bd (patch)
treecd7b5f09c86c204e5c192ed778647ff673722bd4
parent0a1e9ad53f2f7f2fc6139644da122e272b88fb80 (diff)
downloadchromium_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.cc4
-rw-r--r--chrome/browser/profiles/off_the_record_profile_io_data.cc4
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.cc7
-rw-r--r--content/shell/shell_url_request_context_getter.cc4
-rw-r--r--net/base/server_bound_cert_service.cc16
-rw-r--r--net/base/server_bound_cert_service.h14
-rw-r--r--net/base/server_bound_cert_service_unittest.cc263
-rw-r--r--net/spdy/spdy_http_stream_spdy3_unittest.cc8
-rw-r--r--net/url_request/url_request_test_util.cc4
-rw-r--r--webkit/tools/test_shell/test_shell_request_context.cc4
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");