Commit bdd9360c authored by Adam Simpkins's avatar Adam Simpkins Committed by Facebook Github Bot

fix some bugs in AsyncSSLSocketTest

Summary:
A couple of the test functions in AsyncSSLSocketTest maintained two EventBase
objects and alternated looping between them.  In some cases it would call
EventBase::loopOnce() even when there was no work to do.  This call normally
blocks until an event is ready.  This happened to work when using libevent1,
but this appears mostly accidental: with libevent1 EVLOOP_ONCE causes the loop
to break out even after an "internal" I/O event; in libevent2 EVLOOP_ONCE only
breaks out after a non-internal event has occurred:
https://github.com/libevent/libevent/commit/0617a818204397790e5e4c9bcb9e91ae5ea7817a

In these tests it turns out that the internal EventBase NotificationQueue
always gets triggered the very first time loopOnce() is called, preventing
these tests from hanging when using libevent1.

This fixes the hang when using libevent2 by removing the initial loopOnce()
calls that potentially have nothing to do.  This also consolidates the 2
EventBase objects into one to avoid having to alternate loopOnce() calls
between them without knowing which one actually has work to do.

This also fixes an issue where the code never checked the return value of
`recv()`

Reviewed By: yfeldblum, siyengar

Differential Revision: D6735669

