| Index: net/base/keygen_handler_unittest.cc
|
| diff --git a/net/base/keygen_handler_unittest.cc b/net/base/keygen_handler_unittest.cc
|
| index 71c9b0394068b469f6fe3783b9974a9c219e218c..f617e2e1ba7dfa1c5e3540d2ff41044fb54508ca 100644
|
| --- a/net/base/keygen_handler_unittest.cc
|
| +++ b/net/base/keygen_handler_unittest.cc
|
| @@ -4,11 +4,18 @@
|
|
|
| #include "net/base/keygen_handler.h"
|
|
|
| +#if defined(USE_NSS)
|
| +#include <private/pprthred.h> // PR_DetachThread
|
| +#endif
|
| +
|
| #include <string>
|
|
|
| #include "base/base64.h"
|
| #include "base/logging.h"
|
| #include "base/nss_util.h"
|
| +#include "base/task.h"
|
| +#include "base/waitable_event.h"
|
| +#include "base/worker_pool.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace net {
|
| @@ -41,11 +48,10 @@ class KeygenHandlerTest : public ::testing::Test {
|
| }
|
| };
|
|
|
| -TEST_F(KeygenHandlerTest, FLAKY_SmokeTest) {
|
| - KeygenHandler handler(2048, "some challenge");
|
| - handler.set_stores_key(false); // Don't leave the key-pair behind
|
| - std::string result = handler.GenKeyAndSignChallenge();
|
| - LOG(INFO) << "KeygenHandler produced: " << result;
|
| +// Assert that |result| is a valid output for KeygenHandler given challenge
|
| +// string of |challenge|.
|
| +void AssertValidSignedPublicKeyAndChallenge(const std::string& result,
|
| + const std::string& challenge) {
|
| ASSERT_GT(result.length(), 0U);
|
|
|
| // Verify it's valid base64:
|
| @@ -78,6 +84,14 @@ TEST_F(KeygenHandlerTest, FLAKY_SmokeTest) {
|
| // openssl asn1parse -inform DER
|
| }
|
|
|
| +TEST_F(KeygenHandlerTest, FLAKY_SmokeTest) {
|
| + KeygenHandler handler(2048, "some challenge");
|
| + handler.set_stores_key(false); // Don't leave the key-pair behind
|
| + std::string result = handler.GenKeyAndSignChallenge();
|
| + LOG(INFO) << "KeygenHandler produced: " << result;
|
| + AssertValidSignedPublicKeyAndChallenge(result, "some challenge");
|
| +}
|
| +
|
| TEST_F(KeygenHandlerTest, Cache) {
|
| KeygenHandler::Cache* cache = KeygenHandler::Cache::GetInstance();
|
| KeygenHandler::KeyLocation location1;
|
| @@ -106,6 +120,64 @@ TEST_F(KeygenHandlerTest, Cache) {
|
| EXPECT_TRUE(location2.Equals(location3));
|
| }
|
|
|
| +class ConcurrencyTestTask : public Task {
|
| + public:
|
| + ConcurrencyTestTask(base::WaitableEvent* event,
|
| + const std::string& challenge, std::string* result)
|
| + : event_(event),
|
| + challenge_(challenge),
|
| + result_(result) {
|
| + }
|
| +
|
| + virtual void Run() {
|
| + KeygenHandler handler(2048, "some challenge");
|
| + handler.set_stores_key(false); // Don't leave the key-pair behind.
|
| + *result_ = handler.GenKeyAndSignChallenge();
|
| + event_->Signal();
|
| +#if defined(USE_NSS)
|
| + // Detach the thread from NSPR.
|
| + // Calling NSS functions attaches the thread to NSPR, which stores
|
| + // the NSPR thread ID in thread-specific data.
|
| + // The threads in our thread pool terminate after we have called
|
| + // PR_Cleanup. Unless we detach them from NSPR, net_unittests gets
|
| + // segfaults on shutdown when the threads' thread-specific data
|
| + // destructors run.
|
| + PR_DetachThread();
|
| +#endif
|
| + }
|
| +
|
| + private:
|
| + base::WaitableEvent* event_;
|
| + std::string challenge_;
|
| + std::string* result_;
|
| +};
|
| +
|
| +// We asynchronously generate the keys so as not to hang up the IO thread. This
|
| +// test tries to catch concurrency problems in the keygen implementation.
|
| +TEST_F(KeygenHandlerTest, ConcurrencyTest) {
|
| + const int NUM_HANDLERS = 5;
|
| + base::WaitableEvent* events[NUM_HANDLERS] = { NULL };
|
| + std::string results[NUM_HANDLERS];
|
| + for (int i = 0; i < NUM_HANDLERS; i++) {
|
| + events[i] = new base::WaitableEvent(false, false);
|
| + WorkerPool::PostTask(FROM_HERE,
|
| + new ConcurrencyTestTask(events[i], "some challenge",
|
| + &results[i]),
|
| + true);
|
| + }
|
| +
|
| + for (int i = 0; i < NUM_HANDLERS; i++) {
|
| + // Make sure the job completed
|
| + bool signaled = events[i]->Wait();
|
| + EXPECT_TRUE(signaled);
|
| + delete events[i];
|
| + events[i] = NULL;
|
| +
|
| + LOG(INFO) << "KeygenHandler " << i << " produced: " << results[i];
|
| + AssertValidSignedPublicKeyAndChallenge(results[i], "some challenge");
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace net
|
|
|