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