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