[WS2_32_APITESTS] Add nonblocking tests
authorPeter Hater <7element@mail.bg>
Thu, 10 Nov 2016 15:13:19 +0000 (15:13 +0000)
committerPeter Hater <7element@mail.bg>
Thu, 10 Nov 2016 15:13:19 +0000 (15:13 +0000)
svn path=/trunk/; revision=73195

rostests/apitests/ws2_32/CMakeLists.txt
rostests/apitests/ws2_32/nonblocking.c [new file with mode: 0644]
rostests/apitests/ws2_32/testlist.c

index d3af388..f3e9549 100644 (file)
@@ -6,6 +6,7 @@ list(APPEND SOURCE
     getservbyport.c
     helpers.c
     ioctlsocket.c
+    nonblocking.c
     nostartup.c
     recv.c
     send.c
diff --git a/rostests/apitests/ws2_32/nonblocking.c b/rostests/apitests/ws2_32/nonblocking.c
new file mode 100644 (file)
index 0000000..40286cb
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+* PROJECT:         ReactOS api tests
+* LICENSE:         GPL - See COPYING in the top level directory
+* PURPOSE:         Test for nonblocking sockets
+* PROGRAMMERS:     Peter Hater 
+*/
+
+#include <apitest.h>
+
+#include <stdio.h>
+#include <windows.h>
+#include <winsock2.h>
+
+#define SVR_PORT 5000
+#define WAIT_TIMEOUT_ 10000
+#define EXIT_FLAGS (FD_ACCEPT|FD_CONNECT)
+
+START_TEST(nonblocking)
+{
+    WSADATA    WsaData;
+    SOCKET     ServerSocket = INVALID_SOCKET,
+               ClientSocket = INVALID_SOCKET;
+    struct sockaddr_in server_addr_in;
+    struct sockaddr_in addr_remote;
+    struct sockaddr_in addr_con_loc;
+    int nConRes, err;
+    int addrsize;
+    SOCKET sockaccept;
+    ULONG ulValue = 1;
+    DWORD dwFlags = 0, dwLen, dwAddrLen;
+    fd_set readfds, writefds, exceptfds;
+    struct timeval tval = { 0 };
+    char address[100];
+
+    if (WSAStartup(MAKEWORD(2, 2), &WsaData) != 0)
+    {
+        skip("WSAStartup failed\n");
+        return;
+    }
+
+    ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+    if (ServerSocket == INVALID_SOCKET)
+    {
+        skip("ERROR: Server socket creation failed\n");
+        return;
+    }
+    if (ClientSocket == INVALID_SOCKET)
+    {
+        skip("ERROR: Client socket creation failed\n");
+        closesocket(ServerSocket);
+        return;
+    }
+    server_addr_in.sin_family = AF_INET;
+    server_addr_in.sin_addr.s_addr = INADDR_ANY;
+    server_addr_in.sin_port   = htons(SVR_PORT);
+
+    // server inialialization
+    trace("Initializing server and client connections ...\n");
+    err = bind(ServerSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
+    ok(err == 0, "ERROR: server bind failed\n");
+    err = ioctlsocket(ServerSocket, FIONBIO, &ulValue);
+    ok(err == 0, "ERROR: server ioctlsocket FIONBIO failed\n");
+
+    // client inialialization
+    err = ioctlsocket(ClientSocket, FIONBIO, &ulValue);
+    ok(err == 0, "ERROR: client ioctlsocket FIONBIO failed\n");
+
+    // listen
+    trace("Starting server listening mode ...\n");
+    err = listen(ServerSocket, 2);
+    ok(err == 0, "ERROR: cannot initialize server listen\n");
+
+    trace("Starting client to server connection ...\n");
+    // connect
+    server_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    server_addr_in.sin_port = htons(SVR_PORT);
+    nConRes = connect(ClientSocket, (struct sockaddr*)&server_addr_in, sizeof(server_addr_in));
+    ok(nConRes == SOCKET_ERROR, "ERROR: client connect() result is not SOCKET_ERROR\n");
+    ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
+    FD_ZERO(&readfds);
+    FD_ZERO(&writefds);
+    FD_ZERO(&exceptfds);
+    FD_SET(ServerSocket, &readfds);
+
+    while (dwFlags != EXIT_FLAGS)
+    {
+        addrsize = sizeof(addr_con_loc);
+        err = getsockname(ClientSocket, (struct sockaddr*)&addr_con_loc, &addrsize);
+        if (err == 0)
+        {// client connected
+            dwLen = sizeof(addr_con_loc);
+            dwAddrLen = sizeof(address);
+            err = WSAAddressToStringA((PSOCKADDR)&addr_con_loc, dwLen, NULL, address, &dwAddrLen);
+            if (err == 0)
+            {
+                trace("Event FD_CONNECT...\n");
+                dwFlags |= FD_CONNECT;
+                err = recv(ClientSocket, address, dwAddrLen, 0);
+                ok(err == -1, "ERROR: error reading data from connected socket, error %d\n", WSAGetLastError());
+                ok(WSAGetLastError() == WSAEWOULDBLOCK, "ERROR: client connect() last error is not WSAEWOULDBLOCK\n");
+                err = send(ClientSocket, address, dwAddrLen, 0);
+                ok(err == dwAddrLen, "ERROR: error writing data to connected socket, error %d %d\n", err, WSAGetLastError());
+            }
+            else
+            {
+                trace("WSAAddressToStringA failed %d\n", WSAGetLastError());
+            }
+        }
+
+        err = select(1, &readfds, &writefds, &exceptfds, &tval);
+        if (err == 1 && FD_ISSET(ServerSocket, &readfds))
+        {// connection ready to be accepted
+            trace("Event FD_ACCEPT...\n");
+            addrsize = sizeof(addr_remote);
+            sockaccept = accept(ServerSocket, (struct sockaddr*)&addr_remote, &addrsize);
+            ok(sockaccept != INVALID_SOCKET, "ERROR: Connection accept function failed, error %d\n", WSAGetLastError());
+            dwFlags |= FD_ACCEPT;
+            dwLen = sizeof(addr_remote);
+            dwAddrLen = sizeof(address);
+            err = WSAAddressToStringA((PSOCKADDR)&addr_remote, dwLen, NULL, address, &dwAddrLen);
+            ok(err == 0, "WSAAddressToStringA, error %d\n", WSAGetLastError());
+            ok(dwAddrLen > 7, "len <= 7\n");
+            err = send(sockaccept, address, dwAddrLen, 0);
+            ok(err == dwAddrLen, "ERROR: error sending data on accepted socket, error %d\n", WSAGetLastError());
+        }
+    }
+
+    closesocket(sockaccept);
+    closesocket(ServerSocket);
+    closesocket(ClientSocket);
+
+    WSACleanup();
+}
index 7ee41a5..b49c8c6 100644 (file)
@@ -8,6 +8,7 @@ extern void func_getnameinfo(void);
 extern void func_getservbyname(void);
 extern void func_getservbyport(void);
 extern void func_ioctlsocket(void);
+extern void func_nonblocking(void);
 extern void func_nostartup(void);
 extern void func_recv(void);
 extern void func_send(void);
@@ -23,6 +24,7 @@ const struct test winetest_testlist[] =
     { "getservbyname", func_getservbyname },
     { "getservbyport", func_getservbyport },
     { "ioctlsocket", func_ioctlsocket },
+    { "nonblocking", func_nonblocking },
     { "nostartup", func_nostartup },
     { "recv", func_recv },
     { "send", func_send },