first.h (21329B)
1 #ifndef HEADER_LIBTEST_FIRST_H 2 #define HEADER_LIBTEST_FIRST_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 /* Now include the curl_setup.h file from libcurl's private libdir (the source 27 version, but that might include "curl_config.h" from the build dir so we 28 need both of them in the include path), so that we get good in-depth 29 knowledge about the system we're building this on */ 30 #include "curl_setup.h" 31 32 #include <curl/curl.h> 33 34 typedef CURLcode (*entry_func_t)(char *); 35 36 struct entry_s { 37 const char *name; 38 entry_func_t ptr; 39 }; 40 41 extern const struct entry_s s_entries[]; 42 43 extern int unitfail; /* for unittests */ 44 45 #include <curlx/curlx.h> 46 47 #ifdef HAVE_SYS_SELECT_H 48 /* since so many tests use select(), we can just as well include it here */ 49 #include <sys/select.h> 50 #endif 51 52 #include "curl_printf.h" 53 54 /* GCC <4.6 does not support '#pragma GCC diagnostic push' and 55 does not support 'pragma GCC diagnostic' inside functions. */ 56 #if (defined(__GNUC__) && \ 57 ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)))) 58 #define CURL_GNUC_DIAG 59 #endif 60 61 #define test_setopt(A,B,C) \ 62 if((res = curl_easy_setopt((A), (B), (C))) != CURLE_OK) \ 63 goto test_cleanup 64 65 #define test_multi_setopt(A,B,C) \ 66 if((res = curl_multi_setopt((A), (B), (C))) != CURLE_OK) \ 67 goto test_cleanup 68 69 extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */ 70 extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */ 71 extern char *libtest_arg4; /* set by first.c to the argv[4] or NULL */ 72 73 /* argc and argv as passed in to the main() function */ 74 extern int test_argc; 75 extern char **test_argv; 76 extern int testnum; 77 extern struct curltime tv_test_start; /* for test timing */ 78 79 extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, 80 struct timeval *tv); 81 82 extern char *hexdump(const unsigned char *buffer, size_t len); 83 84 /* 85 ** TEST_ERR_* values must within the CURLcode range to not cause compiler 86 ** errors. 87 88 ** For portability reasons TEST_ERR_* values should be less than 127. 89 */ 90 91 #define TEST_ERR_MAJOR_BAD CURLE_OBSOLETE20 92 #define TEST_ERR_RUNS_FOREVER CURLE_OBSOLETE24 93 #define TEST_ERR_EASY_INIT CURLE_OBSOLETE29 94 #define TEST_ERR_MULTI CURLE_OBSOLETE32 95 #define TEST_ERR_NUM_HANDLES CURLE_OBSOLETE34 96 #define TEST_ERR_SELECT CURLE_OBSOLETE40 97 #define TEST_ERR_SUCCESS CURLE_OBSOLETE41 98 #define TEST_ERR_FAILURE CURLE_OBSOLETE44 99 #define TEST_ERR_USAGE CURLE_OBSOLETE46 100 #define TEST_ERR_FOPEN CURLE_OBSOLETE50 101 #define TEST_ERR_FSTAT CURLE_OBSOLETE51 102 #define TEST_ERR_BAD_TIMEOUT CURLE_OBSOLETE57 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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 curl_mfprintf(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 = curlx_now(); \ 445 } while(0) 446 447 #define TEST_HANG_TIMEOUT 60 * 1000 /* global default */ 448 449 #define exe_test_timedout(T,Y,Z) do { \ 450 timediff_t timediff = curlx_timediff(curlx_now(), tv_test_start); \ 451 if(timediff > (T)) { \ 452 curl_mfprintf(stderr, "%s:%d ABORTING TEST, since it seems " \ 453 "that it would have run forever (%ld ms > %ld ms)\n", \ 454 (Y), (Z), (long)timediff, (long)(TEST_HANG_TIMEOUT)); \ 455 res = TEST_ERR_RUNS_FOREVER; \ 456 } \ 457 } while(0) 458 459 #define res_test_timedout() \ 460 exe_test_timedout(TEST_HANG_TIMEOUT, (__FILE__), (__LINE__)) 461 462 #define res_test_timedout_custom(T) \ 463 exe_test_timedout((T), (__FILE__), (__LINE__)) 464 465 #define chk_test_timedout(T, Y, Z) do { \ 466 exe_test_timedout(T, Y, Z); \ 467 if(res) \ 468 goto test_cleanup; \ 469 } while(0) 470 471 #define abort_on_test_timeout() \ 472 chk_test_timedout(TEST_HANG_TIMEOUT, (__FILE__), (__LINE__)) 473 474 #define abort_on_test_timeout_custom(T) \ 475 chk_test_timedout((T), (__FILE__), (__LINE__)) 476 477 /* ---------------------------------------------------------------- */ 478 479 #define exe_global_init(A,Y,Z) do { \ 480 CURLcode ec; \ 481 if((ec = curl_global_init((A))) != CURLE_OK) { \ 482 curl_mfprintf(stderr, "%s:%d curl_global_init() failed, " \ 483 "with code %d (%s)\n", \ 484 (Y), (Z), (int)ec, curl_easy_strerror(ec)); \ 485 res = ec; \ 486 } \ 487 } while(0) 488 489 #define res_global_init(A) \ 490 exe_global_init((A), (__FILE__), (__LINE__)) 491 492 #define chk_global_init(A, Y, Z) do { \ 493 exe_global_init((A), (Y), (Z)); \ 494 if(res) \ 495 return res; \ 496 } while(0) 497 498 /* global_init() is different than other macros. In case of 499 failure it 'return's instead of going to 'test_cleanup'. */ 500 501 #define global_init(A) \ 502 chk_global_init((A), (__FILE__), (__LINE__)) 503 504 #define NO_SUPPORT_BUILT_IN \ 505 { \ 506 (void)URL; \ 507 curl_mfprintf(stderr, "Missing support\n"); \ 508 return CURLE_UNSUPPORTED_PROTOCOL; \ 509 } 510 511 #define NUM_HANDLES 4 /* global default */ 512 513 #endif /* HEADER_LIBTEST_FIRST_H */