nsprpub/pr/tests/accept.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/nsprpub/pr/tests/accept.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,487 @@
     1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +/***********************************************************************
    1.10 +**  1996 - Netscape Communications Corporation
    1.11 +**
    1.12 +** Name: accept.c
    1.13 +**
    1.14 +** Description: Run accept() sucessful connection tests.
    1.15 +**
    1.16 +** Modification History:
    1.17 +** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL
    1.18 +** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode 
    1.19 +**             The debug mode will print all of the printfs associated with this test.
    1.20 +**             The regress mode will be the default mode. Since the regress tool limits
    1.21 +**           the output to a one line status:PASS or FAIL,all of the printf statements
    1.22 +**             have been handled with an if (debug_mode) statement.
    1.23 +** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
    1.24 +**            recognize the return code from tha main program.
    1.25 +** 12-June-97 Revert to return code 0 and 1.
    1.26 +***********************************************************************/
    1.27 +
    1.28 +/***********************************************************************
    1.29 +** Includes
    1.30 +***********************************************************************/
    1.31 +
    1.32 +#include "nspr.h"
    1.33 +#include "prpriv.h"
    1.34 +
    1.35 +#include <stdlib.h>
    1.36 +#include <string.h>
    1.37 +
    1.38 +#include "plgetopt.h"
    1.39 +#include "plerror.h"
    1.40 +
    1.41 +#define BASE_PORT 10000
    1.42 +
    1.43 +#define CLIENT_DATA        128
    1.44 +
    1.45 +#define ACCEPT_NORMAL        0x1
    1.46 +#define ACCEPT_FAST        0x2
    1.47 +#define ACCEPT_READ        0x3
    1.48 +#define ACCEPT_READ_FAST    0x4
    1.49 +#define ACCEPT_READ_FAST_CB    0x5
    1.50 +
    1.51 +#define CLIENT_NORMAL        0x1
    1.52 +#define CLIENT_TIMEOUT_ACCEPT    0x2
    1.53 +#define CLIENT_TIMEOUT_SEND    0x3
    1.54 +
    1.55 +#define SERVER_MAX_BIND_COUNT        100
    1.56 +
    1.57 +#if defined(XP_OS2) || defined(SYMBIAN)
    1.58 +#define TIMEOUTSECS 10
    1.59 +#else
    1.60 +#define TIMEOUTSECS 2
    1.61 +#endif
    1.62 +PRIntervalTime timeoutTime;
    1.63 +
    1.64 +static PRInt32 count = 1;
    1.65 +static PRFileDesc *output;
    1.66 +static PRNetAddr serverAddr;
    1.67 +static PRThreadScope thread_scope = PR_LOCAL_THREAD;
    1.68 +static PRInt32 clientCommand;
    1.69 +static PRInt32 iterations;
    1.70 +static PRStatus rv;
    1.71 +static PRFileDesc *listenSock;
    1.72 +static PRFileDesc *clientSock = NULL;
    1.73 +static PRNetAddr listenAddr;
    1.74 +static PRNetAddr clientAddr;
    1.75 +static PRThread *clientThread;
    1.76 +static PRNetAddr *raddr;
    1.77 +static char buf[4096 + 2*sizeof(PRNetAddr) + 32];
    1.78 +static PRInt32 status;
    1.79 +static PRInt32 bytesRead;
    1.80 +
    1.81 +PRIntn failed_already=0;
    1.82 +PRIntn debug_mode;
    1.83 +
    1.84 +void Test_Assert(const char *msg, const char *file, PRIntn line)
    1.85 +{
    1.86 +    failed_already=1;
    1.87 +    if (debug_mode) {
    1.88 +        PR_fprintf(output,  "@%s:%d ", file, line);
    1.89 +        PR_fprintf(output, msg);
    1.90 +    }
    1.91 +}  /* Test_Assert */
    1.92 +
    1.93 +#define TEST_ASSERT(expr) \
    1.94 +    if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__)
    1.95 +
    1.96 +#ifdef WINNT
    1.97 +#define CALLBACK_MAGIC 0x12345678
    1.98 +
    1.99 +void timeout_callback(void *magic)
   1.100 +{
   1.101 +    TEST_ASSERT(magic == (void *)CALLBACK_MAGIC);
   1.102 +    if (debug_mode)
   1.103 +        PR_fprintf(output, "timeout callback called okay\n");
   1.104 +}
   1.105 +#endif
   1.106 +
   1.107 +
   1.108 +static void PR_CALLBACK
   1.109 +ClientThread(void *_action)
   1.110 +{
   1.111 +    PRInt32 action = * (PRInt32 *) _action;
   1.112 +    PRInt32 iterations = count;
   1.113 +    PRFileDesc *sock = NULL;
   1.114 +
   1.115 +    serverAddr.inet.family = PR_AF_INET;
   1.116 +    serverAddr.inet.port = listenAddr.inet.port;
   1.117 +    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
   1.118 +
   1.119 +    for (; iterations--;) {
   1.120 +        PRInt32 rv;
   1.121 +        char buf[CLIENT_DATA];
   1.122 +
   1.123 +        memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */
   1.124 +        sock = PR_NewTCPSocket();
   1.125 +        if (!sock) {
   1.126 +            if (!debug_mode)
   1.127 +                failed_already=1;
   1.128 +            else    
   1.129 +                PR_fprintf(output, "client: unable to create socket\n");
   1.130 +            return;
   1.131 +        }
   1.132 +
   1.133 +        if (action != CLIENT_TIMEOUT_ACCEPT) {
   1.134 +
   1.135 +            if ((rv = PR_Connect(sock, &serverAddr,
   1.136 +                timeoutTime)) < 0) {
   1.137 +                if (!debug_mode)
   1.138 +                    failed_already=1;
   1.139 +                else    
   1.140 +                    PR_fprintf(output, 
   1.141 +                        "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
   1.142 +                        iterations, rv, PR_GetError(), PR_GetOSError());
   1.143 +                goto ErrorExit;
   1.144 +            }
   1.145 +
   1.146 +            if (action != CLIENT_TIMEOUT_SEND) {
   1.147 +                if ((rv = PR_Send(sock, buf, CLIENT_DATA,
   1.148 +                    0, timeoutTime))< 0) {
   1.149 +                    if (!debug_mode)
   1.150 +                        failed_already=1;
   1.151 +                    else    
   1.152 +                        PR_fprintf(output, 
   1.153 +                            "client: unable to send to server (%d, %ld, %ld)\n",
   1.154 +                            CLIENT_DATA, rv, PR_GetError());
   1.155 +                	goto ErrorExit;
   1.156 +                }
   1.157 +            } else {
   1.158 +                PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
   1.159 +            }
   1.160 +        } else {
   1.161 +            PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
   1.162 +        }
   1.163 +        if (debug_mode)
   1.164 +            PR_fprintf(output, ".");
   1.165 +        PR_Close(sock);
   1.166 +		sock = NULL;
   1.167 +    }
   1.168 +    if (debug_mode)
   1.169 +        PR_fprintf(output, "\n");
   1.170 +
   1.171 +ErrorExit:
   1.172 +	if (sock != NULL)
   1.173 +        PR_Close(sock);
   1.174 +}
   1.175 +
   1.176 +
   1.177 +static void 
   1.178 +RunTest(PRInt32 acceptType, PRInt32 clientAction)
   1.179 +{
   1.180 +int i;
   1.181 +
   1.182 +    /* First bind to the socket */
   1.183 +    listenSock = PR_NewTCPSocket();
   1.184 +    if (!listenSock) {
   1.185 +        failed_already=1;
   1.186 +        if (debug_mode)
   1.187 +            PR_fprintf(output, "unable to create listen socket\n");
   1.188 +        return;
   1.189 +    }
   1.190 +	memset(&listenAddr, 0 , sizeof(listenAddr));
   1.191 +    listenAddr.inet.family = PR_AF_INET;
   1.192 +    listenAddr.inet.port = PR_htons(BASE_PORT);
   1.193 +    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
   1.194 +    /*
   1.195 +     * try a few times to bind server's address, if addresses are in
   1.196 +     * use
   1.197 +     */
   1.198 +    i = 0;
   1.199 +    while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) {
   1.200 +        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
   1.201 +            listenAddr.inet.port += 2;
   1.202 +            if (i++ < SERVER_MAX_BIND_COUNT)
   1.203 +                continue;
   1.204 +        }
   1.205 +        failed_already=1;
   1.206 +        if (debug_mode)
   1.207 +        	PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
   1.208 +		return;
   1.209 +    }
   1.210 +
   1.211 +
   1.212 +    rv = PR_Listen(listenSock, 100);
   1.213 +    if (rv == PR_FAILURE) {
   1.214 +        failed_already=1;
   1.215 +        if (debug_mode)
   1.216 +            PR_fprintf(output, "unable to listen\n");
   1.217 +        return;
   1.218 +    }
   1.219 +
   1.220 +    clientCommand = clientAction;
   1.221 +    clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
   1.222 +        (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
   1.223 +        PR_JOINABLE_THREAD, 0);
   1.224 +    if (!clientThread) {
   1.225 +        failed_already=1;
   1.226 +        if (debug_mode)
   1.227 +            PR_fprintf(output, "error creating client thread\n");
   1.228 +        return;
   1.229 +    }
   1.230 +
   1.231 +    iterations = count;
   1.232 +    for (;iterations--;) {
   1.233 +        switch (acceptType) {
   1.234 +        case ACCEPT_NORMAL:
   1.235 +            clientSock = PR_Accept(listenSock, &clientAddr,
   1.236 +                timeoutTime);
   1.237 +            switch(clientAction) {
   1.238 +            case CLIENT_TIMEOUT_ACCEPT:
   1.239 +                TEST_ASSERT(clientSock == 0);
   1.240 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.241 +                break;
   1.242 +            case CLIENT_NORMAL:
   1.243 +                TEST_ASSERT(clientSock);
   1.244 +                bytesRead = PR_Recv(clientSock,
   1.245 +                    buf,  CLIENT_DATA,  0,  timeoutTime);
   1.246 +                TEST_ASSERT(bytesRead == CLIENT_DATA);
   1.247 +                break;
   1.248 +            case CLIENT_TIMEOUT_SEND:
   1.249 +                TEST_ASSERT(clientSock);
   1.250 +                bytesRead = PR_Recv(clientSock,
   1.251 +                    buf,  CLIENT_DATA,  0,  timeoutTime);
   1.252 +                TEST_ASSERT(bytesRead == -1);
   1.253 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.254 +                break;
   1.255 +            }
   1.256 +            break;
   1.257 +        case ACCEPT_READ:
   1.258 +            status = PR_AcceptRead(listenSock, &clientSock,
   1.259 +                &raddr, buf, CLIENT_DATA, timeoutTime);
   1.260 +            switch(clientAction) {
   1.261 +            case CLIENT_TIMEOUT_ACCEPT:
   1.262 +                /* Invalid test case */
   1.263 +                TEST_ASSERT(0);
   1.264 +                break;
   1.265 +            case CLIENT_NORMAL:
   1.266 +                TEST_ASSERT(clientSock);
   1.267 +                TEST_ASSERT(status == CLIENT_DATA);
   1.268 +                break;
   1.269 +            case CLIENT_TIMEOUT_SEND:
   1.270 +                TEST_ASSERT(status == -1);
   1.271 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.272 +                break;
   1.273 +            }
   1.274 +            break;
   1.275 +#ifdef WINNT
   1.276 +        case ACCEPT_FAST:
   1.277 +            clientSock = PR_NTFast_Accept(listenSock,
   1.278 +                &clientAddr, timeoutTime);
   1.279 +            switch(clientAction) {
   1.280 +            case CLIENT_TIMEOUT_ACCEPT:
   1.281 +                TEST_ASSERT(clientSock == 0);
   1.282 +                if (debug_mode)
   1.283 +                    PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError());
   1.284 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.285 +                break;
   1.286 +            case CLIENT_NORMAL:
   1.287 +                TEST_ASSERT(clientSock);
   1.288 +                bytesRead = PR_Recv(clientSock,
   1.289 +                    buf,  CLIENT_DATA,  0,  timeoutTime);
   1.290 +                TEST_ASSERT(bytesRead == CLIENT_DATA);
   1.291 +                break;
   1.292 +            case CLIENT_TIMEOUT_SEND:
   1.293 +                TEST_ASSERT(clientSock);
   1.294 +                bytesRead = PR_Recv(clientSock,
   1.295 +                    buf,  CLIENT_DATA,  0,  timeoutTime);
   1.296 +                TEST_ASSERT(bytesRead == -1);
   1.297 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.298 +                break;
   1.299 +            }
   1.300 +            break;
   1.301 +            break;
   1.302 +        case ACCEPT_READ_FAST:
   1.303 +            status = PR_NTFast_AcceptRead(listenSock,
   1.304 +                &clientSock, &raddr, buf, 4096, timeoutTime);
   1.305 +            switch(clientAction) {
   1.306 +            case CLIENT_TIMEOUT_ACCEPT:
   1.307 +                /* Invalid test case */
   1.308 +                TEST_ASSERT(0);
   1.309 +                break;
   1.310 +            case CLIENT_NORMAL:
   1.311 +                TEST_ASSERT(clientSock);
   1.312 +                TEST_ASSERT(status == CLIENT_DATA);
   1.313 +                break;
   1.314 +            case CLIENT_TIMEOUT_SEND:
   1.315 +                TEST_ASSERT(clientSock == NULL);
   1.316 +                TEST_ASSERT(status == -1);
   1.317 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.318 +                break;
   1.319 +            }
   1.320 +            break;
   1.321 +        case ACCEPT_READ_FAST_CB:
   1.322 +            status = PR_NTFast_AcceptRead_WithTimeoutCallback(
   1.323 +                listenSock, &clientSock, &raddr, buf, 4096,
   1.324 +                timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
   1.325 +            switch(clientAction) {
   1.326 +            case CLIENT_TIMEOUT_ACCEPT:
   1.327 +                /* Invalid test case */
   1.328 +                TEST_ASSERT(0);
   1.329 +                break;
   1.330 +            case CLIENT_NORMAL:
   1.331 +                TEST_ASSERT(clientSock);
   1.332 +                TEST_ASSERT(status == CLIENT_DATA);
   1.333 +                break;
   1.334 +            case CLIENT_TIMEOUT_SEND:
   1.335 +                if (debug_mode)
   1.336 +                    PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock);
   1.337 +                TEST_ASSERT(clientSock == NULL);
   1.338 +                TEST_ASSERT(status == -1);
   1.339 +                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
   1.340 +                break;
   1.341 +            }
   1.342 +            break;
   1.343 +#endif
   1.344 +        }
   1.345 +        if (clientSock != NULL) {
   1.346 +            PR_Close(clientSock);
   1.347 +            clientSock = NULL;
   1.348 +        }
   1.349 +    }
   1.350 +    PR_Close(listenSock);
   1.351 +
   1.352 +    PR_JoinThread(clientThread);
   1.353 +}
   1.354 +
   1.355 +
   1.356 +void AcceptUpdatedTest(void)
   1.357 +{ 
   1.358 +    RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); 
   1.359 +}
   1.360 +void AcceptNotUpdatedTest(void)
   1.361 +{ 
   1.362 +    RunTest(ACCEPT_FAST, CLIENT_NORMAL); 
   1.363 +}
   1.364 +void AcceptReadTest(void)
   1.365 +{ 
   1.366 +    RunTest(ACCEPT_READ, CLIENT_NORMAL); 
   1.367 +}
   1.368 +void AcceptReadNotUpdatedTest(void)
   1.369 +{ 
   1.370 +    RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); 
   1.371 +}
   1.372 +void AcceptReadCallbackTest(void)
   1.373 +{ 
   1.374 +    RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); 
   1.375 +}
   1.376 +
   1.377 +void TimeoutAcceptUpdatedTest(void)
   1.378 +{ 
   1.379 +    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); 
   1.380 +}
   1.381 +void TimeoutAcceptNotUpdatedTest(void)
   1.382 +{ 
   1.383 +    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); 
   1.384 +}
   1.385 +void TimeoutAcceptReadCallbackTest(void)
   1.386 +{ 
   1.387 +    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); 
   1.388 +}
   1.389 +
   1.390 +void TimeoutReadUpdatedTest(void)
   1.391 +{ 
   1.392 +    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); 
   1.393 +}
   1.394 +void TimeoutReadNotUpdatedTest(void)
   1.395 +{ 
   1.396 +    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); 
   1.397 +}
   1.398 +void TimeoutReadReadTest(void)
   1.399 +{ 
   1.400 +    RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); 
   1.401 +}
   1.402 +void TimeoutReadReadNotUpdatedTest(void)
   1.403 +{ 
   1.404 +    RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); 
   1.405 +}
   1.406 +void TimeoutReadReadCallbackTest(void)
   1.407 +{ 
   1.408 +    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); 
   1.409 +}
   1.410 +
   1.411 +/************************************************************************/
   1.412 +
   1.413 +static void Measure(void (*func)(void), const char *msg)
   1.414 +{
   1.415 +    PRIntervalTime start, stop;
   1.416 +    double d;
   1.417 +
   1.418 +    start = PR_IntervalNow();
   1.419 +    (*func)();
   1.420 +    stop = PR_IntervalNow();
   1.421 +
   1.422 +    d = (double)PR_IntervalToMicroseconds(stop - start);
   1.423 +    if (debug_mode)
   1.424 +        PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count);
   1.425 +
   1.426 +}
   1.427 +
   1.428 +int main(int argc, char **argv)
   1.429 +{
   1.430 +
   1.431 +    /* The command line argument: -d is used to determine if the test is being run
   1.432 +    in debug mode. The regress tool requires only one line output:PASS or FAIL.
   1.433 +    All of the printfs associated with this test has been handled with a if (debug_mode)
   1.434 +    test.
   1.435 +    Usage: test_name [-d] [-c n]
   1.436 +    */
   1.437 +    PLOptStatus os;
   1.438 +    PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:");
   1.439 +    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   1.440 +    {
   1.441 +        if (PL_OPT_BAD == os) continue;
   1.442 +        switch (opt->option)
   1.443 +        {
   1.444 +        case 'G':  /* global threads */
   1.445 +            thread_scope = PR_GLOBAL_THREAD;
   1.446 +            break;
   1.447 +        case 'd':  /* debug mode */
   1.448 +            debug_mode = 1;
   1.449 +            break;
   1.450 +        case 'c':  /* loop counter */
   1.451 +            count = atoi(opt->value);
   1.452 +            break;
   1.453 +        default:
   1.454 +            break;
   1.455 +        }
   1.456 +    }
   1.457 +    PL_DestroyOptState(opt);
   1.458 +
   1.459 +    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
   1.460 +    output = PR_STDERR;
   1.461 +    PR_STDIO_INIT();
   1.462 +
   1.463 +    timeoutTime = PR_SecondsToInterval(TIMEOUTSECS);
   1.464 +    if (debug_mode)
   1.465 +        PR_fprintf(output, "\nRun accept() sucessful connection tests\n");
   1.466 +
   1.467 +    Measure(AcceptUpdatedTest, "PR_Accept()");
   1.468 +    Measure(AcceptReadTest, "PR_AcceptRead()");
   1.469 +#ifdef WINNT
   1.470 +    Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()");
   1.471 +    Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
   1.472 +    Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
   1.473 +#endif
   1.474 +    if (debug_mode)
   1.475 +        PR_fprintf(output, "\nRun accept() timeout in the accept tests\n");
   1.476 +#ifdef WINNT
   1.477 +    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
   1.478 +#endif
   1.479 +    Measure(TimeoutReadUpdatedTest, "PR_Accept()");
   1.480 +    if (debug_mode)
   1.481 +        PR_fprintf(output, "\nRun accept() timeout in the read tests\n");
   1.482 +    Measure(TimeoutReadReadTest, "PR_AcceptRead()");
   1.483 +#ifdef WINNT
   1.484 +    Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
   1.485 +    Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
   1.486 +    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
   1.487 +#endif
   1.488 +    PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS");
   1.489 +    return failed_already;
   1.490 +}

mercurial