[4/4] ws2_32/tests: Add more select() tests
Bruno Jesus
00cpxxx at gmail.com
Fri Mar 6 12:25:16 CST 2015
These tests combined with existing tests show all remaining
differences between select for bug
https://bugs.winehq.org/show_bug.cgi?id=9425
-------------- next part --------------
---
dlls/ws2_32/tests/sock.c | 121 ++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 108 insertions(+), 13 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 360a0a1..15c0298 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -3387,16 +3387,19 @@ static void test_listen(void)
ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
}
+#define FD_ZERO_ALL() { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); }
+#define FD_SET_ALL(s) { FD_SET(s, &readfds); FD_SET(s, &writefds); FD_SET(s, &exceptfds); }
static void test_select(void)
{
static const char tmp_buf[1024];
- SOCKET fdRead, fdWrite;
+ SOCKET fdListen, fdRead, fdWrite;
fd_set readfds, writefds, exceptfds;
unsigned int maxfd;
- int ret;
+ int ret, len;
char buffer;
struct timeval select_timeout;
+ struct sockaddr_in address;
select_thread_params thread_params;
HANDLE thread_handle;
DWORD id;
@@ -3405,14 +3408,10 @@ static void test_select(void)
ok( (fdRead != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
fdWrite = socket(AF_INET, SOCK_STREAM, 0);
ok( (fdWrite != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptfds);
- FD_SET(fdRead, &readfds);
- FD_SET(fdWrite, &writefds);
- FD_SET(fdRead, &exceptfds);
- FD_SET(fdWrite, &exceptfds);
+
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdRead);
+ FD_SET_ALL(fdWrite);
select_timeout.tv_sec=0;
select_timeout.tv_usec=500;
@@ -3453,9 +3452,7 @@ static void test_select(void)
ok( (ret == -1), "peek at closed socket expected -1 got %d\n", ret);
/* Test selecting invalid handles */
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptfds);
+ FD_ZERO_ALL();
SetLastError(0);
ret = select(maxfd+1, 0, 0, 0, &select_timeout);
@@ -3562,7 +3559,105 @@ static void test_select(void)
closesocket(fdRead);
closesocket(fdWrite);
+
+ /* select() works in 3 distinct states:
+ * - to check if a connection attempt ended with success or error;
+ * - to check if a pending connection is waiting for acceptance;
+ * - to check for data to read, avaliability for write and OOB data
+ *
+ * The tests below ensure that all conditions are tested.
+ */
+ memset(&address, 0, sizeof(address));
+ address.sin_addr.s_addr = inet_addr("127.0.0.1");
+ address.sin_family = AF_INET;
+ len = sizeof(address);
+ fdListen = setup_server_socket(&address, &len);
+ select_timeout.tv_sec = 1;
+ select_timeout.tv_usec = 250000;
+
+ /* When a socket is attempting to connect the listening socket receives the read descriptor */
+ fdWrite = setup_connector_socket(&address, len, TRUE);
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdListen);
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok(FD_ISSET(fdListen, &readfds), "fdListen socket is not in the set\n");
+ len = sizeof(address);
+ fdRead = accept(fdListen, (struct sockaddr*) &address, &len);
+ ok(fdRead != INVALID_SOCKET, "expected a valid socket\n");
+
+ /* The connector is signaled through the write descriptor */
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdListen);
+ FD_SET_ALL(fdRead);
+ FD_SET_ALL(fdWrite);
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+ ok(ret == 2, "expected 2, got %d\n", ret);
+ ok(FD_ISSET(fdWrite, &writefds), "fdWrite socket is not in the set\n");
+ ok(FD_ISSET(fdRead, &writefds), "fdRead socket is not in the set\n");
+
+ /* When data is received the receiver gets the read descriptor */
+ ret = send(fdWrite, "1234", 4, 0);
+ ok(ret == 4, "expected 4, got %d\n", ret);
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdListen);
+ FD_SET(fdRead, &readfds);
+ FD_SET(fdRead, &exceptfds);
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok(FD_ISSET(fdRead, &readfds), "fdRead socket is not in the set\n");
+ ret = recv(fdRead, (char*) tmp_buf, sizeof(tmp_buf), 0);
+ ok(ret == 4, "expected 4, got %d\n", ret);
+ ok(!strcmp((char*) tmp_buf, "1234"), "data received differs from sent\n");
+
+ /* When OOB data is received the socket is set in the except descriptor */
+ ret = send(fdWrite, "A", 1, MSG_OOB);
+ ok(ret == 1, "expected 4, got %d\n", ret);
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdListen);
+ FD_SET(fdRead, &readfds);
+ FD_SET(fdRead, &exceptfds);
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+todo_wine
+ ok(ret == 1, "expected 1, got %d\n", ret);
+todo_wine
+ ok(FD_ISSET(fdRead, &exceptfds), "fdRead socket is not in the set\n");
+ ret = recv(fdRead, (char*) tmp_buf, sizeof(tmp_buf), MSG_OOB);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok(tmp_buf[0] == 'A', "expected 'A', got %c\n", tmp_buf[0]);
+
+ /* When the connection is closed the socket is set in the read descriptor */
+ ret = closesocket(fdRead);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+ FD_ZERO_ALL();
+ FD_SET_ALL(fdListen);
+ FD_SET(fdWrite, &readfds);
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok(FD_ISSET(fdWrite, &readfds), "fdWrite socket is not in the set\n");
+ ret = recv(fdWrite, (char*) tmp_buf, sizeof(tmp_buf), 0);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+
+ /* When a connection is attempted to a non-listening socket it will get to the except descriptor */
+ ret = closesocket(fdWrite);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+ ret = closesocket(fdListen);
+ ok(ret == 0, "expected 0, got %d\n", ret);
+ fdWrite = setup_connector_socket(&address, len, TRUE);
+ FD_ZERO_ALL();
+ FD_SET(fdWrite, &writefds);
+ FD_SET(fdWrite, &exceptfds);
+ select_timeout.tv_sec = 2; /* requires more time to realize it will not connect */
+ ret = select(0, &readfds, &writefds, &exceptfds, &select_timeout);
+todo_wine
+ ok(ret == 1, "expected 1, got %d\n", ret);
+todo_wine
+ ok(FD_ISSET(fdWrite, &exceptfds), "fdWrite socket is not in the set\n");
+ ok(select_timeout.tv_usec == 250000, "select timeout should not have changed\n");
+ closesocket(fdWrite);
}
+#undef FD_SET_ALL
+#undef FD_ZERO_ALL
static DWORD WINAPI AcceptKillThread(void *param)
{
--
1.8.3.2
More information about the wine-patches
mailing list