Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(551)

Unified Diff: native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc

Issue 26703008: [NaCl SDK] nacl_io: Add support for non-blocking connect/accept (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc
diff --git a/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc b/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc
index dfd682ae9b0129990219e13524763fb11b68b88c..c0c8c9c6603108c8686476f1a94d32b70a47b0aa 100644
--- a/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_socket_test/socket_test.cc
@@ -44,6 +44,14 @@ void IP4ToSockAddr(uint32_t ip, uint16_t port, struct sockaddr_in* addr) {
addr->sin_addr.s_addr = htonl(ip);
}
+void SetNonBlocking(int sock) {
+ int flags = fcntl(sock, F_GETFL);
+ ASSERT_NE(-1, flags);
+ flags |= O_NONBLOCK;
+ ASSERT_EQ(0, fcntl(sock, F_SETFL, flags));
+ ASSERT_EQ(flags, fcntl(sock, F_GETFL));
+}
+
class SocketTest : public ::testing::Test {
public:
SocketTest() : sock1(-1), sock2(-1) {}
@@ -291,6 +299,36 @@ TEST_F(SocketTestWithServer, TCPConnect) {
EXPECT_EQ(0, memcmp(outbuf, inbuf, sizeof(outbuf)));
}
+TEST_F(SocketTestWithServer, TCPConnectNonBlock) {
+ char outbuf[256];
+ //char inbuf[512];
+
+ memset(outbuf, 1, sizeof(outbuf));
+
+ sockaddr_in addr;
+ socklen_t addrlen = sizeof(addr);
+
+ IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
+
+ SetNonBlocking(sock_);
+ ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
+ ASSERT_EQ(EINPROGRESS, errno)
+ << "expected EINPROGRESS but got: " << strerror(errno) << "\n";
+ ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
+ ASSERT_EQ(EALREADY, errno);
+
+ // Wait for the socket connection to complete using poll()
+ struct pollfd pollfd = { sock_, POLLIN|POLLOUT, 0 };
+ ASSERT_EQ(1, poll(&pollfd, 1, -1));
+ ASSERT_EQ(POLLOUT, pollfd.revents);
+
+ // Attempts to connect again should yield EISCONN
+ ASSERT_EQ(-1, connect(sock_, (sockaddr*) &addr, addrlen));
+ ASSERT_EQ(EISCONN, errno);
+
+ // And SO_ERROR should be 0.
+}
+
TEST_F(SocketTest, Getsockopt) {
sock1 = socket(AF_INET, SOCK_STREAM, 0);
EXPECT_GT(sock1, -1);
@@ -334,7 +372,6 @@ TEST_F(SocketTestUDP, Listen) {
}
TEST_F(SocketTestTCP, Listen) {
- // Accept should fail when socket not listening
sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
@@ -346,7 +383,7 @@ TEST_F(SocketTestTCP, Listen) {
// Listen should fail on unbound socket
ASSERT_EQ(-1, listen(server_sock, 10));
- // bind and listen
+ // Bind and Listen
ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
ASSERT_EQ(0, listen(server_sock, 10))
<< "listen failed with: " << strerror(errno);
@@ -377,6 +414,59 @@ TEST_F(SocketTestTCP, Listen) {
char inbuf[512];
ASSERT_EQ(5, recv(new_socket, inbuf, 5, 0));
+ ASSERT_EQ(0, close(new_socket));
+}
+
+TEST_F(SocketTestTCP, ListenNonBlocking) {
+ int server_sock = sock1;
+
+ // Set non-blocking
+ SetNonBlocking(server_sock);
+
+ // bind and listen
+ ASSERT_EQ(0, Bind(server_sock, LOCAL_HOST, PORT1));
+ ASSERT_EQ(0, listen(server_sock, 10))
+ << "listen failed with: " << strerror(errno);
+
+ // Accept should fail with EAGAIN since there is no incomming
+ // connection.
+ sockaddr_in addr;
+ socklen_t addrlen = sizeof(addr);
+ ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
+ ASSERT_EQ(EAGAIN, errno);
+
+ // If we poll the listening socket it should also return
+ // not readable to indicate that no connections are available
+ // to accept.
+ struct pollfd pollfd = { server_sock, POLLIN|POLLOUT, 0 };
+ ASSERT_EQ(0, poll(&pollfd, 1, 0));
+
+ // Connect to listening socket
+ int client_sock = sock2;
+ IP4ToSockAddr(LOCAL_HOST, PORT1, &addr);
+ addrlen = sizeof(addr);
+ ASSERT_EQ(0, connect(client_sock, (sockaddr*)&addr, addrlen))
+ << "Failed with " << errno << ": " << strerror(errno) << "\n";
+
+ // Not poll again but with an infintie timeout.
+ pollfd.fd = server_sock;
+ pollfd.events = POLLIN | POLLOUT;
+ ASSERT_EQ(1, poll(&pollfd, 1, -1));
+
+ // Now non-blocking accept should return the new socket
+ int new_socket = accept(server_sock, (sockaddr*)&addr, &addrlen);
+ ASSERT_NE(-1, new_socket)
+ << "accept failed with: " << strerror(errno) << "\n";
+ ASSERT_EQ(0, close(new_socket));
+
+ // Accept calls should once again fail with EAGAIN
+ ASSERT_EQ(-1, accept(server_sock, (sockaddr*)&addr, &addrlen));
+ ASSERT_EQ(EAGAIN, errno);
+
+ // As should polling the listening socket
+ pollfd.fd = server_sock;
+ pollfd.events = POLLIN | POLLOUT;
+ ASSERT_EQ(0, poll(&pollfd, 1, 0));
}
#endif // PROVIDES_SOCKET_API

Powered by Google App Engine
This is Rietveld 408576698