aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemontest.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemontest.c')
-rw-r--r--src/daemon/daemontest.c278
1 files changed, 35 insertions, 243 deletions
diff --git a/src/daemon/daemontest.c b/src/daemon/daemontest.c
index e110b139..38aadbea 100644
--- a/src/daemon/daemontest.c
+++ b/src/daemon/daemontest.c
@@ -20,7 +20,7 @@
20 20
21/** 21/**
22 * @file daemontest.c 22 * @file daemontest.c
23 * @brief Testcase for libmicrohttpd 23 * @brief Testcase for libmicrohttpd starts and stops
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26 26
@@ -35,12 +35,9 @@ static int testStartError() {
35 struct MHD_Daemon * d; 35 struct MHD_Daemon * d;
36 36
37 d = MHD_start_daemon(MHD_USE_DEBUG, 0, NULL, NULL, NULL, NULL); 37 d = MHD_start_daemon(MHD_USE_DEBUG, 0, NULL, NULL, NULL, NULL);
38 38 if (d != NULL)
39 if(d == NULL) { 39 return 1;
40 return 0; 40 return 0;
41 } else {
42 return 1;
43 }
44} 41}
45 42
46static int apc_nothing(void * cls, 43static int apc_nothing(void * cls,
@@ -64,50 +61,6 @@ static int ahc_nothing(void * cls,
64 return MHD_NO; 61 return MHD_NO;
65} 62}
66 63
67struct CBC {
68 char * buf;
69 size_t pos;
70 size_t size;
71};
72
73static size_t copyBuffer(void * ptr,
74 size_t size,
75 size_t nmemb,
76 void * ctx) {
77 struct CBC * cbc = ctx;
78
79 if (cbc->pos + size * nmemb > cbc->size)
80 return 0; /* overflow */
81 memcpy(&cbc->buf[cbc->pos],
82 ptr,
83 size * nmemb);
84 cbc->pos += size * nmemb;
85 return size * nmemb;
86}
87
88static int ahc_echo(void * cls,
89 struct MHD_Session * session,
90 const char * url,
91 const char * method,
92 const char * upload_data,
93 unsigned int * upload_data_size) {
94 const char * me = cls;
95 struct MHD_Response * response;
96 int ret;
97
98 if (0 != strcmp(me, method))
99 return MHD_NO; /* unexpected method */
100 response = MHD_create_response_from_data(strlen(url),
101 (void*) url,
102 MHD_NO,
103 MHD_YES);
104 ret = MHD_queue_response(session,
105 MHD_HTTP_OK,
106 response);
107 MHD_destroy_response(response);
108 return ret;
109}
110
111static int testStartStop() { 64static int testStartStop() {
112 struct MHD_Daemon * d; 65 struct MHD_Daemon * d;
113 66
@@ -117,39 +70,35 @@ static int testStartStop() {
117 NULL, 70 NULL,
118 &ahc_nothing, 71 &ahc_nothing,
119 NULL); 72 NULL);
120 if (d == NULL) { 73 if (d == NULL)
121 return 1; 74 return 2;
122 }
123 MHD_stop_daemon(d); 75 MHD_stop_daemon(d);
124 return 0; 76 return 0;
125} 77}
126 78
127static int testRun() { 79static int testExternalRun() {
128 struct MHD_Daemon * d; 80 struct MHD_Daemon * d;
129 fd_set read; 81 fd_set read;
130 int maxfd; 82 int maxfd;
131 int i; 83 int i;
132 84
133 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG, 85 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG,
134 1080, 86 1081,
135 &apc_all, 87 &apc_all,
136 NULL, 88 NULL,
137 &ahc_nothing, 89 &ahc_nothing,
138 NULL); 90 NULL);
139 91
140 if(d == NULL) { 92 if (d == NULL)
141 return 1; 93 return 4;
142 }
143 fprintf(stderr, "Testing external select!\n");
144 i = 0; 94 i = 0;
145 while(i < 15) { 95 while(i < 15) {
146 MHD_get_fdset(d, &read, &read, &read, &maxfd); 96 MHD_get_fdset(d, &read, &read, &read, &maxfd);
147 if(MHD_run(d) == MHD_NO) { 97 if (MHD_run(d) == MHD_NO) {
148 MHD_stop_daemon(d); 98 MHD_stop_daemon(d);
149 return 1; 99 return 8;
150 } 100 }
151 sleep(1); 101 i++;
152 i++;
153 } 102 }
154 return 0; 103 return 0;
155} 104}
@@ -157,205 +106,48 @@ static int testRun() {
157static int testThread() { 106static int testThread() {
158 struct MHD_Daemon * d; 107 struct MHD_Daemon * d;
159 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY, 108 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY,
160 1081, 109 1082,
161 &apc_all, 110 &apc_all,
162 NULL, 111 NULL,
163 &ahc_nothing, 112 &ahc_nothing,
164 NULL); 113 NULL);
165 114
166 if(d == NULL) { 115 if (d == NULL)
167 return 1; 116 return 16;
168 } 117 if (MHD_run(d) == MHD_NO)
169 118 return 32;
170 fprintf(stderr, "Testing internal select!\n"); 119 MHD_stop_daemon(d);
171 if (MHD_run(d) == MHD_NO) {
172 return 1;
173 } else {
174 sleep(15);
175 MHD_stop_daemon(d);
176 }
177 return 0; 120 return 0;
178} 121}
179 122
180static int testMultithread() { 123static int testMultithread() {
181 struct MHD_Daemon * d; 124 struct MHD_Daemon * d;
182 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION, 125 d = MHD_start_daemon(MHD_USE_IPv4 | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
183 1082, 126 1083,
184 &apc_all, 127 &apc_all,
185 NULL, 128 NULL,
186 &ahc_nothing, 129 &ahc_nothing,
187 NULL); 130 NULL);
188 131
189 if(d == NULL) { 132 if (d == NULL)
190 return 1; 133 return 64;
191 } 134 if (MHD_run(d) == MHD_NO)
192 135 return 128;
193 fprintf(stderr, "Testing thread per connection!\n"); 136 MHD_stop_daemon(d);
194 if (MHD_run(d) == MHD_NO) {
195 return 1;
196 } else {
197 sleep(15);
198 MHD_stop_daemon(d);
199 }
200 return 0;
201}
202
203static int testInternalGet() {
204 struct MHD_Daemon * d;
205 CURL * c;
206 char buf[2048];
207 struct CBC cbc;
208
209 cbc.buf = buf;
210 cbc.size = 2048;
211 cbc.pos = 0;
212 d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY | MHD_USE_IPv4 | MHD_USE_DEBUG,
213 1083,
214 &apc_all,
215 NULL,
216 &ahc_echo,
217 "GET");
218 if (d == NULL)
219 return 1;
220
221 if(MHD_run(d) == MHD_NO) {
222 MHD_stop_daemon(d);
223 return 2;
224 }
225
226 c = curl_easy_init();
227 curl_easy_setopt(c,
228 CURLOPT_URL,
229 "http://localhost:1083/hello_world");
230 curl_easy_setopt(c,
231 CURLOPT_WRITEFUNCTION,
232 &copyBuffer);
233 curl_easy_setopt(c,
234 CURLOPT_WRITEDATA,
235 &cbc);
236 curl_easy_setopt(c,
237 CURLOPT_FAILONERROR,
238 1);
239 curl_easy_setopt(c,
240 CURLOPT_CONNECTTIMEOUT,
241 15L);
242 // NOTE: use of CONNECTTIMEOUT without also
243 // setting NOSIGNAL results in really weird
244 // crashes on my system!
245 curl_easy_setopt(c,
246 CURLOPT_NOSIGNAL,
247 1);
248 if (CURLE_OK != curl_easy_perform(c))
249 return 3;
250
251 curl_easy_cleanup(c);
252
253 if (cbc.pos != strlen("hello_world"))
254 return 4;
255
256 if (0 != strncmp("hello_world",
257 cbc.buf,
258 strlen("hello_world")))
259 return 5;
260
261 MHD_stop_daemon(d);
262
263 return 0;
264}
265
266static int testMultithreadedGet() {
267 struct MHD_Daemon * d;
268 CURL * c;
269 char buf[2048];
270 struct CBC cbc;
271
272 cbc.buf = buf;
273 cbc.size = 2048;
274 cbc.pos = 0;
275 d = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION | MHD_USE_IPv4 | MHD_USE_DEBUG,
276 1084,
277 &apc_all,
278 NULL,
279 &ahc_echo,
280 "GET");
281 if (d == NULL)
282 return 1;
283
284 if(MHD_run(d) == MHD_NO)
285 return 2;
286
287
288 c = curl_easy_init();
289 curl_easy_setopt(c,
290 CURLOPT_URL,
291 "http://localhost:1084/hello_world");
292 curl_easy_setopt(c,
293 CURLOPT_WRITEFUNCTION,
294 &copyBuffer);
295 curl_easy_setopt(c,
296 CURLOPT_WRITEDATA,
297 &cbc);
298 curl_easy_setopt(c,
299 CURLOPT_FAILONERROR,
300 1);
301 curl_easy_setopt(c,
302 CURLOPT_CONNECTTIMEOUT,
303 15L);
304 // NOTE: use of CONNECTTIMEOUT without also
305 // setting NOSIGNAL results in really weird
306 // crashes on my system!
307 curl_easy_setopt(c,
308 CURLOPT_NOSIGNAL,
309 1);
310 if (CURLE_OK != curl_easy_perform(c))
311 return 3;
312 curl_easy_cleanup(c);
313 if (cbc.pos != strlen("hello_world"))
314 return 4;
315
316 if (0 != strncmp("hello_world",
317 cbc.buf,
318 strlen("hello_world")))
319 return 5;
320
321 MHD_stop_daemon(d);
322
323 return 0; 137 return 0;
324} 138}
325 139
326int main(int argc, 140int main(int argc,
327 char * const * argv) { 141 char * const * argv) {
328 unsigned int errorCount = 0; 142 unsigned int errorCount = 0;
329 fprintf(stderr, "***testStartError()***\n");
330 fprintf(stderr, "***This test verifies the start function responds to bad arguments correctly***\n");
331 errorCount += testStartError(); 143 errorCount += testStartError();
332 fprintf(stderr, "errorCount is %i\n", errorCount);
333 fprintf(stderr, "***testStartStop()***\n");
334 fprintf(stderr, "***This test verifies that the daemon can be started and stopped normally***\n");
335 errorCount += testStartStop(); 144 errorCount += testStartStop();
336 fprintf(stderr, "errorCount is %i\n", errorCount); 145 errorCount += testExternalRun();
337 fprintf(stderr, "***testInternalGet()***\n"); 146 errorCount += testThread();
338 fprintf(stderr, "***This test verifies the functionality of internal select using a canned request***\n"); 147 errorCount += testMultithread();
339 errorCount += testInternalGet(); 148 if (errorCount != 0)
340 fprintf(stderr, "errorCount is %i\n", errorCount); 149 fprintf(stderr,
341 fprintf(stderr, "***testMultithreadedGet()***\n"); 150 "Error (code: %u)\n",
342 fprintf(stderr, "***This test verifies the functionality of multithreaded connections using a canned request***\n"); 151 errorCount);
343 errorCount += testMultithreadedGet();
344 fprintf(stderr, "errorCount is %i\n", errorCount);
345 fprintf(stderr, "***testRun()***\n");
346 fprintf(stderr, "***This test verifies the functionality of external select***\n");
347 fprintf(stderr, "***The sever will sit on the announced port for 15 seconds and wait for external messages***\n");
348 errorCount += testRun();
349 fprintf(stderr, "errorCount is %i\n", errorCount);
350 fprintf(stderr, "***testThread()***\n");
351 fprintf(stderr, "***This test verifies the functionality of internal select***\n");
352 fprintf(stderr, "***The sever will sit on the announced port for 15 seconds and wait for external messages***\n");
353 errorCount += testThread();
354 fprintf(stderr, "errorCount is %i\n", errorCount);
355 fprintf(stderr, "***testMultithread()***\n");
356 fprintf(stderr, "***This test verifies the functionality of multithreaded connections***\n");
357 fprintf(stderr, "***The sever will sit on the announced port for 15 seconds and wait for external messages***\n");
358 errorCount += testMultithread();
359 fprintf(stderr, "errorCount is %i\n", errorCount);
360 return errorCount != 0; /* 0 == pass */ 152 return errorCount != 0; /* 0 == pass */
361} 153}