1 /* $Id: test_ncbi_linkerd_cxx.cpp 578389 2019-01-17 18:08:54Z 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  * Authors:  David McElhany
27  *
28  * File Description:
29  *  Test LINKERD via C++.
30  *  Currently, the only C++ APIs supporting Linkerd are g_HttpGet/Post() and
31  *  CHttpSession::NewRequest().
32  *  Test other service mappers too, and also CHttpStream, to ensure that
33  *  changes made for Linkerd don't break other service mappers or other API
34  *  pathways.
35  *
36  */
37 
38 #include <ncbi_pch.hpp>     // This header must go first
39 
40 #include <connect/ncbi_http_session.hpp>
41 #include <connect/ncbi_socket.h>
42 #include <corelib/ncbi_url.hpp>
43 #include <corelib/ncbiapp.hpp>
44 #include <corelib/ncbidiag.hpp>
45 #include <util/xregexp/regexp.hpp>
46 
47 #include <stdlib.h>
48 
49 #include "test_assert.h"    // This header must go last
50 
51 
52 #ifdef _MSC_VER
53 #define unsetenv(n)     _putenv_s(n,"")
54 #define setenv(n,v,w)   _putenv_s(n,v)
55 #endif
56 
57 
58 USING_NCBI_SCOPE;
59 
60 
61 // Test functions
62 enum { eHttpGet, eHttpPost, eHttpStreamGet, eHttpStreamPost, eNewRequestGet, eNewRequestPost };
63 
64 // Service mappers
65 enum { eDispd, eLbsmd, eLinkerd, eLocal, eNamerd };
66 
67 // POST request data
68 static const string s_kPostData_Def     = "hi there\n";
69 static const string s_kPostData_Fcgi    = "message=hi%20there%0A";
70 
71 // POST expected response data
72 static const string s_kExpData_GetTest      = R"(^.*?<title>NCBI Dispatcher Test Page</title>.*$)";
73 static const string s_kExpData_GetFcgi      = R"(^.*?C\+\+ GIT FastCGI Sample.*?<p>Your previous message: +\n.*$)";
74 static const string s_kExpData_PostBounce   = R"(^hi there\n$)";
75 static const string s_kExpData_PostFcgi     = R"(^.*?C\+\+ GIT FastCGI Sample.*?<p>Your previous message: +'hi there\n'.*$)";
76 
77 // Test data structure
78 struct STest {
STestSTest79     STest(int f, int m, const string& u, const string& e, const string& p = s_kPostData_Def)
80         : func(f), mapper(m), url(u), expected(e), post(p)
81     {
82     }
83     int     func;
84     int     mapper;
85     string  url;
86     string  expected;
87     string  post;
88 };
89 
90 
91 // The URL forms to be tested include:
92 //      Form                                    Example
93 //      -----------------------------------     -----------------------------------
94 //      service-name-only URLs                  foo
95 //      host-based URLs                         https://intrawebdev2.ncbi.nlm.nih.gov/Service/bounce.cgi
96 //      special case (test domain) URLs         https://test.ncbi.nlm.nih.gov/Service/bar.cgi
97 //      full service-based URLs                 ncbilb://foo/Service/bar.cgi
98 //      full service-based URLs with scheme     http+ncbilb://foo/Service/bar.cgi
99 
100 // Simple service name URLs
101 static const string s_UrlServiceGet_test("test");
102 static const string s_UrlServiceGet_fcgi("cxx-fast-cgi-sample");
103 static const string s_UrlServicePost_bounce("bouncehttp");
104 static const string s_UrlServicePost_fcgi("cxx-fast-cgi-sample");
105 
106 // Host-based URLs - i.e. not load-balanced, therefore not using a service mapper,
107 // but they should still be accessible via the service mappers (except Linkerd).
108 static const string s_UrlHostGetHttp("http://intrawebdev2.ncbi.nlm.nih.gov/Service/test.cgi");
109 static const string s_UrlHostGetHttps("https://intrawebdev2.ncbi.nlm.nih.gov/Service/test.cgi");
110 static const string s_UrlHostPostHttp("http://intrawebdev2.ncbi.nlm.nih.gov/Service/bounce.cgi");
111 static const string s_UrlHostPostHttps("https://intrawebdev2.ncbi.nlm.nih.gov/Service/bounce.cgi");
112 
113 // Special case: host-based URL that goes to frontend and gets load-balanced to backend
114 static const string s_UrlFrontendGet("https://test.ncbi.nlm.nih.gov/Service/test.cgi");
115 static const string s_UrlFrontendPost("https://test.ncbi.nlm.nih.gov/Service/bounce.cgi");
116 
117 // Full service-based URLs (as indicated by ncbilb in scheme)
118 static const string s_UrlNcbilbGetTest("ncbilb://test");
119 static const string s_UrlNcbilbGetTestFull("ncbilb://test/Service/test.cgi");
120 static const string s_UrlNcbilbGetFcgi("ncbilb://cxx-fast-cgi-sample");
121 static const string s_UrlNcbilbPostBounce("ncbilb://bouncehttp");
122 static const string s_UrlNcbilbPostBounceFull("ncbilb://bouncehttp/Service/bounce.cgi");
123 static const string s_UrlNcbilbPostFcgi("ncbilb://cxx-fast-cgi-sample");
124 static const string s_UrlNcbilbHttpGetTest("http+ncbilb://test");
125 static const string s_UrlNcbilbHttpGetTestFull("http+ncbilb://test/Service/test.cgi");
126 static const string s_UrlNcbilbHttpGetFcgi("http+ncbilb://cxx-fast-cgi-sample");
127 static const string s_UrlNcbilbHttpPostBounce("http+ncbilb://bouncehttp");
128 static const string s_UrlNcbilbHttpPostBounceFull("http+ncbilb://bouncehttp/Service/bounce.cgi");
129 static const string s_UrlNcbilbHttpPostFcgi("http+ncbilb://cxx-fast-cgi-sample");
130 
131 
132 // Notes on why some combinations of test factors aren't run:
133 //  * LBSMD doesn't support service-based URLs on Windows (but it should work on Cygwin),
134 //      but it's conditionally compiled out rather than removing test cases.
135 //  * LBSMD is also not available on some testsuite hosts.
136 //  * Linkerd can only be used for service-based URLs (it's a service mesh technology).
137 //  * CHttpStream doesn't currently support service-based URLs.
138 
139 static STest s_Tests[] = {
140 
141     // TODO: THESE ARE TEMPORARY AS EXAMPLES FOR DEBUGGING (FOR LACK OF BETTER EXAMPLES) - DO NOT USE IN PRODUCTION - THEY DON'T BELONG TO US.
142     // REPLACE THEM WITH OTHER LEGITIMATE TEST SERVICES HAVING SIMILAR URL AND POST DATA FORMATS.
143     // curl -H "Host: gi2accn.linkerd.ncbi.nlm.nih.gov" "http://linkerd:4140/sviewer/girevhist.cgi?cmd=seqid&seqid=fasta&val=1322283"
144     //STest(eHttpGet,  eLinkerd,      "ncbilb://gi2accn/sviewer/girevhist.cgi?cmd=seqid&seqid=fasta&val=1322283", R"(^gb\|U54469\.1\|DMU54469\n.*$)"),
145     //STest(eHttpGet,  eLinkerd, "http+ncbilb://gi2accn/sviewer/girevhist.cgi?cmd=seqid&seqid=fasta&val=1322283", R"(^gb\|U54469\.1\|DMU54469\n.*$)"),
146     //STest(eHttpPost, eLinkerd,      "ncbilb://gi2accn/sviewer/girevhist.cgi",                                   R"(^gb\|U54469\.1\|DMU54469\n.*$)", "cmd=seqid&seqid=fasta&val=1322283"),
147     //STest(eHttpPost, eLinkerd, "http+ncbilb://gi2accn/sviewer/girevhist.cgi",                                   R"(^gb\|U54469\.1\|DMU54469\n.*$)", "cmd=seqid&seqid=fasta&val=1322283"),
148 
149     // Service-name-only URLs
150 
151     STest(eHttpGet,  eDispd,   s_UrlServiceGet_test,    s_kExpData_GetTest),
152     STest(eHttpGet,  eLbsmd,   s_UrlServiceGet_test,    s_kExpData_GetTest),
153     STest(eHttpGet,  eLinkerd, s_UrlServiceGet_fcgi,    s_kExpData_GetFcgi),
154     STest(eHttpGet,  eLocal,   s_UrlServiceGet_test,    s_kExpData_GetTest),
155     STest(eHttpGet,  eNamerd,  s_UrlServiceGet_test,    s_kExpData_GetTest),
156     STest(eHttpGet,  eNamerd,  s_UrlServiceGet_fcgi,    s_kExpData_GetFcgi),
157     STest(eHttpPost, eDispd,   s_UrlServicePost_bounce, s_kExpData_PostBounce),
158     STest(eHttpPost, eLbsmd,   s_UrlServicePost_bounce, s_kExpData_PostBounce),
159     STest(eHttpPost, eLinkerd, s_UrlServicePost_fcgi,   s_kExpData_PostFcgi, s_kPostData_Fcgi),
160     STest(eHttpPost, eLocal,   s_UrlServicePost_bounce, s_kExpData_PostBounce),
161     STest(eHttpPost, eNamerd,  s_UrlServicePost_bounce, s_kExpData_PostBounce),
162     STest(eHttpPost, eNamerd,  s_UrlServicePost_fcgi,   s_kExpData_PostFcgi, s_kPostData_Fcgi),
163 
164     STest(eNewRequestGet,  eDispd,   s_UrlServiceGet_test,  s_kExpData_GetTest),
165     STest(eNewRequestGet,  eLbsmd,   s_UrlServiceGet_test,  s_kExpData_GetTest),
166     STest(eNewRequestGet,  eLinkerd, s_UrlServiceGet_fcgi,  s_kExpData_GetFcgi),
167     STest(eNewRequestGet,  eLocal,   s_UrlServiceGet_test,  s_kExpData_GetTest),
168     STest(eNewRequestGet,  eNamerd,  s_UrlServiceGet_test,  s_kExpData_GetTest),
169     STest(eNewRequestGet,  eNamerd,  s_UrlServiceGet_fcgi,  s_kExpData_GetFcgi),
170     STest(eNewRequestPost, eDispd,   s_UrlServicePost_bounce,   s_kExpData_PostBounce),
171     STest(eNewRequestPost, eLbsmd,   s_UrlServicePost_bounce,   s_kExpData_PostBounce),
172     STest(eNewRequestPost, eLinkerd, s_UrlServicePost_fcgi,     s_kExpData_PostFcgi, s_kPostData_Fcgi),
173     STest(eNewRequestPost, eLocal,   s_UrlServicePost_bounce,   s_kExpData_PostBounce),
174     STest(eNewRequestPost, eNamerd,  s_UrlServicePost_bounce,   s_kExpData_PostBounce),
175     STest(eNewRequestPost, eNamerd,  s_UrlServicePost_fcgi,     s_kExpData_PostFcgi, s_kPostData_Fcgi),
176 
177     // Host-based URLs
178 
179     STest(eHttpGet,  eDispd,   s_UrlHostGetHttp,    s_kExpData_GetTest),
180     STest(eHttpGet,  eLbsmd,   s_UrlHostGetHttp,    s_kExpData_GetTest),
181     STest(eHttpGet,  eLocal,   s_UrlHostGetHttp,    s_kExpData_GetTest),
182     STest(eHttpGet,  eNamerd,  s_UrlHostGetHttp,    s_kExpData_GetTest),
183     STest(eHttpGet,  eDispd,   s_UrlHostGetHttps,   s_kExpData_GetTest),
184     STest(eHttpGet,  eLbsmd,   s_UrlHostGetHttps,   s_kExpData_GetTest),
185     STest(eHttpGet,  eLocal,   s_UrlHostGetHttps,   s_kExpData_GetTest),
186     STest(eHttpGet,  eNamerd,  s_UrlHostGetHttps,   s_kExpData_GetTest),
187     STest(eHttpPost, eDispd,   s_UrlHostPostHttp,   s_kExpData_PostBounce),
188     STest(eHttpPost, eLbsmd,   s_UrlHostPostHttp,   s_kExpData_PostBounce),
189     STest(eHttpPost, eLocal,   s_UrlHostPostHttp,   s_kExpData_PostBounce),
190     STest(eHttpPost, eNamerd,  s_UrlHostPostHttp,   s_kExpData_PostBounce),
191     STest(eHttpPost, eDispd,   s_UrlHostPostHttps,  s_kExpData_PostBounce),
192     STest(eHttpPost, eLbsmd,   s_UrlHostPostHttps,  s_kExpData_PostBounce),
193     STest(eHttpPost, eLocal,   s_UrlHostPostHttps,  s_kExpData_PostBounce),
194     STest(eHttpPost, eNamerd,  s_UrlHostPostHttps,  s_kExpData_PostBounce),
195 
196     STest(eHttpStreamGet,  eDispd,   s_UrlHostGetHttp,  s_kExpData_GetTest),
197     STest(eHttpStreamGet,  eLbsmd,   s_UrlHostGetHttp,  s_kExpData_GetTest),
198     STest(eHttpStreamGet,  eLocal,   s_UrlHostGetHttp,  s_kExpData_GetTest),
199     STest(eHttpStreamGet,  eNamerd,  s_UrlHostGetHttp,  s_kExpData_GetTest),
200     STest(eHttpStreamGet,  eDispd,   s_UrlHostGetHttps, s_kExpData_GetTest),
201     STest(eHttpStreamGet,  eLbsmd,   s_UrlHostGetHttps, s_kExpData_GetTest),
202     STest(eHttpStreamGet,  eLocal,   s_UrlHostGetHttps, s_kExpData_GetTest),
203     STest(eHttpStreamGet,  eNamerd,  s_UrlHostGetHttps, s_kExpData_GetTest),
204     STest(eHttpStreamPost, eDispd,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
205     STest(eHttpStreamPost, eLbsmd,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
206     STest(eHttpStreamPost, eLocal,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
207     STest(eHttpStreamPost, eNamerd,  s_UrlHostPostHttp,     s_kExpData_PostBounce),
208     STest(eHttpStreamPost, eDispd,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
209     STest(eHttpStreamPost, eLbsmd,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
210     STest(eHttpStreamPost, eLocal,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
211     STest(eHttpStreamPost, eNamerd,  s_UrlHostPostHttps,    s_kExpData_PostBounce),
212 
213     STest(eNewRequestGet,  eDispd,   s_UrlHostGetHttp,  s_kExpData_GetTest),
214     STest(eNewRequestGet,  eLbsmd,   s_UrlHostGetHttp,  s_kExpData_GetTest),
215     STest(eNewRequestGet,  eLocal,   s_UrlHostGetHttp,  s_kExpData_GetTest),
216     STest(eNewRequestGet,  eNamerd,  s_UrlHostGetHttp,  s_kExpData_GetTest),
217     STest(eNewRequestGet,  eDispd,   s_UrlHostGetHttps, s_kExpData_GetTest),
218     STest(eNewRequestGet,  eLbsmd,   s_UrlHostGetHttps, s_kExpData_GetTest),
219     STest(eNewRequestGet,  eLocal,   s_UrlHostGetHttps, s_kExpData_GetTest),
220     STest(eNewRequestGet,  eNamerd,  s_UrlHostGetHttps, s_kExpData_GetTest),
221     STest(eNewRequestPost, eDispd,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
222     STest(eNewRequestPost, eLbsmd,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
223     STest(eNewRequestPost, eLocal,   s_UrlHostPostHttp,     s_kExpData_PostBounce),
224     STest(eNewRequestPost, eNamerd,  s_UrlHostPostHttp,     s_kExpData_PostBounce),
225     STest(eNewRequestPost, eDispd,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
226     STest(eNewRequestPost, eLbsmd,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
227     STest(eNewRequestPost, eLocal,   s_UrlHostPostHttps,    s_kExpData_PostBounce),
228     STest(eNewRequestPost, eNamerd,  s_UrlHostPostHttps,    s_kExpData_PostBounce),
229 
230     // Special case: test domain URLs
231 
232     STest(eHttpGet,  eDispd,   s_UrlFrontendGet,    s_kExpData_GetTest),
233     STest(eHttpGet,  eLbsmd,   s_UrlFrontendGet,    s_kExpData_GetTest),
234     STest(eHttpGet,  eLocal,   s_UrlFrontendGet,    s_kExpData_GetTest),
235     STest(eHttpGet,  eNamerd,  s_UrlFrontendGet,    s_kExpData_GetTest),
236     STest(eHttpPost, eDispd,   s_UrlFrontendPost,   s_kExpData_PostBounce),
237     STest(eHttpPost, eLbsmd,   s_UrlFrontendPost,   s_kExpData_PostBounce),
238     STest(eHttpPost, eLocal,   s_UrlFrontendPost,   s_kExpData_PostBounce),
239     STest(eHttpPost, eNamerd,  s_UrlFrontendPost,   s_kExpData_PostBounce),
240 
241     STest(eHttpStreamGet,  eDispd,   s_UrlFrontendGet,  s_kExpData_GetTest),
242     STest(eHttpStreamGet,  eLbsmd,   s_UrlFrontendGet,  s_kExpData_GetTest),
243     STest(eHttpStreamGet,  eLocal,   s_UrlFrontendGet,  s_kExpData_GetTest),
244     STest(eHttpStreamGet,  eNamerd,  s_UrlFrontendGet,  s_kExpData_GetTest),
245     STest(eHttpStreamPost, eDispd,   s_UrlFrontendPost, s_kExpData_PostBounce),
246     STest(eHttpStreamPost, eLbsmd,   s_UrlFrontendPost, s_kExpData_PostBounce),
247     STest(eHttpStreamPost, eLocal,   s_UrlFrontendPost, s_kExpData_PostBounce),
248     STest(eHttpStreamPost, eNamerd,  s_UrlFrontendPost, s_kExpData_PostBounce),
249 
250     STest(eNewRequestGet,  eDispd,   s_UrlFrontendGet,  s_kExpData_GetTest),
251     STest(eNewRequestGet,  eLbsmd,   s_UrlFrontendGet,  s_kExpData_GetTest),
252     STest(eNewRequestGet,  eLocal,   s_UrlFrontendGet,  s_kExpData_GetTest),
253     STest(eNewRequestGet,  eNamerd,  s_UrlFrontendGet,  s_kExpData_GetTest),
254     STest(eNewRequestPost, eDispd,   s_UrlFrontendPost, s_kExpData_PostBounce),
255     STest(eNewRequestPost, eLbsmd,   s_UrlFrontendPost, s_kExpData_PostBounce),
256     STest(eNewRequestPost, eLocal,   s_UrlFrontendPost, s_kExpData_PostBounce),
257     STest(eNewRequestPost, eNamerd,  s_UrlFrontendPost, s_kExpData_PostBounce),
258 
259     // Full service-based URLs, no scheme
260 
261     STest(eHttpGet,  eDispd,   s_UrlNcbilbGetTest,      s_kExpData_GetTest),
262     STest(eHttpGet,  eDispd,   s_UrlNcbilbGetTestFull,  s_kExpData_GetTest),
263     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbGetTest,      s_kExpData_GetTest),
264     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbGetTestFull,  s_kExpData_GetTest),
265     STest(eHttpGet,  eLinkerd, s_UrlNcbilbGetFcgi,      s_kExpData_GetFcgi),
266     STest(eHttpGet,  eLocal,   s_UrlNcbilbGetTest,      s_kExpData_GetTest),
267     STest(eHttpGet,  eLocal,   s_UrlNcbilbGetTestFull,  s_kExpData_GetTest),
268     STest(eHttpGet,  eNamerd,  s_UrlNcbilbGetTest,      s_kExpData_GetTest),
269     STest(eHttpGet,  eNamerd,  s_UrlNcbilbGetTestFull,  s_kExpData_GetTest),
270     STest(eHttpGet,  eNamerd,  s_UrlNcbilbGetFcgi,      s_kExpData_GetFcgi),
271     STest(eHttpPost, eDispd,   s_UrlNcbilbPostBounce,       s_kExpData_PostBounce),
272     STest(eHttpPost, eDispd,   s_UrlNcbilbPostBounceFull,   s_kExpData_PostBounce),
273     STest(eHttpPost, eLbsmd,   s_UrlNcbilbPostBounce,       s_kExpData_PostBounce),
274     STest(eHttpPost, eLbsmd,   s_UrlNcbilbPostBounceFull,   s_kExpData_PostBounce),
275     STest(eHttpPost, eLinkerd, s_UrlNcbilbPostFcgi,         s_kExpData_PostFcgi, s_kPostData_Fcgi),
276     STest(eHttpPost, eLocal,   s_UrlNcbilbPostBounce,       s_kExpData_PostBounce),
277     STest(eHttpPost, eLocal,   s_UrlNcbilbPostBounceFull,   s_kExpData_PostBounce),
278     STest(eHttpPost, eNamerd,  s_UrlNcbilbPostBounce,       s_kExpData_PostBounce),
279     STest(eHttpPost, eNamerd,  s_UrlNcbilbPostBounceFull,   s_kExpData_PostBounce),
280     STest(eHttpPost, eNamerd,  s_UrlNcbilbPostFcgi,         s_kExpData_PostFcgi, s_kPostData_Fcgi),
281 
282     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbGetTest,        s_kExpData_GetTest),
283     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbGetTestFull,    s_kExpData_GetTest),
284     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbGetTest,        s_kExpData_GetTest),
285     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbGetTestFull,    s_kExpData_GetTest),
286     STest(eNewRequestGet,  eLinkerd, s_UrlNcbilbGetFcgi,        s_kExpData_GetFcgi),
287     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbGetTest,        s_kExpData_GetTest),
288     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbGetTestFull,    s_kExpData_GetTest),
289     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbGetTest,        s_kExpData_GetTest),
290     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbGetTestFull,    s_kExpData_GetTest),
291     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbGetFcgi,        s_kExpData_GetFcgi),
292     STest(eNewRequestPost, eDispd,   s_UrlNcbilbPostBounce,     s_kExpData_PostBounce),
293     STest(eNewRequestPost, eDispd,   s_UrlNcbilbPostBounceFull, s_kExpData_PostBounce),
294     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbPostBounce,     s_kExpData_PostBounce),
295     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbPostBounceFull, s_kExpData_PostBounce),
296     STest(eNewRequestPost, eLinkerd, s_UrlNcbilbPostFcgi,       s_kExpData_PostFcgi, s_kPostData_Fcgi),
297     STest(eNewRequestPost, eLocal,   s_UrlNcbilbPostBounce,     s_kExpData_PostBounce),
298     STest(eNewRequestPost, eLocal,   s_UrlNcbilbPostBounceFull, s_kExpData_PostBounce),
299     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbPostBounce,     s_kExpData_PostBounce),
300     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbPostBounceFull, s_kExpData_PostBounce),
301     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbPostFcgi,       s_kExpData_PostFcgi, s_kPostData_Fcgi),
302 
303     // Full service-based URLs, http scheme
304 
305     STest(eHttpGet,  eDispd,   s_UrlNcbilbHttpGetTest,      s_kExpData_GetTest),
306     STest(eHttpGet,  eDispd,   s_UrlNcbilbHttpGetTestFull,  s_kExpData_GetTest),
307     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbHttpGetTest,      s_kExpData_GetTest),
308     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbHttpGetTestFull,  s_kExpData_GetTest),
309     STest(eHttpGet,  eLinkerd, s_UrlNcbilbHttpGetFcgi,      s_kExpData_GetFcgi),
310     STest(eHttpGet,  eLocal,   s_UrlNcbilbHttpGetTest,      s_kExpData_GetTest),
311     STest(eHttpGet,  eLocal,   s_UrlNcbilbHttpGetTestFull,  s_kExpData_GetTest),
312     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpGetTest,      s_kExpData_GetTest),
313     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpGetTestFull,  s_kExpData_GetTest),
314     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpGetFcgi,      s_kExpData_GetFcgi),
315     STest(eHttpPost, eDispd,   s_UrlNcbilbHttpPostBounce,       s_kExpData_PostBounce),
316     STest(eHttpPost, eDispd,   s_UrlNcbilbHttpPostBounceFull,   s_kExpData_PostBounce),
317     STest(eHttpPost, eLbsmd,   s_UrlNcbilbHttpPostBounce,       s_kExpData_PostBounce),
318     STest(eHttpPost, eLbsmd,   s_UrlNcbilbHttpPostBounceFull,   s_kExpData_PostBounce),
319     STest(eHttpPost, eLinkerd, s_UrlNcbilbHttpPostFcgi,         s_kExpData_PostFcgi, s_kPostData_Fcgi),
320     STest(eHttpPost, eLocal,   s_UrlNcbilbHttpPostBounce,       s_kExpData_PostBounce),
321     STest(eHttpPost, eLocal,   s_UrlNcbilbHttpPostBounceFull,   s_kExpData_PostBounce),
322     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpPostBounce,       s_kExpData_PostBounce),
323     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpPostBounceFull,   s_kExpData_PostBounce),
324     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpPostFcgi,         s_kExpData_PostFcgi, s_kPostData_Fcgi),
325 
326     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbHttpGetTest,        s_kExpData_GetTest),
327     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbHttpGetTestFull,    s_kExpData_GetTest),
328     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbHttpGetTest,        s_kExpData_GetTest),
329     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbHttpGetTestFull,    s_kExpData_GetTest),
330     STest(eNewRequestGet,  eLinkerd, s_UrlNcbilbHttpGetFcgi,        s_kExpData_GetFcgi),
331     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbHttpGetTest,        s_kExpData_GetTest),
332     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbHttpGetTestFull,    s_kExpData_GetTest),
333     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpGetTest,        s_kExpData_GetTest),
334     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpGetTestFull,    s_kExpData_GetTest),
335     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpGetFcgi,        s_kExpData_GetFcgi),
336     STest(eNewRequestPost, eDispd,   s_UrlNcbilbHttpPostBounce,     s_kExpData_PostBounce),
337     STest(eNewRequestPost, eDispd,   s_UrlNcbilbHttpPostBounceFull, s_kExpData_PostBounce),
338     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbHttpPostBounce,     s_kExpData_PostBounce),
339     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbHttpPostBounceFull, s_kExpData_PostBounce),
340     STest(eNewRequestPost, eLinkerd, s_UrlNcbilbHttpPostFcgi,       s_kExpData_PostFcgi, s_kPostData_Fcgi),
341     STest(eNewRequestPost, eLocal,   s_UrlNcbilbHttpPostBounce,     s_kExpData_PostBounce),
342     STest(eNewRequestPost, eLocal,   s_UrlNcbilbHttpPostBounceFull, s_kExpData_PostBounce),
343     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpPostBounce,     s_kExpData_PostBounce),
344     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpPostBounceFull, s_kExpData_PostBounce),
345     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpPostFcgi,       s_kExpData_PostFcgi, s_kPostData_Fcgi),
346 
347     // Full service-based URLs, https scheme
348 
349 // TODO: Add the following when you find a service that can be used for regular testing via HTTPS.
350 #if 0
351     STest(eHttpGet,  eDispd,   s_UrlNcbilbHttpsGetTest,     s_kExpData_GetTest),
352     STest(eHttpGet,  eDispd,   s_UrlNcbilbHttpsGetTestFull, s_kExpData_GetTest),
353     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbHttpsGetTest,     s_kExpData_GetTest),
354     STest(eHttpGet,  eLbsmd,   s_UrlNcbilbHttpsGetTestFull, s_kExpData_GetTest),
355     STest(eHttpGet,  eLinkerd, s_UrlNcbilbHttpsGetFcgi,     s_kExpData_GetFcgi),
356     STest(eHttpGet,  eLocal,   s_UrlNcbilbHttpsGetTest,     s_kExpData_GetTest),
357     STest(eHttpGet,  eLocal,   s_UrlNcbilbHttpsGetTestFull, s_kExpData_GetTest),
358     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpsGetTest,     s_kExpData_GetTest),
359     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpsGetTestFull, s_kExpData_GetTest),
360     STest(eHttpGet,  eNamerd,  s_UrlNcbilbHttpsGetFcgi,     s_kExpData_GetFcgi),
361     STest(eHttpPost, eDispd,   s_UrlNcbilbHttpsPostBounce,      s_kExpData_PostBounce),
362     STest(eHttpPost, eDispd,   s_UrlNcbilbHttpsPostBounceFull,  s_kExpData_PostBounce),
363     STest(eHttpPost, eLbsmd,   s_UrlNcbilbHttpsPostBounce,      s_kExpData_PostBounce),
364     STest(eHttpPost, eLbsmd,   s_UrlNcbilbHttpsPostBounceFull,  s_kExpData_PostBounce),
365     STest(eHttpPost, eLinkerd, s_UrlNcbilbHttpsPostFcgi,        s_kExpData_PostFcgi, s_kPostData_Fcgi),
366     STest(eHttpPost, eLocal,   s_UrlNcbilbHttpsPostBounce,      s_kExpData_PostBounce),
367     STest(eHttpPost, eLocal,   s_UrlNcbilbHttpsPostBounceFull,  s_kExpData_PostBounce),
368     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpsPostBounce,      s_kExpData_PostBounce),
369     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpsPostBounceFull,  s_kExpData_PostBounce),
370     STest(eHttpPost, eNamerd,  s_UrlNcbilbHttpsPostFcgi,        s_kExpData_PostFcgi, s_kPostData_Fcgi),
371 
372     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbHttpsGetTest,       s_kExpData_GetTest),
373     STest(eNewRequestGet,  eDispd,   s_UrlNcbilbHttpsGetTestFull,   s_kExpData_GetTest),
374     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbHttpsGetTest,       s_kExpData_GetTest),
375     STest(eNewRequestGet,  eLbsmd,   s_UrlNcbilbHttpsGetTestFull,   s_kExpData_GetTest),
376     STest(eNewRequestGet,  eLinkerd, s_UrlNcbilbHttpsGetFcgi,       s_kExpData_GetFcgi),
377     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbHttpsGetTest,       s_kExpData_GetTest),
378     STest(eNewRequestGet,  eLocal,   s_UrlNcbilbHttpsGetTestFull,   s_kExpData_GetTest),
379     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpsGetTest,       s_kExpData_GetTest),
380     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpsGetTestFull,   s_kExpData_GetTest),
381     STest(eNewRequestGet,  eNamerd,  s_UrlNcbilbHttpsGetFcgi,       s_kExpData_GetFcgi),
382     STest(eNewRequestPost, eDispd,   s_UrlNcbilbHttpsPostBounce,        s_kExpData_PostBounce),
383     STest(eNewRequestPost, eDispd,   s_UrlNcbilbHttpsPostBounceFull,    s_kExpData_PostBounce),
384     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbHttpsPostBounce,        s_kExpData_PostBounce),
385     STest(eNewRequestPost, eLbsmd,   s_UrlNcbilbHttpsPostBounceFull,    s_kExpData_PostBounce),
386     STest(eNewRequestPost, eLinkerd, s_UrlNcbilbHttpsPostFcgi,          s_kExpData_PostFcgi, s_kPostData_Fcgi),
387     STest(eNewRequestPost, eLocal,   s_UrlNcbilbHttpsPostBounce,        s_kExpData_PostBounce),
388     STest(eNewRequestPost, eLocal,   s_UrlNcbilbHttpsPostBounceFull,    s_kExpData_PostBounce),
389     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpsPostBounce,        s_kExpData_PostBounce),
390     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpsPostBounceFull,    s_kExpData_PostBounce),
391     STest(eNewRequestPost, eNamerd,  s_UrlNcbilbHttpsPostFcgi,          s_kExpData_PostFcgi, s_kPostData_Fcgi),
392 #endif
393 };
394 
395 
396 // Helper class to change service mappers
397 class CMapper
398 {
399 public:
Configure(void)400     void Configure(void)
401     {
402         for (auto const& env : m_EnvSet) {
403             setenv(env.first.c_str(), env.second.c_str(), 1);
404         }
405         for (auto const& env : m_EnvUnset) {
406             unsetenv(env.c_str());
407         }
408     }
409     static void Init(vector<CMapper>& mappers);
410 
411     int                     m_Id;
412     string                  m_Name;
413     bool                    m_Enabled;
414     map<string, string>     m_EnvSet;
415     list<string>            m_EnvUnset;
416 };
417 
418 
419 class CTestNcbiLinkerdCxxApp : public CNcbiApplication
420 {
421 public:
422     virtual void Init(void);
423     virtual int  Run(void);
424 
425 private:
426     void SelectMapper(int id);
427 
428     int CompareResponse(const string& expected, const string& got);
429     int ProcessResponse(CHttpResponse& resp, const string& expected);
430 
431     void TestCaseLine(
432         int id,
433         const string& header,
434         const string& footer,
435         const string& prefix,
436         const string& sep,
437         bool          show_result,
438         int           result,
439         const string& test_case,
440         const string& method,
441         const string& url);
442     void TestCaseStart(
443         int id,
444         const string& test_case,
445         const string& method,
446         const string& url);
447     void TestCaseEnd(
448         int id,
449         const string& test_case,
450         const string& method,
451         int           result,
452         const string& url);
453 
454     int TestGet_Http      (int id, const STest& test);
455     int TestGet_HttpStream(int id, const STest& test);
456     int TestGet_NewRequest(int id, const STest& test);
457 
458     int TestPost_Http      (int id, const STest& test);
459     int TestPost_HttpStream(int id, const STest& test);
460     int TestPost_NewRequest(int id, const STest& test);
461 
462 private:
463     char                m_Hostname[300];
464 
465     vector<CMapper>     m_Mappers;
466     string              m_MapperName;
467 };
468 
469 
Init(vector<CMapper> & mappers)470 void CMapper::Init(vector<CMapper>& mappers)
471 {
472     {{
473         CMapper mapper;
474         mapper.m_Id = eDispd;
475         mapper.m_Name = "dispd";
476         mapper.m_Enabled = true;
477         mapper.m_EnvSet["CONN_DISPD_DISABLE"] = "0";
478         mapper.m_EnvSet["CONN_LBSMD_DISABLE"] = "1";
479         mapper.m_EnvSet["CONN_LINKERD_ENABLE"] = "0";
480         mapper.m_EnvSet["CONN_LOCAL_ENABLE"] = "0";
481         mapper.m_EnvSet["CONN_NAMERD_ENABLE"] = "0";
482         mapper.m_EnvUnset.push_back("CONN_LOCAL_SERVICES");
483         mapper.m_EnvUnset.push_back("TEST_CONN_LOCAL_SERVER_1");
484         mapper.m_EnvUnset.push_back("BOUNCEHTTP_CONN_LOCAL_SERVER_1");
485         mappers.push_back(mapper);
486     }}
487 
488     {{
489         CMapper mapper;
490         mapper.m_Id = eLbsmd;
491         mapper.m_Name = "lbsmd";
492         mapper.m_Enabled = true;
493         mapper.m_EnvSet["CONN_DISPD_DISABLE"] = "1";
494         mapper.m_EnvSet["CONN_LBSMD_DISABLE"] = "0";
495         mapper.m_EnvSet["CONN_LINKERD_ENABLE"] = "0";
496         mapper.m_EnvSet["CONN_LOCAL_ENABLE"] = "0";
497         mapper.m_EnvSet["CONN_NAMERD_ENABLE"] = "0";
498         mapper.m_EnvUnset.push_back("CONN_LOCAL_SERVICES");
499         mapper.m_EnvUnset.push_back("TEST_CONN_LOCAL_SERVER_1");
500         mapper.m_EnvUnset.push_back("BOUNCEHTTP_CONN_LOCAL_SERVER_1");
501         mappers.push_back(mapper);
502     }}
503 
504     {{
505         CMapper mapper;
506         mapper.m_Id = eLinkerd;
507         mapper.m_Name = "linkerd";
508         mapper.m_Enabled = true;
509         mapper.m_EnvSet["CONN_DISPD_DISABLE"] = "1";
510         mapper.m_EnvSet["CONN_LBSMD_DISABLE"] = "1";
511         mapper.m_EnvSet["CONN_LINKERD_ENABLE"] = "1";
512         mapper.m_EnvSet["CONN_LOCAL_ENABLE"] = "0";
513         mapper.m_EnvSet["CONN_NAMERD_ENABLE"] = "0";
514         mapper.m_EnvUnset.push_back("CONN_LOCAL_SERVICES");
515         mapper.m_EnvUnset.push_back("TEST_CONN_LOCAL_SERVER_1");
516         mapper.m_EnvUnset.push_back("BOUNCEHTTP_CONN_LOCAL_SERVER_1");
517         mappers.push_back(mapper);
518     }}
519 
520     {{
521         CMapper mapper;
522         mapper.m_Id = eLocal;
523         mapper.m_Name = "local";
524         mapper.m_Enabled = true;
525         mapper.m_EnvSet["CONN_DISPD_DISABLE"] = "1";
526         mapper.m_EnvSet["CONN_LBSMD_DISABLE"] = "1";
527         mapper.m_EnvSet["CONN_LINKERD_ENABLE"] = "0";
528         mapper.m_EnvSet["CONN_LOCAL_ENABLE"] = "1";
529         mapper.m_EnvSet["CONN_NAMERD_ENABLE"] = "0";
530         mapper.m_EnvSet["CONN_LOCAL_SERVICES"] = "TEST BOUNCEHTTP";
531         // TODO: do not hard-code sutils101 - look up bouncehttp with lbsmc and use the dynamic result
532         mapper.m_EnvSet["TEST_CONN_LOCAL_SERVER_1"] = "HTTP_GET sutils101:80 /Service/test.cgi";
533         mapper.m_EnvSet["BOUNCEHTTP_CONN_LOCAL_SERVER_1"] = "HTTP sutils101:80 /Service/bounce.cgi";
534         mappers.push_back(mapper);
535     }}
536 
537     {{
538         CMapper mapper;
539         mapper.m_Id = eNamerd;
540         mapper.m_Name = "namerd";
541         mapper.m_Enabled = true;
542         mapper.m_EnvSet["CONN_DISPD_DISABLE"] = "1";
543         mapper.m_EnvSet["CONN_LBSMD_DISABLE"] = "1";
544         mapper.m_EnvSet["CONN_LINKERD_ENABLE"] = "0";
545         mapper.m_EnvSet["CONN_LOCAL_ENABLE"] = "0";
546         mapper.m_EnvSet["CONN_NAMERD_ENABLE"] = "1";
547         mapper.m_EnvUnset.push_back("CONN_LOCAL_SERVICES");
548         mapper.m_EnvUnset.push_back("TEST_CONN_LOCAL_SERVER_1");
549         mapper.m_EnvUnset.push_back("BOUNCEHTTP_CONN_LOCAL_SERVER_1");
550         mappers.push_back(mapper);
551     }}
552 }
553 
554 
SelectMapper(int id)555 void CTestNcbiLinkerdCxxApp::SelectMapper(int id)
556 {
557     for (auto& mapper : m_Mappers) {
558         if (mapper.m_Id == id) {
559             mapper.Configure();
560             m_MapperName = mapper.m_Name;
561             return;
562         }
563     }
564     NCBI_USER_THROW(string("MAPPER ") + NStr::NumericToString<int>(id) + " NOT FOUND");
565 }
566 
567 
CompareResponse(const string & expected,const string & got)568 int CTestNcbiLinkerdCxxApp::CompareResponse(const string& expected, const string& got)
569 {
570     CRegexp re(expected, CRegexp::fCompile_dotall);
571     if (re.IsMatch(got)) {
572         ERR_POST(Info << "--- Response Body (STDOUT) ---");
573         ERR_POST(Info << got);
574         return 0;
575     } else {
576         ERR_POST(Error << "--- Response Body (STDOUT) ---  did not match expected value");
577         size_t pos = 0, len;
578         string escaped = expected;
579         len = escaped.length();
580         while ((pos = escaped.find("\\", pos)) != NPOS) { escaped.replace(pos, 1, "\\\\"); pos += 2; }
581         while ((pos = escaped.find("\r", pos)) != NPOS) { escaped.replace(pos, 1, "\\r");  pos += 2; }
582         while ((pos = escaped.find("\n", pos)) != NPOS) { escaped.replace(pos, 1, "\\n");  pos += 2; }
583         ERR_POST(Info << "Escaped exp string (length " << len << "): [" << escaped << "]");
584         escaped = got;
585         len = escaped.length();
586         while ((pos = escaped.find("\\", pos)) != NPOS) { escaped.replace(pos, 1, "\\\\"); pos += 2; }
587         while ((pos = escaped.find("\r", pos)) != NPOS) { escaped.replace(pos, 1, "\\r");  pos += 2; }
588         while ((pos = escaped.find("\n", pos)) != NPOS) { escaped.replace(pos, 1, "\\n");  pos += 2; }
589         ERR_POST(Info << "Escaped got string (length " << len << "): [" << escaped << "]");
590     }
591     return 1;
592 }
593 
594 
ProcessResponse(CHttpResponse & resp,const string & expected)595 int CTestNcbiLinkerdCxxApp::ProcessResponse(CHttpResponse& resp, const string& expected)
596 {
597     ERR_POST(Info << "HTTP Status: " << resp.GetStatusCode() << " " << resp.GetStatusText());
598 
599     string  got;
600     if (resp.CanGetContentStream()) {
601         CNcbiIstream& in = resp.ContentStream();
602         if ( in.good() ) {
603             CNcbiOstrstream out;
604             NcbiStreamCopy(out, in);
605             got = CNcbiOstrstreamToString(out);
606             return CompareResponse(expected, got);
607         }
608         else {
609             ERR_POST(Error << "Bad content stream.");
610         }
611     }
612     else {
613         CNcbiIstream& in = resp.ErrorStream();
614         if (in.good()) {
615             ERR_POST(Info << "--- Response Body (STDERR) ---");
616             CNcbiOstrstream out;
617             NcbiStreamCopy(out, in);
618             got = CNcbiOstrstreamToString(out);
619             ERR_POST(Info << got);
620         }
621         else {
622             ERR_POST(Error << "Bad error stream.");
623         }
624     }
625     return 1;
626 }
627 
628 
TestCaseLine(int id,const string & header,const string & footer,const string & prefix,const string & sep,bool show_result,int result,const string & test_case,const string & method,const string & url)629 void CTestNcbiLinkerdCxxApp::TestCaseLine(
630     int id,
631     const string& header,
632     const string& footer,
633     const string& prefix,
634     const string& sep,
635     bool          show_result,
636     int           result,
637     const string& test_case,
638     const string& method,
639     const string& url)
640 {
641     string msg("\n");
642     msg += header + prefix + sep + NStr::NumericToString<int>(id) + sep +
643            m_Hostname + sep + url + sep + test_case + sep +
644            method + sep + m_MapperName;
645     if (show_result)
646         msg += sep + (result == 0 ? "PASS" : "FAIL");
647     msg += footer + "\n";
648     ERR_POST(Info << msg);
649 }
650 
651 
TestCaseStart(int id,const string & test_case,const string & method,const string & url)652 void CTestNcbiLinkerdCxxApp::TestCaseStart(
653     int id,
654     const string& test_case,
655     const string& method,
656     const string& url)
657 {
658     TestCaseLine(
659         id, string(80, '=') + "\n", "",
660         "TestCaseStart", "\t",
661         false, -1,
662         test_case, method, url);
663 }
664 
665 
666 // Result records can easily be transformed into a CSV.  For example:
667 //      ./test_ncbi_linkerd_cxx | grep -P '^TestCaseEnd\t' | tr '\t' ,
TestCaseEnd(int id,const string & test_case,const string & method,int result,const string & url)668 void CTestNcbiLinkerdCxxApp::TestCaseEnd(
669     int id,
670     const string& test_case,
671     const string& method,
672     int           result,
673     const string& url)
674 {
675     TestCaseLine(
676         id, "", string("\n") + string(80, '-') + "\n",
677         "TestCaseEnd", "\t",
678         true, result,
679         test_case, method, url);
680 }
681 
682 
TestGet_Http(int id,const STest & test)683 int CTestNcbiLinkerdCxxApp::TestGet_Http(int id, const STest& test)
684 {
685     TestCaseStart(id, "g_HttpGet", "GET", test.url);
686     CHttpResponse resp = g_HttpGet(CUrl(test.url));
687     int result = ProcessResponse(resp, test.expected);
688     TestCaseEnd(id, "g_HttpGet", "GET", result, test.url);
689     return result;
690 }
691 
692 
TestGet_HttpStream(int id,const STest & test)693 int CTestNcbiLinkerdCxxApp::TestGet_HttpStream(int id, const STest& test)
694 {
695     int retval = 1;
696     TestCaseStart(id, "CConn_HttpStream", "GET", test.url);
697     try {
698         CConn_HttpStream httpstr(test.url);
699         CConn_MemoryStream mem_str;
700         NcbiStreamCopy(mem_str, httpstr);
701         string got;
702         mem_str.ToString(&got);
703         retval = CompareResponse(test.expected, got);
704     }
705     catch (CException& ex) {
706         ERR_POST(Error << "HttpStream exception: " << ex.what());
707     }
708     TestCaseEnd(id, "CConn_HttpStream", "GET", retval, test.url);
709     return retval;
710 }
711 
712 
TestGet_NewRequest(int id,const STest & test)713 int CTestNcbiLinkerdCxxApp::TestGet_NewRequest(int id, const STest& test)
714 {
715     TestCaseStart(id, "CHttpSession::NewRequest", "GET", test.url);
716     CHttpSession session;
717     CHttpRequest req = session.NewRequest(CUrl(test.url));
718     req.SetTimeout(10);
719     req.SetRetries(3);
720     CHttpResponse resp = req.Execute();
721     int result = ProcessResponse(resp, test.expected);
722     TestCaseEnd(id, "CHttpSession::NewRequest", "GET", result, test.url);
723     return result;
724 }
725 
726 
TestPost_Http(int id,const STest & test)727 int CTestNcbiLinkerdCxxApp::TestPost_Http(int id, const STest& test)
728 {
729     TestCaseStart(id, "g_HttpPost", "POST", test.url);
730     CHttpResponse resp = g_HttpPost(CUrl(test.url), test.post);
731     int result = ProcessResponse(resp, test.expected);
732     TestCaseEnd(id, "g_HttpPost", "POST", result, test.url);
733     return result;
734 }
735 
736 
TestPost_HttpStream(int id,const STest & test)737 int CTestNcbiLinkerdCxxApp::TestPost_HttpStream(int id, const STest& test)
738 {
739     int retval = 1;
740     TestCaseStart(id, "CConn_HttpStream", "POST", test.url);
741     try {
742         CConn_HttpStream httpstr(test.url, eReqMethod_Post);
743         httpstr << test.post;
744         CConn_MemoryStream mem_str;
745         NcbiStreamCopy(mem_str, httpstr);
746         string got;
747         mem_str.ToString(&got);
748         retval = CompareResponse(test.expected, got);
749     }
750     catch (CException& ex) {
751         ERR_POST(Error << "HttpStream exception: " << ex.what());
752     }
753     TestCaseEnd(id, "CConn_HttpStream", "POST", retval, test.url);
754     return retval;
755 }
756 
757 
TestPost_NewRequest(int id,const STest & test)758 int CTestNcbiLinkerdCxxApp::TestPost_NewRequest(int id, const STest& test)
759 {
760     TestCaseStart(id, "CHttpSession::NewRequest", "POST", test.url);
761     CHttpSession session;
762     CHttpRequest req = session.NewRequest(CUrl(test.url), CHttpSession::ePost);
763     req.SetTimeout(10);
764     req.SetRetries(3);
765     req.ContentStream() << test.post;
766     CHttpResponse resp = req.Execute();
767     int result = ProcessResponse(resp, test.expected);
768     TestCaseEnd(id, "CHttpSession::NewRequest", "POST", result, test.url);
769     return result;
770 }
771 
772 
Init(void)773 void CTestNcbiLinkerdCxxApp::Init(void)
774 {
775     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
776     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
777                               "Test Linkerd via C++ classes");
778 
779     SetupArgDescriptions(arg_desc.release());
780 
781     SOCK_gethostname(m_Hostname, sizeof(m_Hostname));
782 
783     CMapper::Init(m_Mappers);
784 }
785 
786 
Run(void)787 int CTestNcbiLinkerdCxxApp::Run(void)
788 {
789     int num_total = sizeof(s_Tests) / sizeof(s_Tests[0]);
790     int num_run = 0, num_skipped = 0, num_passed = 0, num_failed = 0;
791 
792     ERR_POST(Info << "CTestNcbiLinkerdCxxApp::Run()   $Id: test_ncbi_linkerd_cxx.cpp 578389 2019-01-17 18:08:54Z lavr $");
793 
794     for (auto test : s_Tests) {
795 #if !defined(NCBI_OS_LINUX)  ||  !defined(HAVE_LOCAL_LBSM)
796         if (test.mapper == eLbsmd) {
797             ++num_skipped;
798             continue;
799         }
800 #endif
801         SelectMapper(test.mapper);
802         int result = 1;
803              if (test.func == eHttpGet)         result = TestGet_Http(num_run, test);
804         else if (test.func == eHttpPost)        result = TestPost_Http(num_run, test);
805         else if (test.func == eHttpStreamGet)   result = TestGet_HttpStream(num_run, test);
806         else if (test.func == eHttpStreamPost)  result = TestPost_HttpStream(num_run, test);
807         else if (test.func == eNewRequestGet)   result = TestGet_NewRequest(num_run, test);
808         else if (test.func == eNewRequestPost)  result = TestPost_NewRequest(num_run, test);
809         else
810             NCBI_USER_THROW("Invalid test function");   // would be a programming error
811         if (result == 0)
812             ++num_passed;
813         else
814             ++num_failed;
815         ++num_run;
816     }
817 
818     ERR_POST(Info << "All tests: " << num_total);
819     ERR_POST(Info << "Skipped:     " << num_skipped);
820     ERR_POST(Info << "Executed:    " << num_run);
821     ERR_POST(Info << "Passed:        " << num_passed);
822     ERR_POST(Info << "Failed:        " << num_failed);
823     if (num_total != num_run + num_skipped  ||  num_run != num_passed + num_failed)
824         NCBI_USER_THROW("Invalid test counts.");   // would be a programming error
825 
826     return num_run > 0 ? num_failed : -1;
827 }
828 
829 
main(int argc,char * argv[])830 int main(int argc, char* argv[])
831 {
832     int exit_code = 1;
833 
834     SetDiagTrace(eDT_Enable);
835     SetDiagPostLevel(eDiag_Info);
836     SetDiagPostAllFlags((SetDiagPostAllFlags(eDPF_Default) & ~eDPF_All)
837                         | eDPF_Severity | eDPF_ErrorID | eDPF_Prefix);
838     SetDiagTraceAllFlags(SetDiagPostAllFlags(eDPF_Default));
839 
840     try {
841         exit_code = CTestNcbiLinkerdCxxApp().AppMain(argc, argv);
842     }
843     catch (...) {
844         // ERR_POST may not work
845         cerr << "\n\nunhandled exception" << endl;
846     }
847 
848     return exit_code;
849 }
850