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