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 +}