• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef HEADER_CURL_TEST_H
2 #define HEADER_CURL_TEST_H
3 /***************************************************************************
4  *                                  _   _ ____  _
5  *  Project                     ___| | | |  _ \| |
6  *                             / __| | | | |_) | |
7  *                            | (__| |_| |  _ <| |___
8  *                             \___|\___/|_| \_\_____|
9  *
10  * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
11  *
12  * This software is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution. The terms
14  * are also available at https://curl.se/docs/copyright.html.
15  *
16  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17  * copies of the Software, and permit persons to whom the Software is
18  * furnished to do so, under the terms of the COPYING file.
19  *
20  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21  * KIND, either express or implied.
22  *
23  * SPDX-License-Identifier: curl
24  *
25  ***************************************************************************/
26 
27 /* Now include the curl_setup.h file from libcurl's private libdir (the source
28    version, but that might include "curl_config.h" from the build dir so we
29    need both of them in the include path), so that we get good in-depth
30    knowledge about the system we're building this on */
31 
32 #define CURL_NO_OLDIES
33 
34 #include "curl_setup.h"
35 
36 #include <curl/curl.h>
37 
38 #ifdef HAVE_SYS_SELECT_H
39 /* since so many tests use select(), we can just as well include it here */
40 #include <sys/select.h>
41 #elif defined(HAVE_UNISTD_H)
42 #include <unistd.h>
43 #endif
44 
45 #include "curl_printf.h"
46 
47 /* GCC <4.6 does not support '#pragma GCC diagnostic push' and
48    does not support 'pragma GCC diagnostic' inside functions. */
49 #if (defined(__GNUC__) && \
50   ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))))
51 #define CURL_GNUC_DIAG
52 #endif
53 
54 #ifdef _WIN32
55 #define sleep(sec) Sleep((sec)*1000)
56 #endif
57 
58 #define test_setopt(A,B,C)                                      \
59   if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK)       \
60     goto test_cleanup
61 
62 #define test_multi_setopt(A,B,C)                                \
63   if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK)      \
64     goto test_cleanup
65 
66 extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */
67 extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
68 
69 /* argc and argv as passed in to the main() function */
70 extern int test_argc;
71 extern char **test_argv;
72 
73 extern struct timeval tv_test_start; /* for test timing */
74 
75 extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
76                           struct timeval *tv);
77 
78 extern void wait_ms(int ms); /* wait this many milliseconds */
79 
80 #ifndef CURLTESTS_BUNDLED_TEST_H
81 extern CURLcode test(char *URL); /* the actual test function provided by each
82                                     individual libXXX.c file */
83 #endif
84 
85 extern char *hexdump(const unsigned char *buffer, size_t len);
86 
87 extern int unitfail;
88 
89 /*
90 ** TEST_ERR_* values must be greater than CURL_LAST CURLcode in order
91 ** to avoid confusion with any CURLcode or CURLMcode. These TEST_ERR_*
92 ** codes are returned to signal test specific situations and should
93 ** not get mixed with CURLcode or CURLMcode values.
94 **
95 ** For portability reasons TEST_ERR_* values should be less than 127.
96 */
97 
98 #define TEST_ERR_MAJOR_BAD     (CURLcode) 126
99 #define TEST_ERR_RUNS_FOREVER  (CURLcode) 125
100 #define TEST_ERR_EASY_INIT     (CURLcode) 124
101 #define TEST_ERR_MULTI         (CURLcode) 123
102 #define TEST_ERR_NUM_HANDLES   (CURLcode) 122
103 #define TEST_ERR_SELECT        (CURLcode) 121
104 #define TEST_ERR_SUCCESS       (CURLcode) 120
105 #define TEST_ERR_FAILURE       (CURLcode) 119
106 #define TEST_ERR_USAGE         (CURLcode) 118
107 #define TEST_ERR_FOPEN         (CURLcode) 117
108 #define TEST_ERR_FSTAT         (CURLcode) 116
109 #define TEST_ERR_BAD_TIMEOUT   (CURLcode) 115
110 
111 /*
112 ** Macros for test source code readability/maintainability.
113 **
114 ** All of the following macros require that an int data type 'res' variable
115 ** exists in scope where macro is used, and that it has been initialized to
116 ** zero before the macro is used.
117 **
118 ** exe_* and chk_* macros are helper macros not intended to be used from
119 ** outside of this header file. Arguments 'Y' and 'Z' of these represent
120 ** source code file and line number, while Arguments 'A', 'B', etc, are
121 ** the arguments used to actually call a libcurl function.
122 **
123 ** All easy_* and multi_* macros call a libcurl function and evaluate if
124 ** the function has succeeded or failed. When the function succeeds 'res'
125 ** variable is not set nor cleared and program continues normal flow. On
126 ** the other hand if function fails 'res' variable is set and a jump to
127 ** label 'test_cleanup' is performed.
128 **
129 ** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro
130 ** counterpart that operates in the same way with the exception that no
131 ** jump takes place in case of failure. res_easy_* and res_multi_* macros
132 ** should be immediately followed by checking if 'res' variable has been
133 ** set.
134 **
135 ** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the
136 ** TEST_ERR_* values defined above. It is advisable to return this value
137 ** as test result.
138 */
139 
140 /* ---------------------------------------------------------------- */
141 
142 #define exe_easy_init(A,Y,Z) do {                                 \
143   if(((A) = curl_easy_init()) == NULL) {                          \
144     fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \
145     res = TEST_ERR_EASY_INIT;                                     \
146   }                                                               \
147 } while(0)
148 
149 #define res_easy_init(A) \
150   exe_easy_init((A), (__FILE__), (__LINE__))
151 
152 #define chk_easy_init(A,Y,Z) do { \
153   exe_easy_init((A), (Y), (Z));   \
154   if(res)                         \
155     goto test_cleanup;            \
156 } while(0)
157 
158 #define easy_init(A) \
159   chk_easy_init((A), (__FILE__), (__LINE__))
160 
161 /* ---------------------------------------------------------------- */
162 
163 #define exe_multi_init(A,Y,Z) do {                                 \
164   if(((A) = curl_multi_init()) == NULL) {                          \
165     fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
166     res = TEST_ERR_MULTI;                                          \
167   }                                                                \
168 } while(0)
169 
170 #define res_multi_init(A) \
171   exe_multi_init((A), (__FILE__), (__LINE__))
172 
173 #define chk_multi_init(A,Y,Z) do { \
174   exe_multi_init((A), (Y), (Z));   \
175   if(res)                          \
176     goto test_cleanup;             \
177 } while(0)
178 
179 #define multi_init(A) \
180   chk_multi_init((A), (__FILE__), (__LINE__))
181 
182 /* ---------------------------------------------------------------- */
183 
184 #define exe_easy_setopt(A,B,C,Y,Z) do {                    \
185   CURLcode ec;                                             \
186   if((ec = curl_easy_setopt((A), (B), (C))) != CURLE_OK) { \
187     fprintf(stderr, "%s:%d curl_easy_setopt() failed, "    \
188             "with code %d (%s)\n",                         \
189             (Y), (Z), (int)ec, curl_easy_strerror(ec));    \
190     res = ec;                                              \
191   }                                                        \
192 } while(0)
193 
194 #define res_easy_setopt(A, B, C) \
195   exe_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
196 
197 #define chk_easy_setopt(A, B, C, Y, Z) do { \
198   exe_easy_setopt((A), (B), (C), (Y), (Z)); \
199   if(res)                                   \
200     goto test_cleanup;                      \
201 } while(0)
202 
203 #define easy_setopt(A, B, C) \
204   chk_easy_setopt((A), (B), (C), (__FILE__), (__LINE__))
205 
206 /* ---------------------------------------------------------------- */
207 
208 #define exe_multi_setopt(A, B, C, Y, Z) do {                \
209   CURLMcode ec;                                             \
210   if((ec = curl_multi_setopt((A), (B), (C))) != CURLM_OK) { \
211     fprintf(stderr, "%s:%d curl_multi_setopt() failed, "    \
212             "with code %d (%s)\n",                          \
213             (Y), (Z), (int)ec, curl_multi_strerror(ec));    \
214     res = TEST_ERR_MULTI;                                   \
215   }                                                         \
216 } while(0)
217 
218 #define res_multi_setopt(A,B,C) \
219   exe_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
220 
221 #define chk_multi_setopt(A,B,C,Y,Z) do {     \
222   exe_multi_setopt((A), (B), (C), (Y), (Z)); \
223   if(res)                                    \
224     goto test_cleanup;                       \
225 } while(0)
226 
227 #define multi_setopt(A,B,C) \
228   chk_multi_setopt((A), (B), (C), (__FILE__), (__LINE__))
229 
230 /* ---------------------------------------------------------------- */
231 
232 #define exe_multi_add_handle(A,B,Y,Z) do {                   \
233   CURLMcode ec;                                              \
234   if((ec = curl_multi_add_handle((A), (B))) != CURLM_OK) {   \
235     fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \
236             "with code %d (%s)\n",                           \
237             (Y), (Z), (int)ec, curl_multi_strerror(ec));     \
238     res = TEST_ERR_MULTI;                                    \
239   }                                                          \
240 } while(0)
241 
242 #define res_multi_add_handle(A, B) \
243   exe_multi_add_handle((A), (B), (__FILE__), (__LINE__))
244 
245 #define chk_multi_add_handle(A, B, Y, Z) do { \
246   exe_multi_add_handle((A), (B), (Y), (Z));   \
247   if(res)                                     \
248     goto test_cleanup;                        \
249 } while(0)
250 
251 #define multi_add_handle(A, B) \
252   chk_multi_add_handle((A), (B), (__FILE__), (__LINE__))
253 
254 /* ---------------------------------------------------------------- */
255 
256 #define exe_multi_remove_handle(A,B,Y,Z) do {                   \
257   CURLMcode ec;                                                 \
258   if((ec = curl_multi_remove_handle((A), (B))) != CURLM_OK) {   \
259     fprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \
260             "with code %d (%s)\n",                              \
261             (Y), (Z), (int)ec, curl_multi_strerror(ec));        \
262     res = TEST_ERR_MULTI;                                       \
263   }                                                             \
264 } while(0)
265 
266 #define res_multi_remove_handle(A, B) \
267   exe_multi_remove_handle((A), (B), (__FILE__), (__LINE__))
268 
269 #define chk_multi_remove_handle(A, B, Y, Z) do { \
270   exe_multi_remove_handle((A), (B), (Y), (Z));   \
271   if(res)                                        \
272     goto test_cleanup;                           \
273 } while(0)
274 
275 
276 #define multi_remove_handle(A, B) \
277   chk_multi_remove_handle((A), (B), (__FILE__), (__LINE__))
278 
279 /* ---------------------------------------------------------------- */
280 
281 #define exe_multi_perform(A,B,Y,Z) do {                          \
282   CURLMcode ec;                                                  \
283   if((ec = curl_multi_perform((A), (B))) != CURLM_OK) {          \
284     fprintf(stderr, "%s:%d curl_multi_perform() failed, "        \
285             "with code %d (%s)\n",                               \
286             (Y), (Z), (int)ec, curl_multi_strerror(ec));         \
287     res = TEST_ERR_MULTI;                                        \
288   }                                                              \
289   else if(*((B)) < 0) {                                          \
290     fprintf(stderr, "%s:%d curl_multi_perform() succeeded, "     \
291             "but returned invalid running_handles value (%d)\n", \
292             (Y), (Z), (int)*((B)));                              \
293     res = TEST_ERR_NUM_HANDLES;                                  \
294   }                                                              \
295 } while(0)
296 
297 #define res_multi_perform(A, B) \
298   exe_multi_perform((A), (B), (__FILE__), (__LINE__))
299 
300 #define chk_multi_perform(A, B, Y, Z) do { \
301   exe_multi_perform((A), (B), (Y), (Z));   \
302   if(res)                                  \
303     goto test_cleanup;                     \
304 } while(0)
305 
306 #define multi_perform(A,B) \
307   chk_multi_perform((A), (B), (__FILE__), (__LINE__))
308 
309 /* ---------------------------------------------------------------- */
310 
311 #define exe_multi_fdset(A, B, C, D, E, Y, Z) do {                    \
312   CURLMcode ec;                                                      \
313   if((ec = curl_multi_fdset((A), (B), (C), (D), (E))) != CURLM_OK) { \
314     fprintf(stderr, "%s:%d curl_multi_fdset() failed, "              \
315             "with code %d (%s)\n",                                   \
316             (Y), (Z), (int)ec, curl_multi_strerror(ec));             \
317     res = TEST_ERR_MULTI;                                            \
318   }                                                                  \
319   else if(*((E)) < -1) {                                             \
320     fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, "           \
321             "but returned invalid max_fd value (%d)\n",              \
322             (Y), (Z), (int)*((E)));                                  \
323     res = TEST_ERR_NUM_HANDLES;                                      \
324   }                                                                  \
325 } while(0)
326 
327 #define res_multi_fdset(A, B, C, D, E) \
328   exe_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
329 
330 #define chk_multi_fdset(A, B, C, D, E, Y, Z) do {       \
331     exe_multi_fdset((A), (B), (C), (D), (E), (Y), (Z)); \
332     if(res)                                             \
333       goto test_cleanup;                                \
334   } while(0)
335 
336 #define multi_fdset(A, B, C, D, E) \
337   chk_multi_fdset((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
338 
339 /* ---------------------------------------------------------------- */
340 
341 #define exe_multi_timeout(A,B,Y,Z) do {                      \
342   CURLMcode ec;                                              \
343   if((ec = curl_multi_timeout((A), (B))) != CURLM_OK) {      \
344     fprintf(stderr, "%s:%d curl_multi_timeout() failed, "    \
345             "with code %d (%s)\n",                           \
346             (Y), (Z), (int)ec, curl_multi_strerror(ec));     \
347     res = TEST_ERR_BAD_TIMEOUT;                              \
348   }                                                          \
349   else if(*((B)) < -1L) {                                    \
350     fprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \
351             "but returned invalid timeout value (%ld)\n",    \
352             (Y), (Z), (long)*((B)));                         \
353     res = TEST_ERR_BAD_TIMEOUT;                              \
354   }                                                          \
355 } while(0)
356 
357 #define res_multi_timeout(A, B) \
358   exe_multi_timeout((A), (B), (__FILE__), (__LINE__))
359 
360 #define chk_multi_timeout(A, B, Y, Z) do { \
361     exe_multi_timeout((A), (B), (Y), (Z)); \
362     if(res)                                \
363       goto test_cleanup;                   \
364   } while(0)
365 
366 #define multi_timeout(A, B) \
367   chk_multi_timeout((A), (B), (__FILE__), (__LINE__))
368 
369 /* ---------------------------------------------------------------- */
370 
371 #define exe_multi_poll(A,B,C,D,E,Y,Z) do {                          \
372   CURLMcode ec;                                                     \
373   if((ec = curl_multi_poll((A), (B), (C), (D), (E))) != CURLM_OK) { \
374     fprintf(stderr, "%s:%d curl_multi_poll() failed, "              \
375             "with code %d (%s)\n",                                  \
376             (Y), (Z), (int)ec, curl_multi_strerror(ec));            \
377     res = TEST_ERR_MULTI;                                           \
378   }                                                                 \
379   else if(*((E)) < 0) {                                             \
380     fprintf(stderr, "%s:%d curl_multi_poll() succeeded, "           \
381             "but returned invalid numfds value (%d)\n",             \
382             (Y), (Z), (int)*((E)));                                 \
383     res = TEST_ERR_NUM_HANDLES;                                     \
384   }                                                                 \
385 } while(0)
386 
387 #define res_multi_poll(A, B, C, D, E) \
388   exe_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
389 
390 #define chk_multi_poll(A, B, C, D, E, Y, Z) do {     \
391   exe_multi_poll((A), (B), (C), (D), (E), (Y), (Z)); \
392   if(res)                                            \
393     goto test_cleanup;                               \
394 } while(0)
395 
396 #define multi_poll(A, B, C, D, E) \
397   chk_multi_poll((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
398 
399 /* ---------------------------------------------------------------- */
400 
401 #define exe_multi_wakeup(A,Y,Z) do {                     \
402   CURLMcode ec;                                          \
403   if((ec = curl_multi_wakeup((A))) != CURLM_OK) {        \
404     fprintf(stderr, "%s:%d curl_multi_wakeup() failed, " \
405             "with code %d (%s)\n",                       \
406             (Y), (Z), (int)ec, curl_multi_strerror(ec)); \
407     res = TEST_ERR_MULTI;                                \
408   }                                                      \
409 } while(0)
410 
411 #define res_multi_wakeup(A) \
412   exe_multi_wakeup((A), (__FILE__), (__LINE__))
413 
414 #define chk_multi_wakeup(A, Y, Z) do { \
415   exe_multi_wakeup((A), (Y), (Z));     \
416   if(res)                              \
417     goto test_cleanup;                 \
418 } while(0)
419 
420 #define multi_wakeup(A) \
421   chk_multi_wakeup((A), (__FILE__), (__LINE__))
422 
423 /* ---------------------------------------------------------------- */
424 
425 #define exe_select_test(A, B, C, D, E, Y, Z) do {               \
426     int ec;                                                     \
427     if(select_wrapper((A), (B), (C), (D), (E)) == -1) {         \
428       ec = SOCKERRNO;                                           \
429       fprintf(stderr, "%s:%d select() failed, with "            \
430               "errno %d (%s)\n",                                \
431               (Y), (Z), ec, strerror(ec));                      \
432       res = TEST_ERR_SELECT;                                    \
433     }                                                           \
434   } while(0)
435 
436 #define res_select_test(A, B, C, D, E) \
437   exe_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
438 
439 #define chk_select_test(A, B, C, D, E, Y, Z) do {       \
440     exe_select_test((A), (B), (C), (D), (E), (Y), (Z)); \
441     if(res)                                             \
442       goto test_cleanup;                                \
443   } while(0)
444 
445 #define select_test(A, B, C, D, E) \
446   chk_select_test((A), (B), (C), (D), (E), (__FILE__), (__LINE__))
447 
448 /* ---------------------------------------------------------------- */
449 
450 #define start_test_timing() do { \
451   tv_test_start = tutil_tvnow(); \
452 } while(0)
453 
454 #define exe_test_timedout(Y,Z) do {                                       \
455   long timediff = tutil_tvdiff(tutil_tvnow(), tv_test_start);             \
456   if(timediff > (TEST_HANG_TIMEOUT)) {                                    \
457     fprintf(stderr, "%s:%d ABORTING TEST, since it seems "                \
458             "that it would have run forever (%ld ms > %ld ms)\n",         \
459             (Y), (Z), timediff, (long) (TEST_HANG_TIMEOUT));              \
460     res = TEST_ERR_RUNS_FOREVER;                                          \
461   }                                                                       \
462 } while(0)
463 
464 #define res_test_timedout() \
465   exe_test_timedout((__FILE__), (__LINE__))
466 
467 #define chk_test_timedout(Y, Z) do { \
468     exe_test_timedout(Y, Z);         \
469     if(res)                          \
470       goto test_cleanup;             \
471   } while(0)
472 
473 #define abort_on_test_timeout() \
474   chk_test_timedout((__FILE__), (__LINE__))
475 
476 /* ---------------------------------------------------------------- */
477 
478 #define exe_global_init(A,Y,Z) do {                     \
479   CURLcode ec;                                          \
480   if((ec = curl_global_init((A))) != CURLE_OK) {        \
481     fprintf(stderr, "%s:%d curl_global_init() failed, " \
482             "with code %d (%s)\n",                      \
483             (Y), (Z), (int)ec, curl_easy_strerror(ec)); \
484     res = ec;                                           \
485   }                                                     \
486 } while(0)
487 
488 #define res_global_init(A) \
489   exe_global_init((A), (__FILE__), (__LINE__))
490 
491 #define chk_global_init(A, Y, Z) do { \
492     exe_global_init((A), (Y), (Z));   \
493     if(res)                           \
494       return res;                     \
495   } while(0)
496 
497 /* global_init() is different than other macros. In case of
498    failure it 'return's instead of going to 'test_cleanup'. */
499 
500 #define global_init(A) \
501   chk_global_init((A), (__FILE__), (__LINE__))
502 
503 #ifndef CURLTESTS_BUNDLED_TEST_H
504 #define NO_SUPPORT_BUILT_IN                     \
505   CURLcode test(char *URL)                      \
506   {                                             \
507     (void)URL;                                  \
508     fprintf(stderr, "Missing support\n");       \
509     return (CURLcode)1;                         \
510   }
511 #endif
512 
513 /* ---------------------------------------------------------------- */
514 
515 #endif /* HEADER_CURL_TEST_H */
516 
517 #ifdef CURLTESTS_BUNDLED_TEST_H
518 extern CURLcode test(char *URL); /* the actual test function provided by each
519                                     individual libXXX.c file */
520 
521 #undef NO_SUPPORT_BUILT_IN
522 #define NO_SUPPORT_BUILT_IN                     \
523   CURLcode test(char *URL)                      \
524   {                                             \
525     (void)URL;                                  \
526     fprintf(stderr, "Missing support\n");       \
527     return (CURLcode)1;                         \
528   }
529 #endif
530