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