123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- /***********************************************************************
- ** 1996 - Netscape Communications Corporation
- **
- ** Name: accept.c
- **
- ** Description: Run accept() sucessful connection tests.
- **
- ** Modification History:
- ** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL
- ** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode
- ** The debug mode will print all of the printfs associated with this test.
- ** The regress mode will be the default mode. Since the regress tool limits
- ** the output to a one line status:PASS or FAIL,all of the printf statements
- ** have been handled with an if (debug_mode) statement.
- ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
- ** recognize the return code from tha main program.
- ** 12-June-97 Revert to return code 0 and 1.
- ***********************************************************************/
- /***********************************************************************
- ** Includes
- ***********************************************************************/
- #include "nspr.h"
- #include "prpriv.h"
- #include <stdlib.h>
- #include <string.h>
- #include "plgetopt.h"
- #include "plerror.h"
- #define BASE_PORT 10000
- #define CLIENT_DATA 128
- #define ACCEPT_NORMAL 0x1
- #define ACCEPT_FAST 0x2
- #define ACCEPT_READ 0x3
- #define ACCEPT_READ_FAST 0x4
- #define ACCEPT_READ_FAST_CB 0x5
- #define CLIENT_NORMAL 0x1
- #define CLIENT_TIMEOUT_ACCEPT 0x2
- #define CLIENT_TIMEOUT_SEND 0x3
- #define SERVER_MAX_BIND_COUNT 100
- #if defined(XP_OS2)
- #define TIMEOUTSECS 10
- #else
- #define TIMEOUTSECS 2
- #endif
- PRIntervalTime timeoutTime;
- static PRInt32 count = 1;
- static PRFileDesc *output;
- static PRNetAddr serverAddr;
- static PRThreadScope thread_scope = PR_LOCAL_THREAD;
- static PRInt32 clientCommand;
- static PRInt32 iterations;
- static PRStatus rv;
- static PRFileDesc *listenSock;
- static PRFileDesc *clientSock = NULL;
- static PRNetAddr listenAddr;
- static PRNetAddr clientAddr;
- static PRThread *clientThread;
- static PRNetAddr *raddr;
- static char buf[4096 + 2*sizeof(PRNetAddr) + 32];
- static PRInt32 status;
- static PRInt32 bytesRead;
- PRIntn failed_already=0;
- PRIntn debug_mode;
- void Test_Assert(const char *msg, const char *file, PRIntn line)
- {
- failed_already=1;
- if (debug_mode) {
- PR_fprintf(output, "@%s:%d ", file, line);
- PR_fprintf(output, msg);
- }
- } /* Test_Assert */
- #define TEST_ASSERT(expr) \
- if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__)
- #ifdef WINNT
- #define CALLBACK_MAGIC 0x12345678
- void timeout_callback(void *magic)
- {
- TEST_ASSERT(magic == (void *)CALLBACK_MAGIC);
- if (debug_mode) {
- PR_fprintf(output, "timeout callback called okay\n");
- }
- }
- #endif
- static void PR_CALLBACK
- ClientThread(void *_action)
- {
- PRInt32 action = * (PRInt32 *) _action;
- PRInt32 iterations = count;
- PRFileDesc *sock = NULL;
- serverAddr.inet.family = PR_AF_INET;
- serverAddr.inet.port = listenAddr.inet.port;
- serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
- for (; iterations--;) {
- PRInt32 rv;
- char buf[CLIENT_DATA];
- memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */
- sock = PR_NewTCPSocket();
- if (!sock) {
- if (!debug_mode) {
- failed_already=1;
- }
- else {
- PR_fprintf(output, "client: unable to create socket\n");
- }
- return;
- }
- if (action != CLIENT_TIMEOUT_ACCEPT) {
- if ((rv = PR_Connect(sock, &serverAddr,
- timeoutTime)) < 0) {
- if (!debug_mode) {
- failed_already=1;
- }
- else
- PR_fprintf(output,
- "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
- iterations, rv, PR_GetError(), PR_GetOSError());
- goto ErrorExit;
- }
- if (action != CLIENT_TIMEOUT_SEND) {
- if ((rv = PR_Send(sock, buf, CLIENT_DATA,
- 0, timeoutTime))< 0) {
- if (!debug_mode) {
- failed_already=1;
- } else {
- PR_fprintf(output,
- "client: unable to send to server (%d, %ld, %ld)\n",
- CLIENT_DATA, rv, PR_GetError());
- }
- goto ErrorExit;
- }
- } else {
- PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
- }
- } else {
- PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
- }
- if (debug_mode) {
- PR_fprintf(output, ".");
- }
- PR_Close(sock);
- sock = NULL;
- }
- if (debug_mode) {
- PR_fprintf(output, "\n");
- }
- ErrorExit:
- if (sock != NULL) {
- PR_Close(sock);
- }
- }
- static void
- RunTest(PRInt32 acceptType, PRInt32 clientAction)
- {
- int i;
- /* First bind to the socket */
- listenSock = PR_NewTCPSocket();
- if (!listenSock) {
- failed_already=1;
- if (debug_mode) {
- PR_fprintf(output, "unable to create listen socket\n");
- }
- return;
- }
- memset(&listenAddr, 0, sizeof(listenAddr));
- listenAddr.inet.family = PR_AF_INET;
- listenAddr.inet.port = PR_htons(BASE_PORT);
- listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
- /*
- * try a few times to bind server's address, if addresses are in
- * use
- */
- i = 0;
- while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) {
- if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
- listenAddr.inet.port += 2;
- if (i++ < SERVER_MAX_BIND_COUNT) {
- continue;
- }
- }
- failed_already=1;
- if (debug_mode) {
- PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
- }
- return;
- }
- rv = PR_Listen(listenSock, 100);
- if (rv == PR_FAILURE) {
- failed_already=1;
- if (debug_mode) {
- PR_fprintf(output, "unable to listen\n");
- }
- return;
- }
- clientCommand = clientAction;
- clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
- (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
- PR_JOINABLE_THREAD, 0);
- if (!clientThread) {
- failed_already=1;
- if (debug_mode) {
- PR_fprintf(output, "error creating client thread\n");
- }
- return;
- }
- iterations = count;
- for (; iterations--;) {
- switch (acceptType) {
- case ACCEPT_NORMAL:
- clientSock = PR_Accept(listenSock, &clientAddr,
- timeoutTime);
- switch(clientAction) {
- case CLIENT_TIMEOUT_ACCEPT:
- TEST_ASSERT(clientSock == 0);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- case CLIENT_NORMAL:
- TEST_ASSERT(clientSock);
- bytesRead = PR_Recv(clientSock,
- buf, CLIENT_DATA, 0, timeoutTime);
- TEST_ASSERT(bytesRead == CLIENT_DATA);
- break;
- case CLIENT_TIMEOUT_SEND:
- TEST_ASSERT(clientSock);
- bytesRead = PR_Recv(clientSock,
- buf, CLIENT_DATA, 0, timeoutTime);
- TEST_ASSERT(bytesRead == -1);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- }
- break;
- case ACCEPT_READ:
- status = PR_AcceptRead(listenSock, &clientSock,
- &raddr, buf, CLIENT_DATA, timeoutTime);
- switch(clientAction) {
- case CLIENT_TIMEOUT_ACCEPT:
- /* Invalid test case */
- TEST_ASSERT(0);
- break;
- case CLIENT_NORMAL:
- TEST_ASSERT(clientSock);
- TEST_ASSERT(status == CLIENT_DATA);
- break;
- case CLIENT_TIMEOUT_SEND:
- TEST_ASSERT(status == -1);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- }
- break;
- #ifdef WINNT
- case ACCEPT_FAST:
- clientSock = PR_NTFast_Accept(listenSock,
- &clientAddr, timeoutTime);
- switch(clientAction) {
- case CLIENT_TIMEOUT_ACCEPT:
- TEST_ASSERT(clientSock == 0);
- if (debug_mode) {
- PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError());
- }
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- case CLIENT_NORMAL:
- TEST_ASSERT(clientSock);
- bytesRead = PR_Recv(clientSock,
- buf, CLIENT_DATA, 0, timeoutTime);
- TEST_ASSERT(bytesRead == CLIENT_DATA);
- break;
- case CLIENT_TIMEOUT_SEND:
- TEST_ASSERT(clientSock);
- bytesRead = PR_Recv(clientSock,
- buf, CLIENT_DATA, 0, timeoutTime);
- TEST_ASSERT(bytesRead == -1);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- }
- break;
- break;
- case ACCEPT_READ_FAST:
- status = PR_NTFast_AcceptRead(listenSock,
- &clientSock, &raddr, buf, 4096, timeoutTime);
- switch(clientAction) {
- case CLIENT_TIMEOUT_ACCEPT:
- /* Invalid test case */
- TEST_ASSERT(0);
- break;
- case CLIENT_NORMAL:
- TEST_ASSERT(clientSock);
- TEST_ASSERT(status == CLIENT_DATA);
- break;
- case CLIENT_TIMEOUT_SEND:
- TEST_ASSERT(clientSock == NULL);
- TEST_ASSERT(status == -1);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- }
- break;
- case ACCEPT_READ_FAST_CB:
- status = PR_NTFast_AcceptRead_WithTimeoutCallback(
- listenSock, &clientSock, &raddr, buf, 4096,
- timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
- switch(clientAction) {
- case CLIENT_TIMEOUT_ACCEPT:
- /* Invalid test case */
- TEST_ASSERT(0);
- break;
- case CLIENT_NORMAL:
- TEST_ASSERT(clientSock);
- TEST_ASSERT(status == CLIENT_DATA);
- break;
- case CLIENT_TIMEOUT_SEND:
- if (debug_mode) {
- PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock);
- }
- TEST_ASSERT(clientSock == NULL);
- TEST_ASSERT(status == -1);
- TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
- break;
- }
- break;
- #endif
- }
- if (clientSock != NULL) {
- PR_Close(clientSock);
- clientSock = NULL;
- }
- }
- PR_Close(listenSock);
- PR_JoinThread(clientThread);
- }
- void AcceptUpdatedTest(void)
- {
- RunTest(ACCEPT_NORMAL, CLIENT_NORMAL);
- }
- void AcceptNotUpdatedTest(void)
- {
- RunTest(ACCEPT_FAST, CLIENT_NORMAL);
- }
- void AcceptReadTest(void)
- {
- RunTest(ACCEPT_READ, CLIENT_NORMAL);
- }
- void AcceptReadNotUpdatedTest(void)
- {
- RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL);
- }
- void AcceptReadCallbackTest(void)
- {
- RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL);
- }
- void TimeoutAcceptUpdatedTest(void)
- {
- RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT);
- }
- void TimeoutAcceptNotUpdatedTest(void)
- {
- RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT);
- }
- void TimeoutAcceptReadCallbackTest(void)
- {
- RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT);
- }
- void TimeoutReadUpdatedTest(void)
- {
- RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND);
- }
- void TimeoutReadNotUpdatedTest(void)
- {
- RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND);
- }
- void TimeoutReadReadTest(void)
- {
- RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND);
- }
- void TimeoutReadReadNotUpdatedTest(void)
- {
- RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND);
- }
- void TimeoutReadReadCallbackTest(void)
- {
- RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND);
- }
- /************************************************************************/
- static void Measure(void (*func)(void), const char *msg)
- {
- PRIntervalTime start, stop;
- double d;
- start = PR_IntervalNow();
- (*func)();
- stop = PR_IntervalNow();
- d = (double)PR_IntervalToMicroseconds(stop - start);
- if (debug_mode) {
- PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count);
- }
- }
- int main(int argc, char **argv)
- {
- /* The command line argument: -d is used to determine if the test is being run
- in debug mode. The regress tool requires only one line output:PASS or FAIL.
- All of the printfs associated with this test has been handled with a if (debug_mode)
- test.
- Usage: test_name [-d] [-c n]
- */
- PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:");
- while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
- {
- if (PL_OPT_BAD == os) {
- continue;
- }
- switch (opt->option)
- {
- case 'G': /* global threads */
- thread_scope = PR_GLOBAL_THREAD;
- break;
- case 'd': /* debug mode */
- debug_mode = 1;
- break;
- case 'c': /* loop counter */
- count = atoi(opt->value);
- break;
- default:
- break;
- }
- }
- PL_DestroyOptState(opt);
- PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
- output = PR_STDERR;
- PR_STDIO_INIT();
- timeoutTime = PR_SecondsToInterval(TIMEOUTSECS);
- if (debug_mode) {
- PR_fprintf(output, "\nRun accept() sucessful connection tests\n");
- }
- Measure(AcceptUpdatedTest, "PR_Accept()");
- Measure(AcceptReadTest, "PR_AcceptRead()");
- #ifdef WINNT
- Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()");
- Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
- Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
- #endif
- if (debug_mode) {
- PR_fprintf(output, "\nRun accept() timeout in the accept tests\n");
- }
- #ifdef WINNT
- Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
- #endif
- Measure(TimeoutReadUpdatedTest, "PR_Accept()");
- if (debug_mode) {
- PR_fprintf(output, "\nRun accept() timeout in the read tests\n");
- }
- Measure(TimeoutReadReadTest, "PR_AcceptRead()");
- #ifdef WINNT
- Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
- Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
- Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
- #endif
- PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS");
- return failed_already;
- }
|