1 /* $Id: test_ncbi_socket_connector.c 605943 2020-04-16 20:17:24Z lavr $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author:  Denis Vakatov
27  *
28  * File Description:
29  *   Standard test for the the SOCK-based CONNECTOR
30  *
31  */
32 
33 #include <connect/ncbi_socket_connector.h>
34 #include <connect/ncbi_connutil.h>
35 #include "../ncbi_ansi_ext.h"
36 #include "../ncbi_priv.h"               /* CORE logging facilities */
37 #include "ncbi_conntest.h"
38 #include <errno.h>
39 #include <stdlib.h>
40 
41 #include "test_assert.h"  /* This header must go last */
42 
43 #define TEST_MAX_TRY 2
44 #define TEST_TIMEOUT 5.123456
45 
46 #define _STR(n)     #n
47 #define  STR(n) _STR(n)
48 
49 
50 /* Getter for the pseudo-registry
51  */
52 #if defined(__cplusplus)
53 extern "C" {
54     static int s_REG_Get(void* user_data, const char* section,
55                          const char* name, char* value, size_t value_size);
56 }
57 #endif /* __cplusplus */
58 
59 /*ARGSUSED*/
s_REG_Get(void * unused,const char * section,const char * name,char * value,size_t value_size)60 static int s_REG_Get(void* unused, const char* section,
61                      const char* name, char* value, size_t value_size)
62 {
63     if (strcasecmp(DEF_CONN_REG_SECTION, section) == 0) {
64         if      (strcasecmp(REG_CONN_HOST,    name) == 0)
65             *value = '\0';
66         if      (strcasecmp(REG_CONN_MAX_TRY, name) == 0)
67             strncpy0(value, STR(TEST_MAX_TRY), value_size);
68         else if (strcasecmp(REG_CONN_TIMEOUT, name) == 0)
69             strncpy0(value, STR(TEST_TIMEOUT), value_size);
70         else
71             return -1;
72         return 1;
73     }
74     return -1;
75 }
76 
77 
main(int argc,const char * argv[])78 int main(int argc, const char* argv[])
79 {
80     SConnNetInfo* net_info;
81     CONNECTOR     connector;
82     FILE*         data_file;
83     char          tmo[32];
84     SOCK          sock;
85 
86     /* log and data log streams */
87     CORE_SetLOGFormatFlags(fLOG_None          | fLOG_Level   |
88                            fLOG_OmitNoteLevel | fLOG_DateTime);
89     CORE_SetLOGFILE(stderr, 0/*false*/);
90 
91     /* registry */
92     CORE_SetREG(REG_Create(0, s_REG_Get, 0, 0, 0));
93 
94     assert((net_info = ConnNetInfo_Create(0)) != 0);
95 
96     /* parse cmd.-line args */
97     switch ( argc ) {
98     case 5: { /* timeout */
99         double v;
100         char*  e = (char*) argv[4];
101         if (!*e  ||  (v = NCBI_simple_atof(e, &e)) < 0.0  ||  errno  ||  *e)
102             break;
103         net_info->tmo.sec  = (unsigned int)  v;
104         net_info->tmo.usec = (unsigned int)((v - net_info->tmo.sec) * 1.0e6);
105         net_info->timeout  = &net_info->tmo;
106     }
107     case 4: { /* max_try  */
108         long l;
109         if (sscanf(argv[3], "%ld", &l) != 1  ||  l <= 0)
110             break;
111         net_info->max_try = (unsigned int) l;
112     }
113     case 3: { /* host, port */
114         int i;
115         if (sscanf(argv[2], "%d", &i) != 1  ||  i < 0  ||  65535 < i)
116             break;
117         net_info->port = (unsigned short) i;
118 
119         if (!*argv[1])
120             break;
121         strncpy0(net_info->host, argv[1], sizeof(net_info->host) - 1);
122     }
123     default:
124         break;
125     }
126 
127     /* bad args? -- Usage */
128     if (!*net_info->host  ||  !net_info->port) {
129         ConnNetInfo_Destroy(net_info);
130         fprintf(stderr,
131                 "Usage: %s <host> <port> [max_try [timeout]]\n\n",
132                 argv[0]);
133         return 1/*error*/;
134     }
135 
136     data_file = fopen("test_ncbi_socket_connector.log", "ab");
137     assert(data_file);
138 
139     if (net_info->debug_printout)
140         SOCK_SetDataLoggingAPI(eOn);
141 
142     if (net_info->timeout) {
143         sprintf(tmo, "%u.%06u",
144                 net_info->timeout->sec, net_info->timeout->usec);
145     } else
146         strcpy(tmo, "infinite");
147 
148     /* Tests for SOCKET CONNECTOR */
149     fprintf(stderr,
150             "Starting the SOCKET CONNECTOR test...\n"
151             "%s:%hu, timeout = %s, max # of retries = %u\n",
152             net_info->host, net_info->port, tmo, net_info->max_try);
153 
154     connector = SOCK_CreateConnector(net_info->host, net_info->port,
155                                      net_info->max_try);
156     CONN_TestConnector(connector, net_info->timeout,
157                        data_file, fTC_SingleBouncePrint);
158 
159     connector = SOCK_CreateConnector(net_info->host, net_info->port,
160                                      net_info->max_try);
161     CONN_TestConnector(connector, net_info->timeout,
162                        data_file, fTC_SingleBounceCheck);
163 
164     connector = SOCK_CreateConnector(net_info->host, net_info->port,
165                                      net_info->max_try);
166     CONN_TestConnector(connector, net_info->timeout,
167                        data_file, fTC_Everything);
168 
169     /* Tests for OnTop SOCKET CONNECTOR connector */
170     fprintf(stderr,
171             "Starting the SOCKET CONNECTOR test for \"OnTop\" connectors...\n"
172             "%s:%hu, timeout = %s, max # of retries = %u\n",
173             net_info->host, net_info->port, tmo, net_info->max_try);
174 
175     if (SOCK_Create(net_info->host, net_info->port,
176                     net_info->timeout, &sock) != eIO_Success) {
177         CORE_LOG(eLOG_Fatal, "Cannot create socket");
178     }
179 
180     connector = SOCK_CreateConnectorOnTop(sock, net_info->max_try);
181     CONN_TestConnector(connector, net_info->timeout,
182                        data_file, fTC_Everything);
183 
184     /* cleanup, exit */
185     ConnNetInfo_Destroy(net_info);
186     fclose(data_file);
187     CORE_SetREG(0);
188 
189     CORE_LOG(eLOG_Note, "TEST completed successfully");
190     CORE_SetLOG(0);
191     return 0/*okay*/;
192 }
193