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