ncbi_conntest.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbi_conntest.c,v $
  4.  * PRODUCTION Revision 1000.1  2004/02/24 19:22:39  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [CORE_001] Dev-tree R6.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: ncbi_conntest.c,v 1000.1 2004/02/24 19:22:39 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Author:  Denis Vakatov
  35.  *
  36.  * File Description:
  37.  *   Test suite for NCBI connector (CONNECTOR)
  38.  *   (see also "ncbi_connection.[ch]", "ncbi_connector.h")
  39.  *
  40.  */
  41. #include "ncbi_conntest.h"
  42. #include "../ncbi_priv.h"
  43. #include <connect/ncbi_connection.h>
  44. #include <string.h>
  45. /* This header must go last */
  46. #include "test_assert.h"
  47. /***********************************************************************
  48.  *  INTERNAL
  49.  */
  50. /* Standard error report
  51.  */
  52. #define TEST_LOG(status, descr) 
  53.   CORE_LOGF(status == eIO_Success ? eLOG_Note : 
  54.             status == eIO_Closed  ? eLOG_Warning : 
  55.                                     eLOG_Error, 
  56.             ("%s (status: "%s")", descr, IO_StatusStr(status)))
  57. /* TESTs
  58.  */
  59. static void s_SingleBouncePrint
  60. (CONN  conn,
  61.  FILE* data_file)
  62. {
  63.     static const char write_str[] = "This is a s_*BouncePrint test string.n";
  64.     EIO_Status status;
  65.     size_t     n_written, n_read;
  66.     char       buf[8192];
  67.     TEST_LOG(eIO_Success, "[s_SingleBouncePrint]  Starting...");
  68.     /* WRITE */
  69.     status = CONN_Write(conn, write_str, strlen(write_str),
  70.                         &n_written, eIO_WritePersist);
  71.     if (status != eIO_Success  ||  n_written != strlen(write_str)) {
  72.         TEST_LOG(status, "[s_SingleBouncePrint] Write failed!");
  73.     }
  74.     assert(n_written == strlen(write_str));
  75.     assert(status == eIO_Success);
  76.     /* READ the "bounced" data from the connection */
  77.     status = CONN_Read(conn, buf, sizeof(buf) - 1, &n_read, eIO_ReadPersist);
  78.     TEST_LOG(status, "[s_SingleBouncePrint] after READ");
  79.     /* Printout to LOG file, if any */
  80.     if (data_file  &&  n_read) {
  81.         fprintf(data_file, "ns_SingleBouncePrint(BEGIN PRINT)n");
  82.         assert(fwrite(buf, n_read, 1, data_file) == 1);
  83.         fprintf(data_file, "ns_SingleBouncePrint(END PRINT)n");
  84.     }
  85.     /* Check-up */
  86.     assert(n_read >= n_written);
  87.     buf[n_read] = '';
  88.     assert(strstr(buf, write_str));
  89. }
  90. static void s_MultiBouncePrint
  91. (CONN  conn,
  92.  FILE* data_file)
  93. {
  94.     int i;
  95.     TEST_LOG(eIO_Success, "[s_MultiBouncePrint]  Starting...");
  96.     if ( data_file )
  97.         fprintf(data_file, "ns_MultiBouncePrint(BEGIN)n");
  98.     for (i = 0;  i < 5;  i++) {
  99.         s_SingleBouncePrint(conn, data_file);
  100.     }
  101.     TEST_LOG(eIO_Success, "[s_MultiBouncePrint]  ...finished");
  102.     if ( data_file )
  103.         fprintf(data_file, "ns_MultiBouncePrint(END)n");
  104. }
  105. static void s_SingleBounceCheck
  106. (CONN            conn,
  107.  const STimeout* timeout,
  108.  FILE*           data_file)
  109. {
  110.     EIO_Status status;
  111.     static const char sym[] = {
  112.         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
  113.     };
  114. #define TEST_N_LINES 200
  115. #define TEST_BUF_SIZE (TEST_N_LINES * (TEST_N_LINES + 3) / 2)
  116.     char  buf[TEST_BUF_SIZE];
  117.     TEST_LOG(eIO_Success, "[s_SingleBounceCheck]  Starting...");
  118.     /* WRITE to the connection:  "0n12n345n6789n01234n........"
  119.      */
  120.     {{
  121.         size_t k = 0;
  122.         size_t i, j=0;
  123.         for (i = 0;  k != sizeof(buf);  i++) {
  124.             /* prepare output data */
  125.             size_t n_write, n_written;
  126.             for (n_write = 0;  n_write < i;  n_write++, k++) {
  127.                 assert(k != sizeof(buf));
  128.                 buf[n_write] = sym[j++ % sizeof(sym)];
  129.             }
  130.             assert(k != sizeof(buf));
  131.             if ( n_write ) {
  132.                 buf[n_write++] = 'n';  k++;
  133.             }
  134.             buf[n_write] = '';
  135.             do { /* persistently */
  136.                 /* WAIT... sometimes */
  137.                 if (n_write % 5 == 3) {
  138.                     status = CONN_Wait(conn, eIO_Write, timeout);
  139.                     if (status != eIO_Success) {
  140.                         TEST_LOG(status, "The pre-WRITE CONN_Wait failed");
  141.                         assert(status == eIO_Timeout);
  142.                     }
  143.                 }
  144.                 /* WRITE */
  145.                 status = CONN_Write(conn, buf, n_write,
  146.                                     &n_written, eIO_WritePersist);
  147.                 if (status != eIO_Success) {
  148.                     TEST_LOG(status, "Write failed. Retrying...");
  149.                     assert(n_written < n_write);
  150.                     assert(status == eIO_Timeout);
  151.                 }
  152.                 else {
  153.                     assert(n_written == n_write);
  154.                 }
  155.             } while (status != eIO_Success);
  156.         }
  157.     }}
  158.     /* READ the "bounced" data from the connection, the first TEST_BUF_SIZE
  159.      * bytes must be:  "0n12n345n6789n01234n........"
  160.      */
  161.     {{
  162.         char* x_buf;
  163.         size_t n_read, n_to_read;
  164.         memset(buf, '', TEST_BUF_SIZE);
  165.         /* PEEK until the 1st 1/3 of the "bounced" data is available */
  166.         x_buf = buf;
  167.         n_to_read = TEST_BUF_SIZE/3;
  168.         do {
  169.             status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPeek);
  170.             if (status != eIO_Success) {
  171.                 TEST_LOG(status, "The 1/3 PEEK failed. Retrying...");
  172.                 assert(n_read < n_to_read);
  173.                 assert(status == eIO_Timeout);
  174.             }
  175.             if (n_read < n_to_read) {
  176.                 TEST_LOG(status, "Not all of the expected data is peeked yet."
  177.                          " Continue...");
  178.             }
  179.         } while (n_read != n_to_read);
  180.         /* READ 1st 1/3 of "bounced" data, compare it with the PEEKed data */
  181.         status = CONN_Read(conn, x_buf + n_to_read, n_to_read, &n_read,
  182.                            eIO_ReadPlain);
  183.         assert(status == eIO_Success);
  184.         assert(n_read == n_to_read);
  185.         assert(memcmp(x_buf, x_buf + n_to_read, n_to_read) == 0);
  186.         memset(x_buf + n_to_read, '', n_to_read);
  187.         /* WAIT on read */
  188.         status = CONN_Wait(conn, eIO_Read, timeout);
  189.         if (status != eIO_Success) {
  190.             TEST_LOG(status, "The 2/3 pre-READ CONN_Wait failed");
  191.             assert(status == eIO_Timeout);
  192.         }
  193.         /* READ the 2nd 1/3 of "bounced" data */
  194.         x_buf = buf + TEST_BUF_SIZE/3;
  195.         n_to_read = TEST_BUF_SIZE/3;
  196.         while ( n_to_read ) {
  197.             TEST_LOG(status, "2/3 READ...");
  198.             status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPlain);
  199.             if (status != eIO_Success) {
  200.                 TEST_LOG(status, "The 2/3 READ failed. Retrying...");
  201.                 assert(n_read < n_to_read);
  202.                 assert(status == eIO_Timeout);
  203.             } else {
  204.                 assert(n_read <= n_to_read);
  205.             }
  206.             n_to_read -= n_read;
  207.             x_buf     += n_read;
  208.         }
  209.         assert(status == eIO_Success);
  210.         /* Persistently READ the 3rd 1/3 of "bounced" data */
  211.         n_to_read = TEST_BUF_SIZE - (x_buf - buf);
  212.         status = CONN_Read(conn, x_buf, n_to_read, &n_read, eIO_ReadPersist);
  213.         if (status != eIO_Success) {
  214.             TEST_LOG(status, "The 3/3 (persistent) READ failed!");
  215.             assert(n_read < n_to_read);
  216.             assert(0);
  217.         } else {
  218.             assert(n_read == n_to_read);
  219.         }
  220.     }}
  221.     /* Check for the received "bounced" data is identical to the sent data
  222.      */
  223.     {{
  224.         const char* x_buf = buf;
  225.         size_t i;
  226.         size_t k=0, j=0;
  227.         for (i = 1;  k != sizeof(buf);  i++) {
  228.             size_t n;
  229.             for (n = 0;  n < i;  n++, k++) {
  230.                 if (k == sizeof(buf))
  231.                     break;
  232.                 assert(*x_buf++ == sym[j++ % sizeof(sym)]);
  233.             }
  234.             assert(*x_buf++ == 'n');  k++;
  235.         }
  236.     }}
  237.     /* Now when the "bounced" data is read and tested, READ an arbitrary extra
  238.      * data sent in by the peer and print it out to LOG file
  239.      */
  240.     if ( !data_file )
  241.         return;
  242.     fprintf(data_file, "ns_SingleBounceCheck(BEGIN EXTRA DATA)n");
  243.     for (;;) {
  244.         size_t n_read;
  245.         status = CONN_Read(conn, buf, sizeof(buf), &n_read, eIO_ReadPersist);
  246.         TEST_LOG(status, "s_SingleBounceCheck(The extra data READ...)");
  247.         if ( n_read )
  248.             assert(fwrite(buf, n_read, 1, data_file) == 1);
  249.         if (status == eIO_Closed  ||  status == eIO_Timeout)
  250.             break; /* okay */
  251.         assert(status == eIO_Success  ||  status == eIO_Timeout);
  252.     }
  253.     fprintf(data_file, "ns_SingleBounceCheck(END EXTRA DATA)nn");
  254. }
  255. /***********************************************************************
  256.  *  EXTERNAL
  257.  */
  258. extern void CONN_TestConnector
  259. (CONNECTOR       connector,
  260.  const STimeout* timeout,
  261.  FILE*           data_file,
  262.  TTestConnFlags  flags)
  263. {
  264.     EIO_Status status;
  265.     CONN       conn;
  266.     TEST_LOG(eIO_Success, "[CONN_TestConnector]  Starting...");
  267.     /* CREATE new connection on the base of the connector, set
  268.      * TIMEOUTs, try to RECONNECT, WAIT for the connection is writable
  269.      */
  270.     assert(CONN_Create(connector, &conn) == eIO_Success);
  271.     CONN_SetTimeout(conn, eIO_Open,      timeout);
  272.     CONN_SetTimeout(conn, eIO_Read,      timeout);
  273.     CONN_SetTimeout(conn, eIO_ReadWrite, timeout);
  274.     CONN_SetTimeout(conn, eIO_Close,     timeout);
  275.     assert(CONN_ReInit(conn, connector) == eIO_Success);
  276.     CONN_SetTimeout(conn, eIO_Write, timeout);
  277.     status = CONN_Wait(conn, eIO_Write, timeout);
  278.     if (status != eIO_Success) {
  279.         TEST_LOG(status, "First CONN_Wait failed");
  280.         assert(status == eIO_Timeout);
  281.     }
  282.     /* Run the specified TESTs
  283.      */
  284.     if ( !flags )
  285.         flags = fTC_Everything;
  286.     if (flags & fTC_SingleBouncePrint) {
  287.         s_SingleBouncePrint(conn, data_file);
  288.     }
  289.     if (flags & fTC_MultiBouncePrint) {
  290.         s_MultiBouncePrint(conn, data_file);
  291.     }
  292.     if (flags & fTC_SingleBounceCheck) {
  293.         s_SingleBounceCheck(conn, timeout, data_file);
  294.     }
  295.     /* And CLOSE the connection...
  296.      */
  297.     assert(CONN_Close(conn) == eIO_Success);
  298.     TEST_LOG(status, "Test completed successfully");
  299. }
  300. /*
  301.  * --------------------------------------------------------------------------
  302.  * $Log: ncbi_conntest.c,v $
  303.  * Revision 1000.1  2004/02/24 19:22:39  gouriano
  304.  * PRODUCTION: UPGRADED [CORE_001] Dev-tree R6.9
  305.  *
  306.  * Revision 6.9  2004/02/23 15:23:42  lavr
  307.  * New (last) parameter "how" added in CONN_Write() API call
  308.  *
  309.  * Revision 6.8  2003/02/10 15:57:35  lavr
  310.  * Announce successful test completion
  311.  *
  312.  * Revision 6.7  2002/08/07 16:38:08  lavr
  313.  * EIO_ReadMethod enums changed accordingly; log moved to end
  314.  *
  315.  * Revision 6.6  2002/03/22 19:46:02  lavr
  316.  * Test_assert.h made last among the include files
  317.  *
  318.  * Revision 6.5  2002/01/16 21:23:14  vakatov
  319.  * Utilize header "test_assert.h" to switch on ASSERTs in the Release mode too
  320.  *
  321.  * Revision 6.4  2001/03/02 20:03:34  lavr
  322.  * Typos fixed
  323.  *
  324.  * Revision 6.3  2000/12/29 18:25:06  lavr
  325.  * CONN Reconnect replaced with ReInit.
  326.  *
  327.  * Revision 6.2  2000/04/21 19:53:11  vakatov
  328.  * Minor cosmetic changes
  329.  *
  330.  * Revision 6.1  2000/04/07 20:03:01  vakatov
  331.  * Initial revision
  332.  *
  333.  * ==========================================================================
  334.  */