diff options
Diffstat (limited to 'net/base/keygen_handler_unittest.cc')
-rw-r--r-- | net/base/keygen_handler_unittest.cc | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/net/base/keygen_handler_unittest.cc b/net/base/keygen_handler_unittest.cc index e6b3641..15ec0ce 100644 --- a/net/base/keygen_handler_unittest.cc +++ b/net/base/keygen_handler_unittest.cc @@ -4,11 +4,20 @@ #include "net/base/keygen_handler.h" +#include "build/build_config.h" // Needs to be imported early for USE_NSS + +#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 { @@ -27,11 +36,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: @@ -64,6 +72,72 @@ 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"); +} + +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 |