Patch: winsock-test.diff Author: Martin.Wilck@Fujitsu-Siemens.com Modified files: dlls/winsock: sock.c Makefile.in Added files: dlls/winsock: simple_server.c simple_client.c event_client.c simple_test.c event_test.c This patch is large, but it actually adds no code. The winsock unit tests is just split up over several files, most of which (except simple_test.c, event_test.c) act only as include files. Rationale: - Make it easier to add new unit tests. - Conform better to the usual wine unit testing scheme (instead of running different tests from the same file, run separate files testing different functionality) diff -ruNX ignore CVS/wine/dlls/winsock/tests/Makefile.in TMP/wine/dlls/winsock/tests/Makefile.in --- CVS/wine/dlls/winsock/tests/Makefile.in Fri Aug 9 03:22:41 2002 +++ TMP/wine/dlls/winsock/tests/Makefile.in Wed Sep 4 16:33:18 2002 @@ -6,7 +6,8 @@ IMPORTS = ws2_32 CTESTS = \ - sock.c + simple_test.c \ + event_test.c @MAKE_TEST_RULES@ diff -ruNX ignore CVS/wine/dlls/winsock/tests/event_client.c TMP/wine/dlls/winsock/tests/event_client.c --- CVS/wine/dlls/winsock/tests/event_client.c Thu Jan 1 01:00:00 1970 +++ TMP/wine/dlls/winsock/tests/event_client.c Wed Sep 4 16:42:47 2002 @@ -0,0 +1,147 @@ +/* + * Unit test suite for winsock functions + * + * Copyright 2002 Martin Wilck + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * event_client: An event-driven client + */ +static void WINAPI event_client ( client_params *par ) +{ + test_params *gen = par->general; + client_memory *mem; + int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size, + tmp, err, n; + HANDLE event; + WSANETWORKEVENTS wsa_events; + char *send_last, *recv_last, *send_p, *recv_p; + long mask = FD_READ | FD_WRITE | FD_CLOSE; + + trace ( "event_client (%x): starting\n", id ); + client_start ( par ); + trace ( "event_client (%x): server ready\n", id ); + + mem = TlsGetValue ( tls ); + + /* Prepare event notification for connect, makes socket nonblocking */ + event = WSACreateEvent (); + WSAEventSelect ( mem->s, event, FD_CONNECT ); + tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ); + if ( tmp != 0 && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) + ok ( 0, "event_client (%x): connect error: %d", id, err ); + + tmp = WaitForSingleObject ( event, INFINITE ); + ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d", id, tmp ); + err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); + wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); + + err = wsa_events.iErrorCode[ FD_CONNECT_BIT ]; + ok ( err == 0, "event_client (%x): connect error: %d", id, err ); + if ( err ) goto out; + + trace ( "event_client (%x) connected\n", id ); + + WSAEventSelect ( mem->s, event, mask ); + + recv_p = mem->recv_buf; + recv_last = mem->recv_buf + n_expected; + send_p = mem->send_buf; + send_last = mem->send_buf + n_expected; + + while ( TRUE ) + { + err = WaitForSingleObject ( event, INFINITE ); + ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed", id ); + + err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); + wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); + + if ( wsa_events.lNetworkEvents & FD_WRITE ) + { + err = wsa_events.iErrorCode[ FD_WRITE_BIT ]; + ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err ); + + if ( err== 0 ) + do + { + n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 ); + if ( n < 0 ) + { + err = WSAGetLastError (); + ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err ); + } + else + send_p += n; + } + while ( n >= 0 && send_p < send_last ); + + if ( send_p == send_last ) + { + trace ( "event_client (%x): all data sent - shutdown\n", id ); + shutdown ( mem->s, SD_SEND ); + mask &= ~FD_WRITE; + WSAEventSelect ( mem->s, event, mask ); + } + } + else if ( wsa_events.lNetworkEvents & FD_READ ) + { + err = wsa_events.iErrorCode[ FD_READ_BIT ]; + ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err ); + + n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 ); + wsa_ok ( n, 0 <=, "event_client (%lx): recv error: %d\n" ); + if ( err != 0 || n < 0 ) + break; + else if ( n == 0 ) + { + ok ( 0, "event_client (%x): empty receive", id ); + break; + } + + recv_p += n; + if ( recv_p == recv_last ) + { + trace ( "event_client (%x): all data received\n", id ); + mask &= ~FD_READ; + WSAEventSelect ( mem->s, event, mask ); + } + } + else if ( wsa_events.lNetworkEvents & FD_CLOSE ) + { + trace ( "event_client (%x): close event\n", id ); + err = wsa_events.iErrorCode[ FD_CLOSE_BIT ]; + ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err ); + break; + } + } + + ok ( send_p == send_last, + "simple_client (%x): sent less data then expected: %d of %d", + id, send_p - mem->send_buf, n_expected ); + ok ( recv_p == recv_last, + "simple_client (%x): received less data then expected: %d of %d", + id, recv_p - mem->recv_buf, n_expected ); + recv_p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); + ok ( recv_p == NULL, "event_client (%x): test pattern error: %d", id, recv_p - mem->recv_buf); + +out: + WSACloseEvent ( event ); + trace ( "event_client (%x) exiting\n", id ); + client_stop (); +} + diff -ruNX ignore CVS/wine/dlls/winsock/tests/event_test.c TMP/wine/dlls/winsock/tests/event_test.c --- CVS/wine/dlls/winsock/tests/event_test.c Thu Jan 1 01:00:00 1970 +++ TMP/wine/dlls/winsock/tests/event_test.c Wed Sep 4 16:35:07 2002 @@ -0,0 +1,73 @@ +/* + * Unit test suite for winsock functions + * + * Copyright 2002 Martin Wilck + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/**************** Utility functions & macros ***************/ +#include "sock.c" + +/**************** Servers ***************/ +#include "simple_server.c" + +/**************** Clients ***************/ +#include "event_client.c" + +/************* Array containing the tests to run **********/ + + +static test_setup tests [] = +{ + /* Test 0: synchronous client and server */ + { + { + STD_STREAM_SOCKET, /* sock_type, sock_prot, inet_addr, inet_port */ + 2048, /* chunk_size */ + 16, /* n_chunks */ + 2 /* n_clients */ + }, + simple_server, /* server routine */ + { + NULL, + 0, /* sock_flags */ + 64 /* buflen */ + }, + event_client, /* client routine */ + { + NULL, + 0, /* sock_flags */ + 128 /* buflen */ + } + } +}; + +/**************** Main program ***************/ + +START_TEST( event_test ) +{ + int i; + Init(); + + for (i = 0; i < NUM_TESTS; i++) + { + trace ( " **** STARTING TEST %d **** \n", i ); + do_test ( &tests[i] ); + trace ( " **** TEST %d COMPLETE **** \n", i ); + } + + Exit(); +} diff -ruNX ignore CVS/wine/dlls/winsock/tests/simple_client.c TMP/wine/dlls/winsock/tests/simple_client.c --- CVS/wine/dlls/winsock/tests/simple_client.c Thu Jan 1 01:00:00 1970 +++ TMP/wine/dlls/winsock/tests/simple_client.c Wed Sep 4 16:43:20 2002 @@ -0,0 +1,71 @@ +/* + * Unit test suite for winsock functions + * + * Copyright 2002 Martin Wilck + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * simple_client: A very basic client doing synchronous IO. + */ +static VOID WINAPI simple_client ( client_params *par ) +{ + test_params *gen = par->general; + client_memory *mem; + int n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id; + char *p; + + id = GetCurrentThreadId(); + trace ( "simple_client (%x): starting\n", id ); + /* wait here because we want to call set_so_opentype before creating a socket */ + WaitForSingleObject ( server_ready, INFINITE ); + trace ( "simple_client (%x): server ready\n", id ); + + check_so_opentype (); + set_so_opentype ( FALSE ); /* non-overlapped */ + client_start ( par ); + mem = TlsGetValue ( tls ); + + /* Connect */ + wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ), + 0 ==, "simple_client (%lx): connect error: %d" ); + ok ( set_blocking ( mem->s, TRUE ) == 0, + "simple_client (%x): failed to set blocking mode", id ); + trace ( "simple_client (%x) connected\n", id ); + + /* send data to server */ + n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen ); + ok ( n_sent == n_expected, + "simple_client (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); + + /* shutdown send direction */ + wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d" ); + + /* Receive data echoed back & check it */ + n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen ); + ok ( n_recvd == n_expected, + "simple_client (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); + + /* check data */ + p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); + ok ( p == NULL, "simple_client (%x): test pattern error: %d", id, p - mem->recv_buf); + + /* cleanup */ + read_zero_bytes ( mem->s ); + trace ( "simple_client (%x) exiting\n", id ); + client_stop (); +} + diff -ruNX ignore CVS/wine/dlls/winsock/tests/simple_server.c TMP/wine/dlls/winsock/tests/simple_server.c --- CVS/wine/dlls/winsock/tests/simple_server.c Thu Jan 1 01:00:00 1970 +++ TMP/wine/dlls/winsock/tests/simple_server.c Wed Sep 4 16:43:31 2002 @@ -0,0 +1,77 @@ +/* + * Unit test suite for winsock functions + * + * Copyright 2002 Martin Wilck + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * simple_server: A very basic server doing synchronous IO. + */ +static VOID WINAPI simple_server ( server_params *par ) +{ + test_params *gen = par->general; + server_memory *mem; + int n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i, + id = GetCurrentThreadId(); + char *p; + + trace ( "simple_server (%x) starting\n", id ); + + set_so_opentype ( FALSE ); /* non-overlapped */ + server_start ( par ); + mem = TlsGetValue ( tls ); + + wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%lx): failed to set blocking mode: %d"); + wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%lx): listen failed: %d"); + + trace ( "simple_server (%x) ready\n", id ); + SetEvent ( server_ready ); /* notify clients */ + + for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ ) + { + trace ( "simple_server (%x): waiting for client\n", id ); + + /* accept a single connection */ + tmp = sizeof ( mem->sock[0].peer ); + mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp ); + wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%lx): accept failed: %d" ); + + ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ), + "simple_server (%x): strange peer address", id ); + + /* Receive data & check it */ + n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); + ok ( n_recvd == n_expected, + "simple_server (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); + p = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks ); + ok ( p == NULL, "simple_server (%x): test pattern error: %d", id, p - mem->sock[0].buf); + + /* Echo data back */ + n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); + ok ( n_sent == n_expected, + "simple_server (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); + + /* cleanup */ + read_zero_bytes ( mem->sock[0].s ); + wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%lx): closesocket error: %d" ); + mem->sock[0].s = INVALID_SOCKET; + } + + trace ( "simple_server (%x) exiting\n", id ); + server_stop (); +} + diff -ruNX ignore CVS/wine/dlls/winsock/tests/simple_test.c TMP/wine/dlls/winsock/tests/simple_test.c --- CVS/wine/dlls/winsock/tests/simple_test.c Thu Jan 1 01:00:00 1970 +++ TMP/wine/dlls/winsock/tests/simple_test.c Wed Sep 4 16:35:31 2002 @@ -0,0 +1,73 @@ +/* + * Unit test suite for winsock functions + * + * Copyright 2002 Martin Wilck + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/**************** Utility functions & macros ***************/ +#include "sock.c" + +/**************** Servers ***************/ +#include "simple_server.c" + +/**************** Clients ***************/ +#include "simple_client.c" + +/************* Array containing the tests to run **********/ + + +static test_setup tests [] = +{ + /* Test 0: synchronous client and server */ + { + { + STD_STREAM_SOCKET, /* sock_type, sock_prot, inet_addr, inet_port */ + 2048, /* chunk_size */ + 16, /* n_chunks */ + 2 /* n_clients */ + }, + simple_server, /* server routine */ + { + NULL, + 0, /* sock_flags */ + 64 /* buflen */ + }, + simple_client, /* client routine */ + { + NULL, + 0, /* sock_flags */ + 128 /* buflen */ + } + } +}; + +/**************** Main program ***************/ + +START_TEST( simple_test ) +{ + int i; + Init(); + + for (i = 0; i < NUM_TESTS; i++) + { + trace ( " **** STARTING TEST %d **** \n", i ); + do_test ( &tests[i] ); + trace ( " **** TEST %d COMPLETE **** \n", i ); + } + + Exit(); +} diff -ruNX ignore CVS/wine/dlls/winsock/tests/sock.c TMP/wine/dlls/winsock/tests/sock.c --- CVS/wine/dlls/winsock/tests/sock.c Tue Jun 25 16:04:43 2002 +++ TMP/wine/dlls/winsock/tests/sock.c Wed Sep 4 16:43:43 2002 @@ -27,12 +27,13 @@ #include <mswsock.h> #define MAX_CLIENTS 4 /* Max number of clients */ -#define NUM_TESTS 2 /* Number of tests performed */ #define FIRST_CHAR 'A' /* First character in transferred pattern */ #define BIND_SLEEP 10 /* seconds to wait between attempts to bind() */ #define BIND_TRIES 6 /* Number of bind() attempts */ #define TEST_TIMEOUT 30 /* seconds to wait before killing child threads after server initialization, if something hangs */ +#define NUM_TESTS (sizeof(tests) / sizeof (test_setup)) + #define wsa_ok(op, cond, msg) \ do { \ @@ -42,6 +43,11 @@ ok ( cond tmp, msg, GetCurrentThreadId(), err); \ } while (0); +#define STD_STREAM_SOCKET \ + SOCK_STREAM, \ + 0, \ + "127.0.0.1", \ + 9374 /**************** Structs and typedefs ***************/ @@ -311,246 +317,7 @@ ExitThread(0); } -/**************** Servers ***************/ - -/* - * simple_server: A very basic server doing synchronous IO. - */ -static VOID WINAPI simple_server ( server_params *par ) -{ - test_params *gen = par->general; - server_memory *mem; - int n_recvd, n_sent, n_expected = gen->n_chunks * gen->chunk_size, tmp, i, - id = GetCurrentThreadId(); - char *p; - - trace ( "simple_server (%x) starting\n", id ); - - set_so_opentype ( FALSE ); /* non-overlapped */ - server_start ( par ); - mem = TlsGetValue ( tls ); - - wsa_ok ( set_blocking ( mem->s, TRUE ), 0 ==, "simple_server (%lx): failed to set blocking mode: %d"); - wsa_ok ( listen ( mem->s, SOMAXCONN ), 0 ==, "simple_server (%lx): listen failed: %d"); - - trace ( "simple_server (%x) ready\n", id ); - SetEvent ( server_ready ); /* notify clients */ - - for ( i = 0; i < min ( gen->n_clients, MAX_CLIENTS ); i++ ) - { - trace ( "simple_server (%x): waiting for client\n", id ); - - /* accept a single connection */ - tmp = sizeof ( mem->sock[0].peer ); - mem->sock[0].s = accept ( mem->s, (struct sockaddr*) &mem->sock[0].peer, &tmp ); - wsa_ok ( mem->sock[0].s, INVALID_SOCKET !=, "simple_server (%lx): accept failed: %d" ); - - ok ( mem->sock[0].peer.sin_addr.s_addr == inet_addr ( gen->inet_addr ), - "simple_server (%x): strange peer address", id ); - - /* Receive data & check it */ - n_recvd = do_synchronous_recv ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); - ok ( n_recvd == n_expected, - "simple_server (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); - p = test_buffer ( mem->sock[0].buf, gen->chunk_size, gen->n_chunks ); - ok ( p == NULL, "simple_server (%x): test pattern error: %d", id, p - mem->sock[0].buf); - - /* Echo data back */ - n_sent = do_synchronous_send ( mem->sock[0].s, mem->sock[0].buf, n_expected, par->buflen ); - ok ( n_sent == n_expected, - "simple_server (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); - - /* cleanup */ - read_zero_bytes ( mem->sock[0].s ); - wsa_ok ( closesocket ( mem->sock[0].s ), 0 ==, "simple_server (%lx): closesocket error: %d" ); - mem->sock[0].s = INVALID_SOCKET; - } - - trace ( "simple_server (%x) exiting\n", id ); - server_stop (); -} - -/**************** Clients ***************/ - -/* - * simple_client: A very basic client doing synchronous IO. - */ -static VOID WINAPI simple_client ( client_params *par ) -{ - test_params *gen = par->general; - client_memory *mem; - int n_sent, n_recvd, n_expected = gen->n_chunks * gen->chunk_size, id; - char *p; - - id = GetCurrentThreadId(); - trace ( "simple_client (%x): starting\n", id ); - /* wait here because we want to call set_so_opentype before creating a socket */ - WaitForSingleObject ( server_ready, INFINITE ); - trace ( "simple_client (%x): server ready\n", id ); - - check_so_opentype (); - set_so_opentype ( FALSE ); /* non-overlapped */ - client_start ( par ); - mem = TlsGetValue ( tls ); - - /* Connect */ - wsa_ok ( connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ), - 0 ==, "simple_client (%lx): connect error: %d" ); - ok ( set_blocking ( mem->s, TRUE ) == 0, - "simple_client (%x): failed to set blocking mode", id ); - trace ( "simple_client (%x) connected\n", id ); - - /* send data to server */ - n_sent = do_synchronous_send ( mem->s, mem->send_buf, n_expected, par->buflen ); - ok ( n_sent == n_expected, - "simple_client (%x): sent less data then expected: %d of %d", id, n_sent, n_expected ); - - /* shutdown send direction */ - wsa_ok ( shutdown ( mem->s, SD_SEND ), 0 ==, "simple_client (%lx): shutdown failed: %d" ); - - /* Receive data echoed back & check it */ - n_recvd = do_synchronous_recv ( mem->s, mem->recv_buf, n_expected, par->buflen ); - ok ( n_recvd == n_expected, - "simple_client (%x): received less data then expected: %d of %d", id, n_recvd, n_expected ); - - /* check data */ - p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); - ok ( p == NULL, "simple_client (%x): test pattern error: %d", id, p - mem->recv_buf); - - /* cleanup */ - read_zero_bytes ( mem->s ); - trace ( "simple_client (%x) exiting\n", id ); - client_stop (); -} - -/* - * event_client: An event-driven client - */ -static void WINAPI event_client ( client_params *par ) -{ - test_params *gen = par->general; - client_memory *mem; - int id = GetCurrentThreadId(), n_expected = gen->n_chunks * gen->chunk_size, - tmp, err, n; - HANDLE event; - WSANETWORKEVENTS wsa_events; - char *send_last, *recv_last, *send_p, *recv_p; - long mask = FD_READ | FD_WRITE | FD_CLOSE; - - trace ( "event_client (%x): starting\n", id ); - client_start ( par ); - trace ( "event_client (%x): server ready\n", id ); - - mem = TlsGetValue ( tls ); - - /* Prepare event notification for connect, makes socket nonblocking */ - event = WSACreateEvent (); - WSAEventSelect ( mem->s, event, FD_CONNECT ); - tmp = connect ( mem->s, (struct sockaddr*) &mem->addr, sizeof ( mem->addr ) ); - if ( tmp != 0 && ( err = WSAGetLastError () ) != WSAEWOULDBLOCK ) - ok ( 0, "event_client (%x): connect error: %d", id, err ); - - tmp = WaitForSingleObject ( event, INFINITE ); - ok ( tmp == WAIT_OBJECT_0, "event_client (%x): wait for connect event failed: %d", id, tmp ); - err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); - wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); - - err = wsa_events.iErrorCode[ FD_CONNECT_BIT ]; - ok ( err == 0, "event_client (%x): connect error: %d", id, err ); - if ( err ) goto out; - - trace ( "event_client (%x) connected\n", id ); - - WSAEventSelect ( mem->s, event, mask ); - - recv_p = mem->recv_buf; - recv_last = mem->recv_buf + n_expected; - send_p = mem->send_buf; - send_last = mem->send_buf + n_expected; - - while ( TRUE ) - { - err = WaitForSingleObject ( event, INFINITE ); - ok ( err == WAIT_OBJECT_0, "event_client (%x): wait failed", id ); - - err = WSAEnumNetworkEvents ( mem->s, event, &wsa_events ); - wsa_ok ( err, 0 ==, "event_client (%lx): WSAEnumNetworkEvents error: %d\n" ); - - if ( wsa_events.lNetworkEvents & FD_WRITE ) - { - err = wsa_events.iErrorCode[ FD_WRITE_BIT ]; - ok ( err == 0, "event_client (%x): FD_WRITE error code: %d\n", id, err ); - - if ( err== 0 ) - do - { - n = send ( mem->s, send_p, min ( send_last - send_p, par->buflen ), 0 ); - if ( n < 0 ) - { - err = WSAGetLastError (); - ok ( err == WSAEWOULDBLOCK, "event_client (%x): send error: %d\n", id, err ); - } - else - send_p += n; - } - while ( n >= 0 && send_p < send_last ); - - if ( send_p == send_last ) - { - trace ( "event_client (%x): all data sent - shutdown\n", id ); - shutdown ( mem->s, SD_SEND ); - mask &= ~FD_WRITE; - WSAEventSelect ( mem->s, event, mask ); - } - } - else if ( wsa_events.lNetworkEvents & FD_READ ) - { - err = wsa_events.iErrorCode[ FD_READ_BIT ]; - ok ( err == 0, "event_client (%x): FD_READ error code: %d\n", id, err ); - - n = recv ( mem->s, recv_p, min ( recv_last - recv_p, par->buflen ), 0 ); - wsa_ok ( n, 0 <=, "event_client (%lx): recv error: %d\n" ); - if ( err != 0 || n < 0 ) - break; - else if ( n == 0 ) - { - ok ( 0, "event_client (%x): empty receive", id ); - break; - } - - recv_p += n; - if ( recv_p == recv_last ) - { - trace ( "event_client (%x): all data received\n", id ); - mask &= ~FD_READ; - WSAEventSelect ( mem->s, event, mask ); - } - } - else if ( wsa_events.lNetworkEvents & FD_CLOSE ) - { - trace ( "event_client (%x): close event\n", id ); - err = wsa_events.iErrorCode[ FD_CLOSE_BIT ]; - ok ( err == 0, "event_client (%x): FD_CLOSE error code: %d\n", id, err ); - break; - } - } - - ok ( send_p == send_last, - "simple_client (%x): sent less data then expected: %d of %d", - id, send_p - mem->send_buf, n_expected ); - ok ( recv_p == recv_last, - "simple_client (%x): received less data then expected: %d of %d", - id, recv_p - mem->recv_buf, n_expected ); - recv_p = test_buffer ( mem->recv_buf, gen->chunk_size, gen->n_chunks ); - ok ( recv_p == NULL, "event_client (%x): test pattern error: %d", id, recv_p - mem->recv_buf); - -out: - WSACloseEvent ( event ); - trace ( "event_client (%x) exiting\n", id ); - client_stop (); -} - -/**************** Main program utility functions ***************/ +/*************** Main program utility functions ***************/ static void Init (void) { @@ -620,73 +387,3 @@ CloseHandle ( client_ready[i] ); } -/************* Array containing the tests to run **********/ - -#define STD_STREAM_SOCKET \ - SOCK_STREAM, \ - 0, \ - "127.0.0.1", \ - 9374 - -static test_setup tests [NUM_TESTS] = -{ - /* Test 0: synchronous client and server */ - { - { - STD_STREAM_SOCKET, - 2048, - 16, - 2 - }, - simple_server, - { - NULL, - 0, - 64 - }, - simple_client, - { - NULL, - 0, - 128 - } - }, - /* Test 1: event-driven client, synchronous server */ - { - { - STD_STREAM_SOCKET, - 2048, - 16, - 2 - }, - simple_server, - { - NULL, - 0, - 64 - }, - event_client, - { - NULL, - 0, - 128 - } - } -}; - -/**************** Main program ***************/ - -START_TEST( sock ) -{ - int i; - Init(); - - for (i = 0; i < NUM_TESTS; i++) - { - trace ( " **** STARTING TEST %d **** \n", i ); - do_test ( &tests[i] ); - trace ( " **** TEST %d COMPLETE **** \n", i ); - } - - Exit(); -} -- Martin Wilck Phone: +49 5251 8 15113 Fujitsu Siemens Computers Fax: +49 5251 8 20409 Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck@Fujitsu-Siemens.com D-33106 Paderborn http://www.fujitsu-siemens.com/primergy