From 373bee1800e8c4c8cfd5ec6829ebf13a0f4342b7 Mon Sep 17 00:00:00 2001 From: Peter Hater <7element@mail.bg> Date: Thu, 10 Nov 2016 15:13:19 +0000 Subject: [PATCH] [WS2_32_APITESTS] Add nonblocking tests svn path=/trunk/; revision=73195 --- rostests/apitests/ws2_32/CMakeLists.txt | 1 + rostests/apitests/ws2_32/nonblocking.c | 135 ++++++++++++++++++++++++ rostests/apitests/ws2_32/testlist.c | 2 + 3 files changed, 138 insertions(+) create mode 100644 rostests/apitests/ws2_32/nonblocking.c diff --git a/rostests/apitests/ws2_32/CMakeLists.txt b/rostests/apitests/ws2_32/CMakeLists.txt index d3af38835b1..f3e95495881 100644 --- a/rostests/apitests/ws2_32/CMakeLists.txt +++ b/rostests/apitests/ws2_32/CMakeLists.txt @@ -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 index 00000000000..40286cb1751 --- /dev/null +++ b/rostests/apitests/ws2_32/nonblocking.c @@ -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 + +#include +#include +#include + +#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(); +} diff --git a/rostests/apitests/ws2_32/testlist.c b/rostests/apitests/ws2_32/testlist.c index 7ee41a5a3f2..b49c8c6a200 100644 --- a/rostests/apitests/ws2_32/testlist.c +++ b/rostests/apitests/ws2_32/testlist.c @@ -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 },