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