home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / accept.c next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  15.5 KB  |  519 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /***********************************************************************
  20. **  1996 - Netscape Communications Corporation
  21. **
  22. ** Name: accept.c
  23. **
  24. ** Description: Run accept() sucessful connection tests.
  25. **
  26. ** Modification History:
  27. ** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL
  28. ** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode 
  29. **             The debug mode will print all of the printfs associated with this test.
  30. **             The regress mode will be the default mode. Since the regress tool limits
  31. **           the output to a one line status:PASS or FAIL,all of the printf statements
  32. **             have been handled with an if (debug_mode) statement.
  33. ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
  34. **            recognize the return code from tha main program.
  35. ** 12-June-97 Revert to return code 0 and 1.
  36. ***********************************************************************/
  37.  
  38. /***********************************************************************
  39. ** Includes
  40. ***********************************************************************/
  41.  
  42. #include "nspr.h"
  43. #include "prpriv.h"
  44.  
  45. #include <stdlib.h>
  46. #include <string.h>
  47.  
  48. #include "plgetopt.h"
  49. #include "plerror.h"
  50.  
  51. #ifdef XP_MAC
  52. #include "prlog.h"
  53. #define printf PR_LogPrint
  54. extern void SetupMacPrintfLog(char *logFile);
  55. #endif
  56.  
  57. #define BASE_PORT 8001
  58.  
  59. #define CLIENT_DATA        128
  60.  
  61. #define ACCEPT_NORMAL        0x1
  62. #define ACCEPT_FAST        0x2
  63. #define ACCEPT_READ        0x3
  64. #define ACCEPT_READ_FAST    0x4
  65. #define ACCEPT_READ_FAST_CB    0x5
  66.  
  67. #define CLIENT_NORMAL        0x1
  68. #define CLIENT_TIMEOUT_ACCEPT    0x2
  69. #define CLIENT_TIMEOUT_SEND    0x3
  70.  
  71. #if defined(XP_MAC) || defined(XP_OS2)
  72. #define TIMEOUTSECS 10
  73. #else
  74. #define TIMEOUTSECS 2
  75. #endif
  76. PRIntervalTime timeoutTime;
  77.  
  78. static PRInt32 count = 10;
  79. static PRNetAddr serverAddr;
  80. static PRThreadScope thread_scope = PR_LOCAL_THREAD;
  81.  
  82. PRIntn failed_already=0;
  83. PRIntn debug_mode;
  84.  
  85. void Test_Assert(const char *msg, const char *file, PRIntn line)
  86. {
  87.     failed_already=1;
  88.     if (debug_mode) {
  89. #if defined(WIN16)
  90.         printf( "@%s:%d ", file, line);
  91.         printf(msg);
  92. #else
  93.         PR_fprintf(PR_STDERR, "@%s:%d ", file, line);
  94.         PL_FPrintError(PR_STDERR, msg);
  95. #endif
  96.     }
  97. }  /* Test_Assert */
  98.  
  99. #define TEST_ASSERT(expr) \
  100.     if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__)
  101.  
  102. #ifdef WINNT
  103. #define CALLBACK_MAGIC 0x12345678
  104.  
  105. void timeout_callback(void *magic)
  106. {
  107.     TEST_ASSERT(magic == (void *)CALLBACK_MAGIC);
  108.     if (debug_mode)
  109.         printf("timeout callback called okay\n");
  110. }
  111. #endif
  112.  
  113.  
  114. static void PR_CALLBACK
  115. ClientThread(void *_action)
  116. {
  117.     PRInt32 action = * (PRInt32 *) _action;
  118.     PRInt32 iterations = count;
  119.     PRFileDesc *sock = NULL;
  120.  
  121.     serverAddr.inet.family = AF_INET;
  122.     serverAddr.inet.port = PR_htons(BASE_PORT);
  123.     serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK);
  124.  
  125.     for (; iterations--;) {
  126.         PRInt32 rv;
  127.         char buf[CLIENT_DATA];
  128.  
  129.         sock = PR_NewTCPSocket();
  130.         if (!sock) {
  131.             if (!debug_mode)
  132.                 failed_already=1;
  133.             else    
  134.                 printf("client: unable to create socket\n");
  135.             return;
  136.         }
  137.  
  138.         if (action != CLIENT_TIMEOUT_ACCEPT) {
  139.  
  140.             if ((rv = PR_Connect(sock, &serverAddr,
  141.                 timeoutTime)) < 0) {
  142.                 if (!debug_mode)
  143.                     failed_already=1;
  144.                 else    
  145.                     printf(
  146.                         "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
  147.                         iterations, rv, PR_GetError(),
  148.                         PR_GetOSError());
  149.                 goto ErrorExit;
  150.             }
  151.  
  152.             if (action != CLIENT_TIMEOUT_SEND) {
  153.                 if ((rv = PR_Send(sock, buf, CLIENT_DATA,
  154.                     0, timeoutTime))< 0) {
  155.                     if (!debug_mode)
  156.                         failed_already=1;
  157.                     else    
  158.                         printf("client: unable to send to server (%d, %ld, %ld)\n",
  159.                             CLIENT_DATA, rv,
  160.                             PR_GetError());
  161.                     goto ErrorExit;
  162.                 }
  163.             } else {
  164.                 PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+
  165.                     1));
  166.             }
  167.         } else {
  168.             PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+
  169.                 1));
  170.         }
  171.         if (debug_mode)
  172.             printf(".");
  173.         PR_Close(sock);
  174.     }
  175.     if (debug_mode)
  176.         printf("\n");
  177.  
  178. ErrorExit:
  179.     if (sock != NULL)
  180.         PR_Close(sock);
  181. }
  182.  
  183.  
  184. static  PRInt32 clientCommand;
  185. static  PRInt32 iterations;
  186. static  PRStatus rv;
  187. static     PRFileDesc *listenSock;
  188. static  PRFileDesc *clientSock = NULL;
  189. static  PRNetAddr listenAddr;
  190. static  PRNetAddr clientAddr;
  191. static  PRThread *clientThread;
  192. static  PRNetAddr *raddr;
  193. static  char buf[4096 + 64];
  194. static  PRInt32 status;
  195. static  PRInt32 bytesRead;
  196.  
  197. static void 
  198. RunTest(PRInt32 acceptType, PRInt32 clientAction)
  199. {
  200.  
  201.     /* First bind to the socket */
  202.     listenSock = PR_NewTCPSocket();
  203.     if (!listenSock) {
  204.         if (!debug_mode)
  205.             failed_already=1;
  206.         else    
  207.             printf("unable to create listen socket\n");
  208.         return;
  209.     }
  210.     listenAddr.inet.family = AF_INET;
  211.     listenAddr.inet.port = PR_htons(BASE_PORT);
  212.     listenAddr.inet.ip = PR_htonl(INADDR_ANY);
  213.     rv = PR_Bind(listenSock, &listenAddr);
  214.     if (rv == PR_FAILURE) {
  215.         if (!debug_mode)
  216.             failed_already=1;
  217.         else    
  218.             printf("unable to bind\n");
  219.         return;
  220.     }
  221.  
  222.     rv = PR_Listen(listenSock, 100);
  223.     if (rv == PR_FAILURE) {
  224.         if (!debug_mode)
  225.             failed_already=1;
  226.         else    
  227.             printf("unable to listen\n");
  228.         return;
  229.     }
  230.  
  231.     clientCommand = clientAction;
  232.     clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
  233.         (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
  234.         PR_JOINABLE_THREAD, 0);
  235.     if (!clientThread) {
  236.         if (!debug_mode)
  237.             failed_already=1;
  238.         else    
  239.             printf("error creating client thread\n");
  240.         return;
  241.     }
  242.  
  243.     iterations = count;
  244.     for (;iterations--;) {
  245.         switch (acceptType) {
  246.         case ACCEPT_NORMAL:
  247.             clientSock = PR_Accept(listenSock, &clientAddr,
  248.                 timeoutTime);
  249.             switch(clientAction) {
  250.             case CLIENT_TIMEOUT_ACCEPT:
  251.                 TEST_ASSERT(clientSock == 0);
  252.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  253.                 break;
  254.             case CLIENT_NORMAL:
  255.                 TEST_ASSERT(clientSock);
  256.                 bytesRead = PR_Recv(clientSock,
  257.                     buf,  CLIENT_DATA,  0,  timeoutTime);
  258.                 TEST_ASSERT(bytesRead == CLIENT_DATA);
  259.                 break;
  260.             case CLIENT_TIMEOUT_SEND:
  261.                 TEST_ASSERT(clientSock);
  262.                 bytesRead = PR_Recv(clientSock,
  263.                     buf,  CLIENT_DATA,  0,  timeoutTime);
  264.                 TEST_ASSERT(bytesRead == -1);
  265.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  266.                 break;
  267.             }
  268.             break;
  269.         case ACCEPT_READ:
  270.             status = PR_AcceptRead(listenSock, &clientSock,
  271.                 &raddr, buf, CLIENT_DATA, timeoutTime);
  272.             switch(clientAction) {
  273.             case CLIENT_TIMEOUT_ACCEPT:
  274.                 /* Invalid test case */
  275.                 TEST_ASSERT(0);
  276.                 break;
  277.             case CLIENT_NORMAL:
  278.                 TEST_ASSERT(clientSock);
  279.                 TEST_ASSERT(status == CLIENT_DATA);
  280.                 break;
  281.             case CLIENT_TIMEOUT_SEND:
  282.                 TEST_ASSERT(status == -1);
  283.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  284.                 break;
  285.             }
  286.             break;
  287. #ifdef WINNT
  288.         case ACCEPT_FAST:
  289.             clientSock = PR_NTFast_Accept(listenSock,
  290.                 &clientAddr, timeoutTime);
  291.             switch(clientAction) {
  292.             case CLIENT_TIMEOUT_ACCEPT:
  293.                 TEST_ASSERT(clientSock == 0);
  294.                 if (debug_mode)
  295.                     printf("PR_GetError is %ld\n",
  296.                         PR_GetError());
  297.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  298.                 break;
  299.             case CLIENT_NORMAL:
  300.                 TEST_ASSERT(clientSock);
  301.                 bytesRead = PR_Recv(clientSock,
  302.                     buf,  CLIENT_DATA,  0,  timeoutTime);
  303.                 TEST_ASSERT(bytesRead == CLIENT_DATA);
  304.                 break;
  305.             case CLIENT_TIMEOUT_SEND:
  306.                 TEST_ASSERT(clientSock);
  307.                 bytesRead = PR_Recv(clientSock,
  308.                     buf,  CLIENT_DATA,  0,  timeoutTime);
  309.                 TEST_ASSERT(bytesRead == -1);
  310.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  311.                 break;
  312.             }
  313.             break;
  314.             break;
  315.         case ACCEPT_READ_FAST:
  316.             status = PR_NTFast_AcceptRead(listenSock,
  317.                 &clientSock, &raddr, buf, 4096, timeoutTime);
  318.             switch(clientAction) {
  319.             case CLIENT_TIMEOUT_ACCEPT:
  320.                 /* Invalid test case */
  321.                 TEST_ASSERT(0);
  322.                 break;
  323.             case CLIENT_NORMAL:
  324.                 TEST_ASSERT(clientSock);
  325.                 TEST_ASSERT(status == CLIENT_DATA);
  326.                 break;
  327.             case CLIENT_TIMEOUT_SEND:
  328.                 TEST_ASSERT(clientSock);
  329.                 TEST_ASSERT(status == -1);
  330.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  331.                 break;
  332.             }
  333.             break;
  334.         case ACCEPT_READ_FAST_CB:
  335.             status = PR_NTFast_AcceptRead_WithTimeoutCallback(
  336.                 listenSock, &clientSock, &raddr, buf, 4096,
  337.                 timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
  338.             switch(clientAction) {
  339.             case CLIENT_TIMEOUT_ACCEPT:
  340.                 /* Invalid test case */
  341.                 TEST_ASSERT(0);
  342.                 break;
  343.             case CLIENT_NORMAL:
  344.                 TEST_ASSERT(clientSock);
  345.                 TEST_ASSERT(status == CLIENT_DATA);
  346.                 break;
  347.             case CLIENT_TIMEOUT_SEND:
  348.                 if (debug_mode)
  349.                     printf("clientSock = 0x%8.8lx\n",
  350.                         clientSock);
  351.                 TEST_ASSERT(clientSock);
  352.                 TEST_ASSERT(status == -1);
  353.                 TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
  354.                 break;
  355.             }
  356.             break;
  357. #endif
  358.         }
  359.         if (clientSock != NULL) {
  360.             PR_Close(clientSock);
  361.             clientSock = NULL;
  362.         }
  363.     }
  364.     PR_Close(listenSock);
  365.  
  366.     PR_JoinThread(clientThread);
  367. }
  368.  
  369.  
  370. void AcceptUpdatedTest(void)
  371.     RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); 
  372. }
  373. void AcceptNotUpdatedTest(void)
  374.     RunTest(ACCEPT_FAST, CLIENT_NORMAL); 
  375. }
  376. void AcceptReadTest(void)
  377.     RunTest(ACCEPT_READ, CLIENT_NORMAL); 
  378. }
  379. void AcceptReadNotUpdatedTest(void)
  380.     RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); 
  381. }
  382. void AcceptReadCallbackTest(void)
  383.     RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); 
  384. }
  385.  
  386. void TimeoutAcceptUpdatedTest(void)
  387.     RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); 
  388. }
  389. void TimeoutAcceptNotUpdatedTest(void)
  390.     RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); 
  391. }
  392. void TimeoutAcceptReadCallbackTest(void)
  393.     RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); 
  394. }
  395.  
  396. void TimeoutReadUpdatedTest(void)
  397.     RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); 
  398. }
  399. void TimeoutReadNotUpdatedTest(void)
  400.     RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); 
  401. }
  402. void TimeoutReadReadTest(void)
  403.     RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); 
  404. }
  405. void TimeoutReadReadNotUpdatedTest(void)
  406.     RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); 
  407. }
  408. void TimeoutReadReadCallbackTest(void)
  409.     RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); 
  410. }
  411.  
  412. /************************************************************************/
  413.  
  414. static void Measure(void (*func)(void), const char *msg)
  415. {
  416.     PRIntervalTime start, stop;
  417.     double d;
  418.  
  419.     start = PR_IntervalNow();
  420.     (*func)();
  421.     stop = PR_IntervalNow();
  422.  
  423.     d = (double)PR_IntervalToMicroseconds(stop - start);
  424.     if (debug_mode)
  425.         printf("%40s: %6.2f usec\n", msg, d / count);
  426.  
  427. }
  428.  
  429. int main(int argc, char **argv)
  430. {
  431.  
  432.     /* The command line argument: -d is used to determine if the test is being run
  433.     in debug mode. The regress tool requires only one line output:PASS or FAIL.
  434.     All of the printfs associated with this test has been handled with a if (debug_mode)
  435.     test.
  436.     Usage: test_name [-d] [-c n]
  437.     */
  438.     PLOptStatus os;
  439.     PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:");
  440.     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  441.     {
  442.         if (PL_OPT_BAD == os) continue;
  443.         switch (opt->option)
  444.         {
  445.         case 'G':  /* global threads */
  446.             thread_scope = PR_GLOBAL_THREAD;
  447.             break;
  448.         case 'd':  /* debug mode */
  449.             debug_mode = 1;
  450.             break;
  451.         case 'c':  /* loop counter */
  452.             count = atoi(opt->value);
  453.             break;
  454.         default:
  455.             break;
  456.         }
  457.     }
  458.     PL_DestroyOptState(opt);
  459.  
  460.  
  461.     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  462.     PR_STDIO_INIT();
  463.  
  464. #ifdef XP_MAC
  465.     SetupMacPrintfLog("accept.log");
  466.     debug_mode = 1;
  467. #endif
  468.  
  469.     timeoutTime = PR_SecondsToInterval(TIMEOUTSECS);
  470.     if (debug_mode)
  471.         printf("\nRun accept() sucessful connection tests\n");
  472.  
  473.     Measure(AcceptUpdatedTest, "PR_Accept()");
  474.     Measure(AcceptReadTest, "PR_AcceptRead()");
  475. #ifdef WINNT
  476.     Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()");
  477.     Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
  478.     Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
  479. #endif
  480.     if (debug_mode)
  481.         printf("\nRun accept() timeout in the accept tests\n");
  482. #ifdef WINNT
  483.     Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
  484. #endif
  485.     if (debug_mode)
  486.         printf("\nRun accept() timeout in the read tests\n");
  487.     Measure(TimeoutReadUpdatedTest, "PR_Accept()");
  488.     Measure(TimeoutReadReadTest, "PR_AcceptRead()");
  489. #ifdef WINNT
  490.     Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
  491.     Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
  492.     Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
  493. #endif
  494.     if(failed_already)
  495.     {
  496.         printf("FAIL\n");
  497.         return 1;
  498.     }
  499.     else
  500.     {
  501.         printf("PASS\n");
  502.         return 0;
  503.  
  504.     }
  505. }
  506.