1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 * Unit tests for HTTP interfaces
26 */
27
28 #include "HttpFixture.hpp"
29
30 #include <ktst/unit_test.hpp>
31 #include <kfg/config.h>
32 #include <kns/manager.h>
33 #include <kns/http.h>
34 #include <kfs/directory.h>
35 #include <kfs/file.h>
36
37 using namespace std;
38 using namespace ncbi::NK;
39
40 rc_t CC
Whack(KSTREAM_IMPL * self)41 TestStream :: Whack ( KSTREAM_IMPL *self )
42 {
43 if ( TestEnv::verbosity == LogLevel::e_message )
44 cout << "TestStream::Whack() called" << endl;
45 return 0;
46 }
47
48 rc_t CC
Read(const KSTREAM_IMPL * self,void * buffer,size_t bsize,size_t * num_read)49 TestStream :: Read ( const KSTREAM_IMPL *self, void *buffer, size_t bsize, size_t *num_read )
50 {
51 if ( TestEnv::verbosity == LogLevel::e_message )
52 cout << "TestStream::Read() called" << endl;
53 * num_read = 0;
54 return 0;
55 }
56
57 rc_t CC
Write(KSTREAM_IMPL * self,const void * buffer,size_t size,size_t * num_writ)58 TestStream :: Write ( KSTREAM_IMPL *self, const void *buffer, size_t size, size_t *num_writ )
59 {
60 if ( TestEnv::verbosity == LogLevel::e_message )
61 cout << "TestStream::Write() called" << endl;
62 * num_writ = size;
63 m_requests . push_back ( string ( (const char*)buffer, size) );
64 return 0;
65 }
66
67 rc_t CC
TimedRead(const KSTREAM_IMPL * self,void * buffer,size_t bsize,size_t * num_read,struct timeout_t * tm)68 TestStream :: TimedRead ( const KSTREAM_IMPL *self, void *buffer, size_t bsize, size_t *num_read, struct timeout_t *tm )
69 {
70 if ( TestEnv::verbosity == LogLevel::e_message )
71 cout << "TestStream::TimedRead() called" << endl;
72
73 string response;
74 if ( m_responses.size()> 0)
75 {
76 response = m_responses.front();
77 m_responses.pop_front();
78 }
79 else
80 {
81 throw logic_error ( "TestStream: TimedRead is out of responses" );
82 }
83
84 if ( response.size() >= bsize )
85 {
86 memmove(buffer, response.c_str(), bsize);
87 * num_read = bsize;
88 response = response.substr(bsize);
89 }
90 else
91 {
92 memmove(buffer, response.c_str(), response.size());
93 * num_read = response.size();
94 response.clear();
95 }
96 if ( TestEnv::verbosity == LogLevel::e_message )
97 cout << "TestStream::TimedRead returned \"" << string((const char*)buffer, * num_read) << "\"" << endl;
98
99 return 0;
100 }
101
102 rc_t CC
TimedWrite(KSTREAM_IMPL * self,const void * buffer,size_t size,size_t * num_writ,struct timeout_t * tm)103 TestStream :: TimedWrite ( KSTREAM_IMPL *self, const void *buffer, size_t size, size_t *num_writ, struct timeout_t *tm )
104 {
105 if ( TestEnv::verbosity == LogLevel::e_message )
106 cout << "TestStream::TimedWrite(\"" << string((const char*)buffer, size) << "\") called" << endl;
107 * num_writ = size;
108 m_requests . push_back ( string ( (const char*)buffer, size) );
109 return 0;
110 }
111
112 void
AddResponse(const string & p_str,bool end_binary)113 TestStream :: AddResponse ( const string& p_str, bool end_binary )
114 {
115 if (end_binary)
116 m_responses.push_back(p_str);
117 else
118 m_responses.push_back(std::string(p_str.c_str(), p_str.size() + 1));
119 }
120
121 list<string> TestStream :: m_requests;
122 list<string> TestStream :: m_responses;
123
124 KStream_vt_v1 TestStream::vt =
125 {
126 1, 1,
127 TestStream::Whack,
128 TestStream::Read,
129 TestStream::Write,
130 TestStream::TimedRead,
131 TestStream::TimedWrite
132 };
133
HttpFixture()134 HttpFixture :: HttpFixture()
135 : m_file ( nullptr ),
136 m_req ( nullptr )
137 {
138 if ( KStreamInit ( & m_stream, ( const KStream_vt* ) & TestStream::vt, "TestStream", "", true, true ) != 0 )
139 throw logic_error ( "HttpFixture: KStreamInit failed" );
140
141 TestStream::m_requests.clear();
142 TestStream::m_responses.clear();
143 }
144
~HttpFixture()145 HttpFixture :: ~HttpFixture()
146 {
147 if ( KFileRelease ( m_file ) != 0 )
148 cerr << "HttpFixture::~HttpFixture KFileRelease failed" << endl;
149
150 if ( KClientHttpRequestRelease ( m_req ) != 0 )
151 cerr << "HttpFixture::~HttpFixture KClientHttpRequestRelease failed" << endl;
152
153 if ( ! TestStream::m_responses.empty() )
154 cerr << "HttpFixture::~HttpFixture not all TestStream::m_responses have been consumed" << endl;
155 }
156
157 KConfig*
MakeConfig(const char * name,const char * contents)158 HttpFixture :: MakeConfig( const char* name, const char* contents )
159 {
160 KDirectory* wd;
161 if ( KDirectoryNativeDir ( & wd ) != 0 )
162 throw logic_error("KfgFixture: KDirectoryNativeDir failed");
163
164 {
165 KFile* file;
166 if (KDirectoryCreateFile(wd, &file, true, 0664, kcmInit, name) != 0)
167 throw logic_error("MakeConfig: KDirectoryCreateFile failed");
168
169 size_t num_writ=0;
170 if (KFileWrite(file, 0, contents, strlen(contents), &num_writ) != 0)
171 throw logic_error("MakeConfig: KFileWrite failed");
172
173 if (KFileRelease(file) != 0)
174 throw logic_error("MakeConfig: KFileRelease failed");
175 }
176
177 KConfig* ret;
178 {
179 if (KConfigMake ( & ret, wd ) != 0)
180 throw logic_error("MakeConfig: KConfigMake failed");
181
182 KFile* file;
183 if (KDirectoryOpenFileRead(wd, (const KFile**)&file, name) != 0)
184 throw logic_error("MakeConfig: KDirectoryOpenFileRead failed");
185
186 if (KConfigLoadFile ( ret, name, file) != 0)
187 throw logic_error("MakeConfig: KConfigLoadFile failed");
188
189 if (KFileRelease(file) != 0)
190 throw logic_error("MakeConfig: KFileRelease failed");
191 }
192
193 if (KDirectoryRemove(wd, true, name) != 0)
194 throw logic_error("MakeConfig: KDirectoryRemove failed");
195 if (KDirectoryRelease(wd) != 0)
196 throw logic_error("MakeConfig: KDirectoryRelease failed");
197
198 return ret;
199 }
200
201 struct KStream *
Reconnect()202 HttpFixture :: Reconnect ()
203 {
204 return & m_stream;
205 }
206
207 string
MakeURL(const string & base)208 HttpFixture :: MakeURL(const string & base)
209 {
210 return string("http://") + base + ".com/blah";
211 }
212
213 KStream HttpFixture :: m_stream;
214
215