fbshipit-source-id: 5f36106a08866aa8908e82263f83a606399cdf79
parent 7da4ef82
...@@ -2082,8 +2082,7 @@ TEST(AsyncSSLSocketTest, HandshakeTFORefused) { ...@@ -2082,8 +2082,7 @@ TEST(AsyncSSLSocketTest, HandshakeTFORefused) {
} }
TEST(AsyncSSLSocketTest, TestPreReceivedData) { TEST(AsyncSSLSocketTest, TestPreReceivedData) {
EventBase clientEventBase; EventBase eventBase;
EventBase serverEventBase;
auto clientCtx = std::make_shared<SSLContext>(); auto clientCtx = std::make_shared<SSLContext>();
auto dfServerCtx = std::make_shared<SSLContext>(); auto dfServerCtx = std::make_shared<SSLContext>();
std::array<int, 2> fds; std::array<int, 2> fds;
...@@ -2091,23 +2090,23 @@ TEST(AsyncSSLSocketTest, TestPreReceivedData) { ...@@ -2091,23 +2090,23 @@ TEST(AsyncSSLSocketTest, TestPreReceivedData) {
getctx(clientCtx, dfServerCtx); getctx(clientCtx, dfServerCtx);
AsyncSSLSocket::UniquePtr clientSockPtr( AsyncSSLSocket::UniquePtr clientSockPtr(
new AsyncSSLSocket(clientCtx, &clientEventBase, fds[0], false)); new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
AsyncSSLSocket::UniquePtr serverSockPtr( AsyncSSLSocket::UniquePtr serverSockPtr(
new AsyncSSLSocket(dfServerCtx, &serverEventBase, fds[1], true)); new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
auto clientSock = clientSockPtr.get(); auto clientSock = clientSockPtr.get();
auto serverSock = serverSockPtr.get(); auto serverSock = serverSockPtr.get();
SSLHandshakeClient client(std::move(clientSockPtr), true, true); SSLHandshakeClient client(std::move(clientSockPtr), true, true);
// Steal some data from the server. // Steal some data from the server.
clientEventBase.loopOnce();
std::array<uint8_t, 10> buf; std::array<uint8_t, 10> buf;
recv(fds[1], buf.data(), buf.size(), 0); auto bytesReceived = recv(fds[1], buf.data(), buf.size(), 0);
checkUnixError(bytesReceived, "recv failed");
serverSock->setPreReceivedData(IOBuf::wrapBuffer(range(buf))); serverSock->setPreReceivedData(
IOBuf::wrapBuffer(ByteRange(buf.data(), bytesReceived)));
SSLHandshakeServer server(std::move(serverSockPtr), true, true); SSLHandshakeServer server(std::move(serverSockPtr), true, true);
while (!client.handshakeSuccess_ && !client.handshakeError_) { while (!client.handshakeSuccess_ && !client.handshakeError_) {
serverEventBase.loopOnce(); eventBase.loopOnce();
clientEventBase.loopOnce();
} }
EXPECT_TRUE(client.handshakeSuccess_); EXPECT_TRUE(client.handshakeSuccess_);
...@@ -2117,8 +2116,7 @@ TEST(AsyncSSLSocketTest, TestPreReceivedData) { ...@@ -2117,8 +2116,7 @@ TEST(AsyncSSLSocketTest, TestPreReceivedData) {
} }
TEST(AsyncSSLSocketTest, TestMoveFromAsyncSocket) { TEST(AsyncSSLSocketTest, TestMoveFromAsyncSocket) {
EventBase clientEventBase; EventBase eventBase;
EventBase serverEventBase;
auto clientCtx = std::make_shared<SSLContext>(); auto clientCtx = std::make_shared<SSLContext>();
auto dfServerCtx = std::make_shared<SSLContext>(); auto dfServerCtx = std::make_shared<SSLContext>();
std::array<int, 2> fds; std::array<int, 2> fds;
...@@ -2126,25 +2124,25 @@ TEST(AsyncSSLSocketTest, TestMoveFromAsyncSocket) { ...@@ -2126,25 +2124,25 @@ TEST(AsyncSSLSocketTest, TestMoveFromAsyncSocket) {
getctx(clientCtx, dfServerCtx); getctx(clientCtx, dfServerCtx);
AsyncSSLSocket::UniquePtr clientSockPtr( AsyncSSLSocket::UniquePtr clientSockPtr(
new AsyncSSLSocket(clientCtx, &clientEventBase, fds[0], false)); new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
AsyncSocket::UniquePtr serverSockPtr( AsyncSocket::UniquePtr serverSockPtr(new AsyncSocket(&eventBase, fds[1]));
new AsyncSocket(&serverEventBase, fds[1]));
auto clientSock = clientSockPtr.get(); auto clientSock = clientSockPtr.get();
auto serverSock = serverSockPtr.get(); auto serverSock = serverSockPtr.get();
SSLHandshakeClient client(std::move(clientSockPtr), true, true); SSLHandshakeClient client(std::move(clientSockPtr), true, true);
// Steal some data from the server. // Steal some data from the server.
clientEventBase.loopOnce();
std::array<uint8_t, 10> buf; std::array<uint8_t, 10> buf;
recv(fds[1], buf.data(), buf.size(), 0); auto bytesReceived = recv(fds[1], buf.data(), buf.size(), 0);
serverSock->setPreReceivedData(IOBuf::wrapBuffer(range(buf))); checkUnixError(bytesReceived, "recv failed");
serverSock->setPreReceivedData(
IOBuf::wrapBuffer(ByteRange(buf.data(), bytesReceived)));
AsyncSSLSocket::UniquePtr serverSSLSockPtr( AsyncSSLSocket::UniquePtr serverSSLSockPtr(
new AsyncSSLSocket(dfServerCtx, std::move(serverSockPtr), true)); new AsyncSSLSocket(dfServerCtx, std::move(serverSockPtr), true));
auto serverSSLSock = serverSSLSockPtr.get(); auto serverSSLSock = serverSSLSockPtr.get();
SSLHandshakeServer server(std::move(serverSSLSockPtr), true, true); SSLHandshakeServer server(std::move(serverSSLSockPtr), true, true);
while (!client.handshakeSuccess_ && !client.handshakeError_) { while (!client.handshakeSuccess_ && !client.handshakeError_) {
serverEventBase.loopOnce(); eventBase.loopOnce();
clientEventBase.loopOnce();
} }
EXPECT_TRUE(client.handshakeSuccess_); EXPECT_TRUE(client.handshakeSuccess_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment