diff options
author | wtc%netscape.com <devnull@localhost> | 2000-05-26 23:14:23 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2000-05-26 23:14:23 +0000 |
commit | d2ba9eaa07e67665eb1303dd40ddcf1e6bea6641 (patch) | |
tree | 8cd8683d83e83784434d7a95e3892773fdc83889 | |
parent | 84837e6e2195d11a31b961ed386d4234e0897aa2 (diff) | |
download | nspr-hg-d2ba9eaa07e67665eb1303dd40ddcf1e6bea6641.tar.gz |
Bugzilla bug #34920: added new test acceptreademu.c to test
PR_EmulateAcceptRead.
Added file: acceptreademu.c
Modified files: Makefile, Makefile.in, runtests.ksh
-rw-r--r-- | pr/tests/Makefile | 1 | ||||
-rw-r--r-- | pr/tests/Makefile.in | 1 | ||||
-rw-r--r-- | pr/tests/acceptreademu.c | 283 | ||||
-rwxr-xr-x | pr/tests/runtests.ksh | 3 |
4 files changed, 287 insertions, 1 deletions
diff --git a/pr/tests/Makefile b/pr/tests/Makefile index e22a574d..8bc76955 100644 --- a/pr/tests/Makefile +++ b/pr/tests/Makefile @@ -39,6 +39,7 @@ endif CSRCS = \ accept.c \ acceptread.c \ + acceptreademu.c \ addrstr.c \ affinity.c \ alarm.c \ diff --git a/pr/tests/Makefile.in b/pr/tests/Makefile.in index b8634f52..7d73b2ee 100644 --- a/pr/tests/Makefile.in +++ b/pr/tests/Makefile.in @@ -44,6 +44,7 @@ endif CSRCS = \ accept.c \ acceptread.c \ + acceptreademu.c \ addrstr.c \ affinity.c \ alarm.c \ diff --git a/pr/tests/acceptreademu.c b/pr/tests/acceptreademu.c new file mode 100644 index 00000000..2dd2c32f --- /dev/null +++ b/pr/tests/acceptreademu.c @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* + * This test is the same as acceptread.c except that it uses the + * emulated acceptread method instead of the regular acceptread. + */ + +#include <prio.h> +#include <prprf.h> +#include <prinit.h> +#include <prnetdb.h> +#include <prinrval.h> +#include <prthread.h> +#include <pprio.h> + +#include <plerror.h> + +#include <stdlib.h> + +#define DEFAULT_PORT 12273 +#define GET "GET / HTTP/1.0\n\n" +static PRFileDesc *std_out, *err_out; +static PRIntervalTime write_dally, accept_timeout; +static PRDescIdentity emu_layer_ident; +static PRIOMethods emu_layer_methods; + +/* the acceptread method in emu_layer_methods */ +static PRInt32 PR_CALLBACK emu_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, + PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout) +{ + return PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout); +} + +static PRStatus PrintAddress(const PRNetAddr* address) +{ + char buffer[100]; + PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer)); + if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString"); + else PR_fprintf( + std_out, "Accepted connection from (0x%p)%s:%d\n", + address, buffer, address->inet.port); + return rv; +} /* PrintAddress */ + +static void ConnectingThread(void *arg) +{ + PRInt32 nbytes; + char buf[1024]; + PRFileDesc *sock; + PRNetAddr peer_addr, *addr; + + addr = (PRNetAddr*)arg; + + sock = PR_NewTCPSocket(); + if (sock == NULL) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed"); + PR_ProcessExit(1); + } + + if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_Connect (client) failed"); + PR_ProcessExit(1); + } + if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetPeerName (client) failed"); + PR_ProcessExit(1); + } + + /* + ** Then wait between the connection coming up and sending the expected + ** data. At some point in time, the server should fail due to a timeou + ** on the AcceptRead() operation, which according to the document is + ** only due to the read() portion. + */ + PR_Sleep(write_dally); + + nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed"); + + nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); + if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed"); + else + { + PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes); + buf[sizeof(buf) - 1] = '\0'; + PR_fprintf(std_out, "%s\n", buf); + } + + if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH)) + PL_FPrintError(err_out, "PR_Shutdown (client) failed"); + + if (PR_FAILURE == PR_Close(sock)) + PL_FPrintError(err_out, "PR_Close (client) failed"); + + return; +} /* ConnectingThread */ + +#define BUF_SIZE 117 +static void AcceptingThread(void *arg) +{ + PRStatus rv; + PRInt32 bytes; + PRSize buf_size = BUF_SIZE; + PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32]; + PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg; + PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket(); + PRFileDesc *layer; + PRSocketOptionData sock_opt; + + if (NULL == listen_sock) + { + PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed"); + PR_ProcessExit(1); + } + layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods); + if (NULL == layer) + { + PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed"); + PR_ProcessExit(1); + } + if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_PushIOLayer (server) failed"); + PR_ProcessExit(1); + } + sock_opt.option = PR_SockOpt_Reuseaddr; + sock_opt.value.reuse_addr = PR_TRUE; + rv = PR_SetSocketOption(listen_sock, &sock_opt); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_SetSocketOption (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Bind(listen_sock, listen_addr); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Bind (server) failed"); + PR_ProcessExit(1); + } + rv = PR_Listen(listen_sock, 10); + if (PR_FAILURE == rv) + { + PL_FPrintError(err_out, "PR_Listen (server) failed"); + PR_ProcessExit(1); + } + bytes = PR_AcceptRead( + listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout); + + if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed"); + else + { + PrintAddress(accept_addr); + PR_fprintf( + std_out, "(Server) read [0x%p..0x%p) %s\n", + buf, &buf[BUF_SIZE], buf); + bytes = PR_Write(accept_sock, buf, bytes); + rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Shutdown (server) failed"); + } + + if (-1 != bytes) + { + rv = PR_Close(accept_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); + } + + rv = PR_Close(listen_sock); + if (PR_FAILURE == rv) + PL_FPrintError(err_out, "PR_Close (server) failed"); +} /* AcceptingThread */ + +PRIntn main(PRIntn argc, char **argv) +{ + PRHostEnt he; + PRStatus status; + PRIntn next_index; + PRUint16 port_number; + char netdb_buf[PR_NETDB_BUF_SIZE]; + PRNetAddr client_addr, server_addr; + PRThread *client_thread, *server_thread; + PRIntervalTime delta = PR_MillisecondsToInterval(500); + + err_out = PR_STDERR; + std_out = PR_STDOUT; + accept_timeout = PR_SecondsToInterval(2); + emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); + emu_layer_methods = *PR_GetDefaultIOMethods(); + emu_layer_methods.acceptread = emu_AcceptRead; + + if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; + else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); + + status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + if (argc < 3) + { + status = PR_InitializeNetAddr( + PR_IpAddrLoopback, port_number, &client_addr); + if (PR_SUCCESS != status) + { + PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); + PR_ProcessExit(1); + } + } + else + { + status = PR_GetHostByName( + argv[1], netdb_buf, sizeof(netdb_buf), &he); + if (status == PR_FAILURE) + { + PL_FPrintError(err_out, "PR_GetHostByName failed"); + PR_ProcessExit(1); + } + next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); + if (next_index == -1) + { + PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); + PR_ProcessExit(1); + } + } + + for ( + write_dally = 0; + write_dally < accept_timeout + (2 * delta); + write_dally += delta) + { + PR_fprintf( + std_out, "Testing w/ write_dally = %d msec\n", + PR_IntervalToMilliseconds(write_dally)); + server_thread = PR_CreateThread( + PR_USER_THREAD, AcceptingThread, &server_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (server_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (server) failed"); + PR_ProcessExit(1); + } + + PR_Sleep(delta); /* let the server pot thicken */ + + client_thread = PR_CreateThread( + PR_USER_THREAD, ConnectingThread, &client_addr, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (client_thread == NULL) + { + PL_FPrintError(err_out, "PR_CreateThread (client) failed"); + PR_ProcessExit(1); + } + + if (PR_JoinThread(client_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (client) failed"); + + if (PR_JoinThread(server_thread) == PR_FAILURE) + PL_FPrintError(err_out, "PR_JoinThread (server) failed"); + } + + return 0; +} diff --git a/pr/tests/runtests.ksh b/pr/tests/runtests.ksh index d25943d7..e5a7182c 100755 --- a/pr/tests/runtests.ksh +++ b/pr/tests/runtests.ksh @@ -78,8 +78,9 @@ LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} # TESTS=" -acceptread accept +acceptread +acceptreademu affinity alarm anonfm |