Index: net/socket/ssl_client_socket_unittest.cc |
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc |
index 3aa445a72f8795eac9bd305e20c203ab41595d64..e9dcaa51e091638c26c48de67aa71b82a449ac20 100644 |
--- a/net/socket/ssl_client_socket_unittest.cc |
+++ b/net/socket/ssl_client_socket_unittest.cc |
@@ -658,12 +658,15 @@ class SSLClientSocketTest : public PlatformTest { |
SSLClientSocketTest() |
: socket_factory_(ClientSocketFactory::GetDefaultFactory()), |
cert_verifier_(new MockCertVerifier), |
- transport_security_state_(new TransportSecurityState) { |
+ transport_security_state_(new TransportSecurityState), |
+ ran_handshake_completion_callback_(false) { |
cert_verifier_->set_default_result(OK); |
context_.cert_verifier = cert_verifier_.get(); |
context_.transport_security_state = transport_security_state_.get(); |
} |
+ void RecordCompletedHandshake() { ran_handshake_completion_callback_ = true; } |
+ |
protected: |
// The address of the spawned test server, after calling StartTestServer(). |
const AddressList& addr() const { return addr_; } |
@@ -730,6 +733,12 @@ class SSLClientSocketTest : public PlatformTest { |
return false; |
} |
+#if defined(USE_OPENSSL) |
+ sock_->SetHandshakeCompletionCallback( |
+ base::Bind(&SSLClientSocketTest::RecordCompletedHandshake, |
+ base::Unretained(this))); |
+#endif |
wtc
2014/08/03 01:49:10
Please remove this. In the CompletionCallbackIsRun
mshelley
2014/08/03 23:37:10
Done.
|
+ |
*result = callback_.GetResult(sock_->Connect(callback_.callback())); |
return true; |
} |
@@ -740,6 +749,7 @@ class SSLClientSocketTest : public PlatformTest { |
SSLClientSocketContext context_; |
scoped_ptr<SSLClientSocket> sock_; |
CapturingNetLog log_; |
+ bool ran_handshake_completion_callback_; |
private: |
scoped_ptr<StreamSocket> transport_; |
@@ -2814,4 +2824,159 @@ TEST_F(SSLClientSocketChannelIDTest, FailingChannelIDAsync) { |
EXPECT_FALSE(sock_->IsConnected()); |
} |
+#if defined(USE_OPENSSL) |
+ |
+TEST_F(SSLClientSocketTest, CompletionCallbackIsRun_WithFailure) { |
wtc
2014/08/03 01:49:10
In your test names, change "CompletionCallback" to
mshelley
2014/08/03 23:37:10
Done.
|
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
+ SpawnedTestServer::kLocalhost, |
+ base::FilePath()); |
+ ASSERT_TRUE(test_server.Start()); |
+ |
+ AddressList addr; |
+ ASSERT_TRUE(test_server.GetAddressList(&addr)); |
+ |
+ TestCompletionCallback callback; |
+ scoped_ptr<StreamSocket> real_transport( |
+ new TCPClientSocket(addr, NULL, NetLog::Source())); |
+ scoped_ptr<SynchronousErrorStreamSocket> transport( |
+ new SynchronousErrorStreamSocket(real_transport.Pass())); |
+ int rv = callback.GetResult(transport->Connect(callback.callback())); |
+ EXPECT_EQ(OK, rv); |
+ |
+ // Disable TLS False Start to avoid handshake non-determinism. |
+ SSLConfig ssl_config; |
+ ssl_config.false_start_enabled = false; |
+ |
+ SynchronousErrorStreamSocket* raw_transport = transport.get(); |
+ scoped_ptr<SSLClientSocket> sock( |
+ CreateSSLClientSocket(transport.PassAs<StreamSocket>(), |
+ test_server.host_port_pair(), |
+ ssl_config)); |
+ |
+ sock->SetHandshakeCompletionCallback(base::Bind( |
+ &SSLClientSocketTest::RecordCompletedHandshake, base::Unretained(this))); |
+ |
+ rv = callback.GetResult(sock->Connect(callback.callback())); |
wtc
2014/08/03 01:49:10
IMPORTANT: please base this unit test on the Conne
mshelley
2014/08/03 23:37:10
Done.
|
+ EXPECT_EQ(OK, rv); |
+ EXPECT_TRUE(sock->IsConnected()); |
+ |
+ const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
+ static const int kRequestTextSize = |
+ static_cast<int>(arraysize(request_text) - 1); |
+ scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); |
+ memcpy(request_buffer->data(), request_text, kRequestTextSize); |
+ |
+ rv = callback.GetResult( |
+ sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); |
+ EXPECT_EQ(kRequestTextSize, rv); |
+ |
+ // Simulate an unclean/forcible shutdown. |
+ raw_transport->SetNextReadError(ERR_CONNECTION_RESET); |
+ |
+ scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
+ |
+ // Note: This test will hang if this bug has regressed. Simply checking that |
+ // rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING is a legitimate |
+ // result when using a dedicated task runner for NSS. |
+ rv = callback.GetResult(sock->Read(buf.get(), 4096, callback.callback())); |
+ |
+ EXPECT_TRUE(ran_handshake_completion_callback_); |
+} |
+ |
+TEST_F(SSLClientSocketTest, CompletionCallbackIsRun_WithFalseStartFailure) { |
wtc
2014/08/03 01:49:11
IMPORTANT: did you verify that the handshake is ac
|
+ SpawnedTestServer test_server(SpawnedTestServer::TYPE_HTTPS, |
+ SpawnedTestServer::kLocalhost, |
+ base::FilePath()); |
+ ASSERT_TRUE(test_server.Start()); |
+ |
+ AddressList addr; |
+ ASSERT_TRUE(test_server.GetAddressList(&addr)); |
+ |
+ TestCompletionCallback callback; |
+ scoped_ptr<StreamSocket> real_transport( |
+ new TCPClientSocket(addr, NULL, NetLog::Source())); |
+ // Note: |error_socket|'s ownership is handed to |transport|, but a pointer |
+ // is retained in order to configure additional errors. |
+ scoped_ptr<SynchronousErrorStreamSocket> error_socket( |
+ new SynchronousErrorStreamSocket(real_transport.Pass())); |
+ SynchronousErrorStreamSocket* raw_error_socket = error_socket.get(); |
+ scoped_ptr<FakeBlockingStreamSocket> transport( |
+ new FakeBlockingStreamSocket(error_socket.PassAs<StreamSocket>())); |
+ FakeBlockingStreamSocket* raw_transport = transport.get(); |
+ int rv = callback.GetResult(transport->Connect(callback.callback())); |
+ EXPECT_EQ(OK, rv); |
+ |
+ SSLConfig ssl_config; |
+ ssl_config.false_start_enabled = true; |
+ |
+ scoped_ptr<SSLClientSocket> sock( |
+ CreateSSLClientSocket(transport.PassAs<StreamSocket>(), |
+ test_server.host_port_pair(), |
+ ssl_config)); |
+ |
+ sock->SetHandshakeCompletionCallback(base::Bind( |
+ &SSLClientSocketTest::RecordCompletedHandshake, base::Unretained(this))); |
+ |
+ rv = callback.GetResult(sock->Connect(callback.callback())); |
+ EXPECT_EQ(OK, rv); |
+ EXPECT_TRUE(sock->IsConnected()); |
+ |
+ const char request_text[] = "GET / HTTP/1.0\r\n\r\n"; |
+ static const int kRequestTextSize = |
+ static_cast<int>(arraysize(request_text) - 1); |
+ scoped_refptr<IOBuffer> request_buffer(new IOBuffer(kRequestTextSize)); |
+ memcpy(request_buffer->data(), request_text, kRequestTextSize); |
+ |
+ // Simulate an unclean/forcible shutdown on the underlying socket. |
+ // However, simulate this error asynchronously. |
+ raw_error_socket->SetNextWriteError(ERR_CONNECTION_RESET); |
+ raw_transport->BlockWrite(); |
+ |
+ // This write should complete synchronously, because the TLS ciphertext |
+ // can be created and placed into the outgoing buffers independent of the |
+ // underlying transport. |
+ rv = callback.GetResult( |
+ sock->Write(request_buffer.get(), kRequestTextSize, callback.callback())); |
+ EXPECT_EQ(kRequestTextSize, rv); |
+ |
+ scoped_refptr<IOBuffer> buf(new IOBuffer(4096)); |
+ |
+ rv = sock->Read(buf.get(), 4096, callback.callback()); |
+ EXPECT_EQ(ERR_IO_PENDING, rv); |
+ |
+ // Now unblock the outgoing request, having it fail with the connection |
+ // being reset. |
+ raw_transport->UnblockWrite(); |
+ |
+ // Note: This will cause an inifite loop if this bug has regressed. Simply |
+ // checking that rv != ERR_IO_PENDING is insufficient, as ERR_IO_PENDING |
+ // is a legitimate result when using a dedicated task runner for NSS. |
wtc
2014/08/03 01:49:10
1. Remove this comment block. It makes sense in th
|
+ rv = callback.GetResult(rv); |
+ |
+ EXPECT_TRUE(ran_handshake_completion_callback_); |
+} |
+ |
+// Tests that the completion callback is run when an SSL connection |
+// completes successfully. |
+TEST_F(SSLClientSocketTest, CompletionCallbackIsRun_WithSuccess) { |
+ SpawnedTestServer::SSLOptions ssl_options; |
+ |
+ ASSERT_TRUE(ConnectToTestServer(ssl_options)); |
+ |
+ base::FilePath certs_dir = GetTestCertsDirectory(); |
+ SSLConfig ssl_config = kDefaultSSLConfig; |
+ ssl_config.send_client_cert = true; |
+ ssl_config.client_cert = ImportCertFromFile(certs_dir, "client_1.pem"); |
wtc
2014/08/03 01:49:10
Please delete these four lines and just use kDefau
mshelley
2014/08/03 23:37:09
Done.
|
+ |
+ int rv; |
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); |
+ EXPECT_EQ(OK, rv); |
+ |
+ EXPECT_TRUE(sock_->IsConnected()); |
+ |
+ EXPECT_TRUE(ran_handshake_completion_callback_); |
+} |
+ |
+#endif // defined(USE_OPENSSL) |
+ |
} // namespace net |