1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

multi tests: OOM handling fixes

Additionally, improved error checking and logging.
This commit is contained in:
Yang Tse 2011-10-21 16:26:18 +02:00
parent 90fcad63cb
commit 629d2e3450
22 changed files with 1053 additions and 1354 deletions

View File

@ -35,9 +35,10 @@ http://%HOSTIP:%HTTPSPORT/504 %HOSTIP:55555
</client>
# Verify data after the test has been "shot"
# TEST_ERR_SUCCESS is errorcode 120
<verify>
<errorcode>
100
120
</errorcode>
</verify>
</testcase>

View File

@ -32,11 +32,10 @@ ftp://%HOSTIP:%FTPPORT/538
</client>
# Verify data after the test has been "shot"
# TEST_ERR_SUCCESS is errorcode 120
<verify>
# ok, the error code here is supposed to be 100 for the fine case since
# that's just how lib504.c is written
<errorcode>
100
120
</errorcode>
<protocol>
USER anonymous

View File

@ -93,7 +93,7 @@ lib537_SOURCES = lib537.c $(SUPPORTFILES) $(WARNLESS)
lib539_SOURCES = lib539.c $(SUPPORTFILES)
lib540_SOURCES = lib540.c $(SUPPORTFILES) $(WARNLESS)
lib540_SOURCES = lib540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib541_SOURCES = lib541.c $(SUPPORTFILES)
@ -125,11 +125,11 @@ lib556_SOURCES = lib556.c $(SUPPORTFILES)
lib557_SOURCES = lib557.c $(SUPPORTFILES)
lib560_SOURCES = lib560.c $(SUPPORTFILES) $(WARNLESS)
lib560_SOURCES = lib560.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib574_SOURCES = lib574.c $(SUPPORTFILES)
lib575_SOURCES = lib575.c $(SUPPORTFILES) $(WARNLESS)
lib575_SOURCES = lib575.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
lib576_SOURCES = lib576.c $(SUPPORTFILES)

View File

@ -30,19 +30,25 @@
# include "memdebug.h"
#endif
int select_test (int num_fds, fd_set *rd, fd_set *wr, fd_set *exc,
int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
struct timeval *tv)
{
if(nfds < 0) {
SET_SOCKERRNO(EINVAL);
return -1;
}
#ifdef USE_WINSOCK
/* Winsock doesn't like no socket set in 'rd', 'wr' or 'exc'. This is
* case when 'num_fds <= 0. So sleep.
/*
* Winsock select() requires that at least one of the three fd_set
* pointers is not NULL and points to a non-empty fdset. IOW Winsock
* select() can not be used to sleep without a single fd_set.
*/
if (num_fds <= 0) {
if(!nfds) {
Sleep(1000*tv->tv_sec + tv->tv_usec/1000);
return 0;
}
#endif
return select(num_fds, rd, wr, exc, tv);
return select(nfds, rd, wr, exc, tv);
}
char *libtest_arg2=NULL;
@ -50,6 +56,8 @@ char *libtest_arg3=NULL;
int test_argc;
char **test_argv;
struct timeval tv_test_start; /* for test timing */
#ifdef UNITTESTS
int unitfail; /* for unittests */
#endif

View File

@ -25,8 +25,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
/*
* Get a single URL without select().
@ -34,90 +33,57 @@
int test(char *URL)
{
CURL *c;
CURL *c = NULL;
CURLM *m = NULL;
int res = 0;
int running=1;
struct timeval mp_start;
char mp_timedout = FALSE;
int running;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((c = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(c, CURLOPT_URL, URL);
easy_init(c);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(c, CURLOPT_URL, URL);
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_add_handle(m, c);
while (running) {
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
for(;;) {
struct timeval timeout;
fd_set fdread, fdwrite, fdexcep;
int maxfd = -1;
int maxfd = -99;
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
fprintf(stderr, "nothing left running.\n");
break;
}
timeout.tv_sec = 0;
timeout.tv_usec = 100000L; /* 100 ms */
multi_perform(m, &running);
abort_on_test_timeout();
if(!running)
break; /* done */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
curl_multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls. On success, the value of maxfd is guaranteed to be
greater or equal than -1. We call select(maxfd + 1, ...), specially in
case of (maxfd == -1), we call select(0, ...), which is basically equal
to sleep. */
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
res = ~CURLM_OK;
break;
}
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
if (mp_timedout) {
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
}
test_cleanup:
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, c);
curl_multi_cleanup(m);
}
curl_easy_cleanup(c);
curl_global_cleanup();

View File

@ -25,8 +25,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
/*
* Source code in here hugely as reported in bug report 651460 by
@ -38,121 +37,62 @@
int test(char *URL)
{
CURL *c;
CURL *c = NULL;
CURLM *m = NULL;
int res = 0;
int running;
char done = FALSE;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((c = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
test_setopt(c, CURLOPT_URL, URL);
test_setopt(c, CURLOPT_USERPWD, "test:ing");
test_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
test_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
test_setopt(c, CURLOPT_HEADER, 1L);
easy_init(c);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
easy_setopt(c, CURLOPT_URL, URL);
easy_setopt(c, CURLOPT_USERPWD, "test:ing");
easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
easy_setopt(c, CURLOPT_HEADER, 1L);
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_add_handle(m, c);
while(!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
done = TRUE;
break;
}
abort_on_test_timeout();
if (mp_timedout || done)
break;
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
}
if(!running)
break; /* done */
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 89;
break;
}
multi_fdset(m, &rd, &wr, &exc, &maxfd);
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 95;
break;
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
}
select_test(maxfd+1, &rd, &wr, &exc, &interval);
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
abort_on_test_timeout();
}
test_cleanup:
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, c);
curl_multi_cleanup(m);
}
curl_easy_cleanup(c);
curl_global_cleanup();

View File

@ -25,8 +25,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
/*
* Source code in here hugely as reported in bug report 651464 by
@ -37,81 +36,41 @@
*/
int test(char *URL)
{
CURL *c;
CURL *c = NULL;
int res = 0;
CURLM *m = NULL;
fd_set rd, wr, exc;
CURLMcode ret;
char done = FALSE;
int running;
int max_fd;
int rc;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((c = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
easy_init(c);
/* The point here is that there must not be anything running on the given
proxy port */
if (libtest_arg2)
test_setopt(c, CURLOPT_PROXY, libtest_arg2);
test_setopt(c, CURLOPT_URL, URL);
test_setopt(c, CURLOPT_VERBOSE, 1L);
easy_setopt(c, CURLOPT_PROXY, libtest_arg2);
easy_setopt(c, CURLOPT_URL, URL);
easy_setopt(c, CURLOPT_VERBOSE, 1L);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
if ((ret = curl_multi_add_handle(m, c)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", ret);
curl_multi_cleanup(m);
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_add_handle(m, c);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
while (!done) {
for(;;) {
struct timeval interval;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
fprintf(stderr, "curl_multi_perform()\n");
ret = curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (mp_timedout)
break;
multi_perform(m, &running);
abort_on_test_timeout();
if(!running) {
/* This is where this code is expected to reach */
@ -119,47 +78,34 @@ int test(char *URL)
CURLMsg *msg = curl_multi_info_read(m, &numleft);
fprintf(stderr, "Expected: not running\n");
if(msg && !numleft)
res = 100; /* this is where we should be */
res = TEST_ERR_SUCCESS; /* this is where we should be */
else
res = 99; /* not correct */
break;
}
fprintf(stderr, "running == %d, ret == %d\n", running, ret);
if (ret != CURLM_OK) {
res = 2;
break;
res = TEST_ERR_FAILURE; /* not correct */
break; /* done */
}
fprintf(stderr, "running == %d\n", running);
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
fprintf(stderr, "curl_multi_fdset()\n");
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 3;
break;
}
rc = select_test(max_fd+1, &rd, &wr, &exc, &interval);
fprintf(stderr, "select returned %d\n", rc);
}
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
multi_fdset(m, &rd, &wr, &exc, &maxfd);
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
select_test(maxfd+1, &rd, &wr, &exc, &interval);
abort_on_test_timeout();
}
test_cleanup:
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, c);
curl_multi_cleanup(m);
}
curl_easy_cleanup(c);
curl_global_cleanup();

View File

@ -25,71 +25,40 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
int test(char *URL)
{
CURL* curls;
CURLM* multi;
CURL* curls = NULL;
CURLM* multi = NULL;
int still_running;
int i = -1;
int res = 0;
CURLMsg *msg;
CURLMcode ret;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((multi = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
if ((curls = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_multi_cleanup(multi);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(multi);
test_setopt(curls, CURLOPT_URL, URL);
test_setopt(curls, CURLOPT_HEADER, 1L);
easy_init(curls);
if ((ret = curl_multi_add_handle(multi, curls)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", ret);
curl_easy_cleanup(curls);
curl_multi_cleanup(multi);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(curls, CURLOPT_URL, URL);
easy_setopt(curls, CURLOPT_HEADER, 1L);
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_add_handle(multi, curls);
ret = curl_multi_perform(multi, &still_running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT)
mp_timedout = TRUE;
multi_perform(multi, &still_running);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
abort_on_test_timeout();
while ((!ml_timedout) && (!mp_timedout) && (still_running)) {
while(still_running) {
struct timeval timeout;
int rc;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
int maxfd = -99;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
@ -97,47 +66,29 @@ int test(char *URL)
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
multi_perform(multi, &still_running);
abort_on_test_timeout();
}
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) {
case -1:
break;
case 0:
default:
mp_timedout = FALSE;
mp_start = tutil_tvnow();
ret = curl_multi_perform(multi, &still_running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT)
mp_timedout = TRUE;
break;
}
}
if (ml_timedout || mp_timedout) {
if (ml_timedout)
fprintf(stderr, "ml_timedout\n");
if (mp_timedout)
fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
i = TEST_ERR_RUNS_FOREVER;
}
else {
msg = curl_multi_info_read(multi, &still_running);
if(msg)
/* this should now contain a result code from the easy handle,
get it */
i = msg->data.result;
}
test_cleanup:
/* undocumented cleanup sequence - type UA */
curl_multi_cleanup(multi);
curl_easy_cleanup(curls);
curl_global_cleanup();

View File

@ -27,37 +27,39 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
int test(char *URL)
{
int res = 0;
CURL *curl;
FILE *hd_src ;
CURL *curl = NULL;
FILE *hd_src = NULL;
int hd ;
int error;
struct_stat file_info;
int running;
char done=FALSE;
CURLM *m = NULL;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
int running;
start_test_timing();
if(!libtest_arg2) {
#ifdef LIB529
/* test 529 */
fprintf(stderr, "Usage: lib529 [url] [uploadfile]\n");
#else
/* test 525 */
fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n");
return -1;
#endif
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
if(NULL == hd_src) {
error = ERRNO;
fprintf(stderr, "fopen() failed with error: %d %s\n",
fprintf(stderr, "fopen() failed with error: %d (%s)\n",
error, strerror(error));
fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
return TEST_ERR_MAJOR_BAD;
fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
return TEST_ERR_FOPEN;
}
/* get the file size of the local file */
@ -65,40 +67,35 @@ int test(char *URL)
if(hd == -1) {
/* can't open file, bail out */
error = ERRNO;
fprintf(stderr, "fstat() failed with error: %d %s\n",
fprintf(stderr, "fstat() failed with error: %d (%s)\n",
error, strerror(error));
fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2);
fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2);
fclose(hd_src);
return -1;
return TEST_ERR_FSTAT;
}
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
res_global_init(CURL_GLOBAL_ALL);
if(res) {
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
return res;
}
if ((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
fclose(hd_src);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_init(curl);
/* enable uploading */
test_setopt(curl, CURLOPT_UPLOAD, 1L);
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
test_setopt(curl,CURLOPT_URL, URL);
easy_setopt(curl,CURLOPT_URL, URL);
/* go verbose */
test_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* use active FTP */
test_setopt(curl, CURLOPT_FTPPORT, "-");
easy_setopt(curl, CURLOPT_FTPPORT, "-");
/* now specify which file to upload */
test_setopt(curl, CURLOPT_READDATA, hd_src);
easy_setopt(curl, CURLOPT_READDATA, hd_src);
/* NOTE: if you want this code to work on Windows with libcurl as a DLL, you
MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to
@ -109,110 +106,60 @@ int test(char *URL)
option you MUST make sure that the type of the passed-in argument is a
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
make sure that to pass in a type 'long' argument. */
test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
multi_add_handle(m, curl);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
while (!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
done = TRUE;
break;
}
abort_on_test_timeout();
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
}
if(!running)
break; /* done */
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 189;
break;
}
multi_fdset(m, &rd, &wr, &exc, &maxfd);
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 195;
break;
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
res = CURLM_CALL_MULTI_PERFORM;
}
select_test(maxfd+1, &rd, &wr, &exc, &interval);
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
abort_on_test_timeout();
}
test_cleanup:
#ifdef LIB529
/* test 529 */
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, curl);
curl_multi_cleanup(m);
}
curl_easy_cleanup(curl);
curl_global_cleanup();
#else
/* test 525 */
if(m)
/* proper cleanup sequence - type PB */
curl_multi_remove_handle(m, curl);
curl_easy_cleanup(curl);
if(m)
curl_multi_cleanup(m);
curl_global_cleanup();
#endif
fclose(hd_src); /* close the local file */
/* close the local file */
fclose(hd_src);
curl_global_cleanup();
return res;
}

View File

@ -46,8 +46,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
#define NUM_HANDLES 4
@ -56,109 +55,51 @@ int test(char *URL)
int res = 0;
CURL *curl[NUM_HANDLES];
int running;
char done=FALSE;
CURLM *m = NULL;
int current = 0;
int i, j;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
int i;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
for(i=0; i < NUM_HANDLES; i++)
curl[i] = NULL;
start_test_timing();
global_init(CURL_GLOBAL_ALL);
/* get NUM_HANDLES easy handles */
for(i=0; i < NUM_HANDLES; i++) {
curl[i] = curl_easy_init();
if(!curl[i]) {
fprintf(stderr, "curl_easy_init() failed "
"on handle #%d\n", i);
for (j=i-1; j >= 0; j--) {
curl_easy_cleanup(curl[j]);
}
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
res = curl_easy_setopt(curl[i], CURLOPT_URL, URL);
if(res) {
fprintf(stderr, "curl_easy_setopt() failed "
"on handle #%d\n", i);
for (j=i; j >= 0; j--) {
curl_easy_cleanup(curl[j]);
}
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
easy_init(curl[i]);
/* specify target */
easy_setopt(curl[i], CURLOPT_URL, URL);
/* go verbose */
res = curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
if(res) {
fprintf(stderr, "curl_easy_setopt() failed "
"on handle #%d\n", i);
for (j=i; j >= 0; j--) {
curl_easy_cleanup(curl[j]);
}
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
}
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
for(i=0; i < NUM_HANDLES; i++) {
curl_easy_cleanup(curl[i]);
}
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
if ((res = (int)curl_multi_add_handle(m, curl[current])) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
for(i=0; i < NUM_HANDLES; i++) {
curl_easy_cleanup(curl[i]);
}
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_add_handle(m, curl[current]);
fprintf(stderr, "Start at URL 0\n");
while (!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
abort_on_test_timeout();
if(!running) {
#ifdef LIB527
/* NOTE: this code does not remove the handle from the multi handle
here, which would be the nice, sane and documented way of working.
This however tests that the API survives this abuse gracefully. */
curl_easy_cleanup(curl[current]);
curl[current] = NULL;
#endif
if(++current < NUM_HANDLES) {
fprintf(stderr, "Advancing to URL %d\n", current);
@ -169,74 +110,75 @@ int test(char *URL)
/* make us re-use the same handle all the time, and try resetting
the handle first too */
curl_easy_reset(curl[0]);
test_setopt(curl[0], CURLOPT_URL, URL);
test_setopt(curl[0], CURLOPT_VERBOSE, 1L);
easy_setopt(curl[0], CURLOPT_URL, URL);
/* go verbose */
easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
/* re-add it */
res = (int)curl_multi_add_handle(m, curl[0]);
multi_add_handle(m, curl[0]);
#else
res = (int)curl_multi_add_handle(m, curl[current]);
multi_add_handle(m, curl[current]);
#endif
if(res) {
fprintf(stderr, "add handle failed: %d.\n", res);
res = 243;
break;
}
}
else {
done = TRUE; /* bail out */
break;
break; /* done */
}
}
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
}
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 189;
break;
multi_fdset(m, &rd, &wr, &exc, &maxfd);
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
select_test(maxfd+1, &rd, &wr, &exc, &interval);
abort_on_test_timeout();
}
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 195;
break;
}
}
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
}
#ifdef LIB532
test_cleanup:
#endif
#ifndef LIB527
/* get NUM_HANDLES easy handles */
#if defined(LIB526)
/* test 526 and 528 */
/* proper cleanup sequence - type PB */
for(i=0; i < NUM_HANDLES; i++) {
#ifdef LIB526
if(m)
curl_multi_remove_handle(m, curl[i]);
#endif
curl_easy_cleanup(curl[i]);
}
#endif
if(m)
curl_multi_cleanup(m);
curl_global_cleanup();
#elif defined(LIB527)
/* test 527 */
/* Upon non-failure test flow the easy's have already been cleanup'ed. In
case there is a failure we arrive here with easy's that have not been
cleanup'ed yet, in this case we have to cleanup them or otherwise these
will be leaked, let's use undocumented cleanup sequence - type UB */
if(res)
for(i=0; i < NUM_HANDLES; i++)
curl_easy_cleanup(curl[i]);
curl_multi_cleanup(m);
curl_global_cleanup();
#elif defined(LIB532)
/* test 532 */
/* undocumented cleanup sequence - type UB */
for(i=0; i < NUM_HANDLES; i++)
curl_easy_cleanup(curl[i]);
curl_multi_cleanup(m);
curl_global_cleanup();
#endif
return res;
}

View File

@ -25,8 +25,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
#define NUM_HANDLES 4
@ -35,169 +34,71 @@ int test(char *URL)
int res = 0;
CURL *curl[NUM_HANDLES];
int running;
char done=FALSE;
CURLM *m;
int i, j;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
CURLM *m = NULL;
int i;
char target_url[256];
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
for(i=0; i < NUM_HANDLES; i++)
curl[i] = NULL;
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
global_init(CURL_GLOBAL_ALL);
multi_init(m);
/* get NUM_HANDLES easy handles */
for(i=0; i < NUM_HANDLES; i++) {
curl[i] = curl_easy_init();
if(!curl[i]) {
fprintf(stderr, "curl_easy_init() failed "
"on handle #%d\n", i);
for (j=i-1; j >= 0; j--) {
curl_multi_remove_handle(m, curl[j]);
curl_easy_cleanup(curl[j]);
}
curl_multi_cleanup(m);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
/* get an easy handle */
easy_init(curl[i]);
/* specify target */
sprintf(target_url, "%s%04i", URL, i + 1);
target_url[sizeof(target_url) - 1] = '\0';
res = curl_easy_setopt(curl[i], CURLOPT_URL, target_url);
if(res) {
fprintf(stderr, "curl_easy_setopt() failed "
"on handle #%d\n", i);
for (j=i; j >= 0; j--) {
curl_multi_remove_handle(m, curl[j]);
curl_easy_cleanup(curl[j]);
}
curl_multi_cleanup(m);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
easy_setopt(curl[i], CURLOPT_URL, target_url);
/* go verbose */
res = curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
if(res) {
fprintf(stderr, "curl_easy_setopt() failed "
"on handle #%d\n", i);
for (j=i; j >= 0; j--) {
curl_multi_remove_handle(m, curl[j]);
curl_easy_cleanup(curl[j]);
}
curl_multi_cleanup(m);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
/* include headers */
res = curl_easy_setopt(curl[i], CURLOPT_HEADER, 1L);
if(res) {
fprintf(stderr, "curl_easy_setopt() failed "
"on handle #%d\n", i);
for (j=i; j >= 0; j--) {
curl_multi_remove_handle(m, curl[j]);
curl_easy_cleanup(curl[j]);
}
curl_multi_cleanup(m);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
easy_setopt(curl[i], CURLOPT_HEADER, 1L);
/* add handle to multi */
if ((res = (int)curl_multi_add_handle(m, curl[i])) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"on handle #%d with code %d\n", i, res);
curl_easy_cleanup(curl[i]);
for (j=i-1; j >= 0; j--) {
curl_multi_remove_handle(m, curl[j]);
curl_easy_cleanup(curl[j]);
}
curl_multi_cleanup(m);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD + i;
}
multi_add_handle(m, curl[i]);
}
curl_multi_setopt(m, CURLMOPT_PIPELINING, 1L);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_setopt(m, CURLMOPT_PIPELINING, 1L);
fprintf(stderr, "Start at URL 0\n");
while (!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
done = TRUE; /* bail out */
break;
}
abort_on_test_timeout();
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
}
if(!running)
break; /* done */
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 189;
break;
multi_fdset(m, &rd, &wr, &exc, &maxfd);
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
select_test(maxfd+1, &rd, &wr, &exc, &interval);
abort_on_test_timeout();
}
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 195;
break;
}
test_cleanup:
res = CURLM_CALL_MULTI_PERFORM;
}
/* proper cleanup sequence - type PB */
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
}
/* test_cleanup: */
/* cleanup NUM_HANDLES easy handles */
for(i=0; i < NUM_HANDLES; i++) {
curl_multi_remove_handle(m, curl[i]);
curl_easy_cleanup(curl[i]);

View File

@ -29,81 +29,45 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
int test(char *URL)
{
int res = 0;
CURL *curl;
CURL *curl = NULL;
int running;
char done=FALSE;
CURLM *m = NULL;
int current=0;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_VERBOSE, 1);
test_setopt(curl, CURLOPT_FAILONERROR, 1);
easy_init(curl);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(curl, CURLOPT_URL, URL);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_add_handle(m, curl);
fprintf(stderr, "Start at URL 0\n");
while (!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
abort_on_test_timeout();
if(!running) {
if(!current++) {
fprintf(stderr, "Advancing to URL 1\n");
/* remove the handle we use */
@ -112,61 +76,35 @@ int test(char *URL)
/* make us re-use the same handle all the time, and try resetting
the handle first too */
curl_easy_reset(curl);
test_setopt(curl, CURLOPT_URL, libtest_arg2);
test_setopt(curl, CURLOPT_VERBOSE, 1);
test_setopt(curl, CURLOPT_FAILONERROR, 1);
easy_setopt(curl, CURLOPT_URL, libtest_arg2);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
/* re-add it */
res = (int)curl_multi_add_handle(m, curl);
if(res) {
fprintf(stderr, "add handle failed: %d.\n", res);
res = 243;
break;
multi_add_handle(m, curl);
}
}
else {
done = TRUE; /* bail out */
break;
}
}
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
else
break; /* done */
}
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 189;
break;
}
multi_fdset(m, &rd, &wr, &exc, &maxfd);
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 195;
break;
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
res = CURLM_CALL_MULTI_PERFORM;
}
select_test(maxfd+1, &rd, &wr, &exc, &interval);
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
abort_on_test_timeout();
}
test_cleanup:
/* undocumented cleanup sequence - type UB */
curl_easy_cleanup(curl);
if(m)
curl_multi_cleanup(m);
curl_global_cleanup();

View File

@ -27,118 +27,111 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
static CURLMcode perform(CURLM * multi)
static int perform(CURLM *multi)
{
int handles;
CURLMcode code;
fd_set fdread, fdwrite, fdexcep;
struct timeval mp_start;
char mp_timedout = FALSE;
mp_timedout = FALSE;
mp_start = tutil_tvnow();
int res = 0;
for(;;) {
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
int maxfd = -1;
struct timeval interval;
int maxfd = -99;
code = curl_multi_perform(multi, &handles);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (handles <= 0)
return CURLM_OK;
interval.tv_sec = 0;
interval.tv_usec = 100000L; /* 100 ms */
switch (code) {
case CURLM_OK:
break;
default:
return code;
}
res_multi_perform(multi, &handles);
if(res)
return res;
res_test_timedout();
if(res)
return res;
if(!handles)
break; /* done */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls. On success, the value of maxfd is guaranteed to be
greater or equal than -1. We call select(maxfd + 1, ...), specially in
case of (maxfd == -1), we call select(0, ...), which is basically equal
to sleep. */
res_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
if(res)
return res;
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1)
return (CURLMcode) ~CURLM_OK;
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
res_select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval);
if(res)
return res;
res_test_timedout();
if(res)
return res;
}
/* We only reach this point if (mp_timedout) */
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
return (CURLMcode) ~CURLM_OK;
return 0; /* success */
}
int test(char *URL)
{
CURLM *multi;
CURL *easy;
CURLM *multi = NULL;
CURL *easy = NULL;
int res = 0;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
start_test_timing();
global_init(CURL_GLOBAL_ALL);
multi_init(multi);
easy_init(easy);
multi_setopt(multi, CURLMOPT_PIPELINING, 1L);
easy_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite);
easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
easy_setopt(easy, CURLOPT_URL, URL);
res_multi_add_handle(multi, easy);
if(res) {
printf("curl_multi_add_handle() 1 failed\n");
goto test_cleanup;
}
if ((multi = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
if ((easy = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_multi_cleanup(multi);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
curl_multi_setopt(multi, CURLMOPT_PIPELINING, 1L);
test_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite);
test_setopt(easy, CURLOPT_FAILONERROR, 1L);
test_setopt(easy, CURLOPT_URL, URL);
if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
printf("curl_multi_add_handle() failed\n");
res = TEST_ERR_MAJOR_BAD;
} else {
if (perform(multi) != CURLM_OK)
res = perform(multi);
if(res) {
printf("retrieve 1 failed\n");
goto test_cleanup;
}
curl_multi_remove_handle(multi, easy);
}
curl_easy_reset(easy);
test_setopt(easy, CURLOPT_FAILONERROR, 1L);
test_setopt(easy, CURLOPT_URL, libtest_arg2);
easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
easy_setopt(easy, CURLOPT_URL, libtest_arg2);
if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
res_multi_add_handle(multi, easy);
if(res) {
printf("curl_multi_add_handle() 2 failed\n");
res = TEST_ERR_MAJOR_BAD;
} else {
if (perform(multi) != CURLM_OK)
printf("retrieve 2 failed\n");
curl_multi_remove_handle(multi, easy);
goto test_cleanup;
}
res = perform(multi);
if(res) {
printf("retrieve 2 failed\n");
goto test_cleanup;
}
curl_multi_remove_handle(multi, easy);
test_cleanup:
/* undocumented cleanup sequence - type UB */
curl_easy_cleanup(easy);
curl_multi_cleanup(multi);
curl_global_cleanup();

View File

@ -30,105 +30,111 @@
#include "test.h"
#include "testutil.h"
#include "warnless.h"
#include "memdebug.h"
#define TEST_HANG_TIMEOUT 60 * 1000
#define PROXY libtest_arg2
#define PROXYUSERPWD libtest_arg3
#define HOST test_argv[4]
CURL *eh = NULL;
#define NUM_HANDLES 2
static int init(CURLM *cm, const char* url, const char* userpwd,
CURL *eh[NUM_HANDLES];
static int init(int num, CURLM *cm, const char* url, const char* userpwd,
struct curl_slist *headers)
{
int res;
int res = 0;
if ((eh = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
goto init_failed;
}
res = curl_easy_setopt(eh, CURLOPT_URL, url);
res_easy_init(eh[num]);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_PROXY, PROXY);
res_easy_setopt(eh[num], CURLOPT_URL, url);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_PROXYUSERPWD, userpwd);
res_easy_setopt(eh[num], CURLOPT_PROXY, PROXY);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
res_easy_setopt(eh[num], CURLOPT_PROXYUSERPWD, userpwd);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_VERBOSE, 1L);
res_easy_setopt(eh[num], CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_HEADER, 1L);
res_easy_setopt(eh[num], CURLOPT_VERBOSE, 1L);
if(res)
goto init_failed;
res = curl_easy_setopt(eh, CURLOPT_HTTPHEADER, headers); /* custom Host: */
res_easy_setopt(eh[num], CURLOPT_HEADER, 1L);
if(res)
goto init_failed;
if ((res = (int)curl_multi_add_handle(cm, eh)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, with code %d\n", res);
res_easy_setopt(eh[num], CURLOPT_HTTPHEADER, headers); /* custom Host: */
if(res)
goto init_failed;
res_multi_add_handle(cm, eh[num]);
if(res)
goto init_failed;
}
return 0; /* success */
init_failed:
if(eh) {
curl_easy_cleanup(eh);
eh = NULL;
curl_easy_cleanup(eh[num]);
eh[num] = NULL;
return res; /* failure */
}
return 1; /* failure */
}
static int loop(CURLM *cm, const char* url, const char* userpwd,
static int loop(int num, CURLM *cm, const char* url, const char* userpwd,
struct curl_slist *headers)
{
CURLMsg *msg;
long L;
int M, Q, U = -1;
int Q, U = -1;
fd_set R, W, E;
struct timeval T;
CURLMcode rc;
int res = 0;
if(init(cm, url, userpwd, headers))
return 1; /* failure */
res = init(num, cm, url, userpwd, headers);
if(res)
return res;
while (U) {
rc = curl_multi_perform(cm, &U);
if(rc == CURLM_OUT_OF_MEMORY)
return 1; /* failure */
int M = -99;
res_multi_perform(cm, &U);
if(res)
return res;
res_test_timedout();
if(res)
return res;
if (U) {
FD_ZERO(&R);
FD_ZERO(&W);
FD_ZERO(&E);
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
fprintf(stderr, "E: curl_multi_fdset\n");
return 1; /* failure */
}
res_multi_fdset(cm, &R, &W, &E, &M);
if(res)
return res;
/* In a real-world program you OF COURSE check the return that maxfd is
bigger than -1 so that the call to select() below makes sense! */
/* At this point, M is guaranteed to be greater or equal than -1. */
if (curl_multi_timeout(cm, &L)) {
fprintf(stderr, "E: curl_multi_timeout\n");
return 1; /* failure */
}
res_multi_timeout(cm, &L);
if(res)
return res;
if(L != -1) {
T.tv_sec = L/1000;
@ -139,25 +145,33 @@ static int loop(CURLM *cm, const char* url, const char* userpwd,
T.tv_usec = 0;
}
if (0 > select(M+1, &R, &W, &E, &T)) {
fprintf(stderr, "E: select\n");
return 1; /* failure */
}
res_select_test(M+1, &R, &W, &E, &T);
if(res)
return res;
}
while ((msg = curl_multi_info_read(cm, &Q))) {
while((msg = curl_multi_info_read(cm, &Q)) != NULL) {
if(msg->msg == CURLMSG_DONE) {
int i;
CURL *e = msg->easy_handle;
fprintf(stderr, "R: %d - %s\n", (int)msg->data.result,
curl_easy_strerror(msg->data.result));
curl_multi_remove_handle(cm, e);
curl_easy_cleanup(e);
eh = NULL;
for(i=0; i < NUM_HANDLES; i++) {
if(eh[i] == e) {
eh[i] = NULL;
break;
}
else {
}
}
else
fprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg);
}
}
res_test_timedout();
if(res)
return res;
}
return 0; /* success */
@ -168,7 +182,13 @@ int test(char *URL)
CURLM *cm = NULL;
struct curl_slist *headers = NULL;
char buffer[246]; /* naively fixed-size */
int res;
int res = 0;
int i;
for(i=0; i < NUM_HANDLES; i++)
eh[i] = NULL;
start_test_timing();
if(test_argc < 4)
return 99;
@ -182,37 +202,37 @@ int test(char *URL)
return TEST_ERR_MAJOR_BAD;
}
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
res_global_init(CURL_GLOBAL_ALL);
if(res) {
curl_slist_free_all(headers);
return TEST_ERR_MAJOR_BAD;
return res;
}
if ((cm = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_slist_free_all(headers);
res_multi_init(cm);
if(res) {
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
curl_slist_free_all(headers);
return res;
}
res = loop(cm, URL, PROXYUSERPWD, headers);
res = loop(0, cm, URL, PROXYUSERPWD, headers);
if(res)
goto test_cleanup;
fprintf(stderr, "lib540: now we do the request again\n");
res = loop(cm, URL, PROXYUSERPWD, headers);
res = loop(1, cm, URL, PROXYUSERPWD, headers);
test_cleanup:
if(cm && eh)
curl_multi_remove_handle(cm, eh);
/* proper cleanup sequence - type PB */
if(eh)
curl_easy_cleanup(eh);
for(i=0; i < NUM_HANDLES; i++) {
curl_multi_remove_handle(cm, eh[i]);
curl_easy_cleanup(eh[i]);
}
if(cm)
curl_multi_cleanup(cm);
curl_global_cleanup();
curl_slist_free_all(headers);

View File

@ -33,7 +33,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
#define UPLOADTHIS "this is the blurb we want to upload\n"
@ -75,114 +75,82 @@ static curlioerr ioctlcallback(CURL *handle,
int test(char *URL)
{
int res;
CURL *curl;
int res = 0;
CURL *curl = NULL;
int counter=0;
CURLM *m = NULL;
int running=1;
struct timeval mp_start;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_VERBOSE, 1L);
test_setopt(curl, CURLOPT_HEADER, 1L);
easy_init(curl);
easy_setopt(curl, CURLOPT_URL, URL);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_HEADER, 1L);
/* read the POST data from a callback */
test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
test_setopt(curl, CURLOPT_IOCTLDATA, &counter);
test_setopt(curl, CURLOPT_READFUNCTION, readcallback);
test_setopt(curl, CURLOPT_READDATA, &counter);
easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
easy_setopt(curl, CURLOPT_READDATA, &counter);
/* We CANNOT do the POST fine without setting the size (or choose chunked)! */
test_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS));
easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS));
test_setopt(curl, CURLOPT_POST, 1L);
easy_setopt(curl, CURLOPT_POST, 1L);
#ifdef CURL_DOES_CONVERSIONS
/* Convert the POST data to ASCII. */
test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
#endif
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
test_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
test_setopt(curl, CURLOPT_PROXYAUTH,
easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
easy_setopt(curl, CURLOPT_PROXYAUTH,
(long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_add_handle(m, curl);
while (running) {
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
struct timeval timeout;
fd_set fdread, fdwrite, fdexcep;
int maxfd = -1;
int maxfd = -99;
timeout.tv_sec = 0;
timeout.tv_usec = 100000L; /* 100 ms */
multi_perform(m, &running);
abort_on_test_timeout();
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
#ifdef TPF
sleep(1); /* avoid ctl-10 dump */
#endif
if (running <= 0) {
fprintf(stderr, "nothing left running.\n");
break;
}
if(!running)
break; /* done */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
curl_multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls. On success, the value of maxfd is guaranteed to be
greater or equal than -1. We call select(maxfd + 1, ...), specially in
case of (maxfd == -1), we call select(0, ...), which is basically equal
to sleep. */
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
res = ~CURLM_OK;
break;
}
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
if (mp_timedout) {
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
}
test_cleanup:
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, curl);
curl_multi_cleanup(m);
}
curl_easy_cleanup(curl);
curl_global_cleanup();

View File

@ -21,9 +21,12 @@
***************************************************************************/
#include "test.h"
#include "testutil.h"
#include "warnless.h"
#include "memdebug.h"
#define TEST_HANG_TIMEOUT 60 * 1000
/*
* Simply download a HTTPS file!
*
@ -36,43 +39,44 @@
*/
int test(char *URL)
{
CURL *http_handle;
CURL *http_handle = NULL;
CURLM *multi_handle = NULL;
int res;
int res = 0;
int still_running; /* keep number of running handles */
http_handle = curl_easy_init();
if (!http_handle)
return TEST_ERR_MAJOR_BAD;
start_test_timing();
/*
** curl_global_init called indirectly from curl_easy_init.
*/
easy_init(http_handle);
/* set options */
test_setopt(http_handle, CURLOPT_URL, URL);
test_setopt(http_handle, CURLOPT_HEADER, 1L);
test_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
test_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
easy_setopt(http_handle, CURLOPT_URL, URL);
easy_setopt(http_handle, CURLOPT_HEADER, 1L);
easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
easy_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
/* init a multi stack */
multi_handle = curl_multi_init();
if (!multi_handle) {
curl_easy_cleanup(http_handle);
return TEST_ERR_MAJOR_BAD;
}
multi_init(multi_handle);
/* add the individual transfers */
curl_multi_add_handle(multi_handle, http_handle);
multi_add_handle(multi_handle, http_handle);
/* we start some action by calling perform right away */
(void) curl_multi_perform(multi_handle, &still_running);
multi_perform(multi_handle, &still_running);
abort_on_test_timeout();
while(still_running) {
struct timeval timeout;
int rc; /* select() return code */
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
int maxfd = -99;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
@ -83,31 +87,25 @@ int test(char *URL)
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls, *and* you make sure that maxfd is bigger than -1 so
that the call to select() below makes sense! */
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
switch(rc) {
case -1:
/* select error */
break;
case 0:
default:
/* timeout or readable/writable sockets */
(void) curl_multi_perform(multi_handle, &still_running);
break;
}
multi_perform(multi_handle, &still_running);
abort_on_test_timeout();
}
test_cleanup:
if(multi_handle)
curl_multi_cleanup(multi_handle);
/* undocumented cleanup sequence - type UA */
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(http_handle);
curl_global_cleanup();

View File

@ -27,120 +27,65 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
int test(char *URL)
{
int res = 0;
CURL *curl;
CURL *curl = NULL;
int running;
char done=FALSE;
CURLM *m = NULL;
struct timeval ml_start;
struct timeval mp_start;
char ml_timedout = FALSE;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_VERBOSE, 1);
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
easy_init(curl);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(curl, CURLOPT_URL, URL);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(curl);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_add_handle(m, curl);
fprintf(stderr, "Start at URL 0\n");
while (!done) {
fd_set rd, wr, exc;
int max_fd;
for(;;) {
struct timeval interval;
fd_set rd, wr, exc;
int maxfd = -99;
interval.tv_sec = 1;
interval.tv_usec = 0;
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_perform(m, &running);
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
done = TRUE; /* bail out */
break;
}
abort_on_test_timeout();
if (res != CURLM_OK) {
fprintf(stderr, "not okay???\n");
break;
}
if(!running)
break; /* done */
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&exc);
max_fd = 0;
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
fprintf(stderr, "unexpected failured of fdset.\n");
res = 189;
break;
}
multi_fdset(m, &rd, &wr, &exc, &maxfd);
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
fprintf(stderr, "bad select??\n");
res = 195;
break;
}
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
if (ml_timedout || mp_timedout) {
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
select_test(maxfd+1, &rd, &wr, &exc, &interval);
abort_on_test_timeout();
}
test_cleanup:
/* undocumented cleanup sequence - type UB */
curl_easy_cleanup(curl);
if(m)
curl_multi_cleanup(m);
curl_global_cleanup();

View File

@ -25,8 +25,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
/*
* Get a single URL without select().
@ -34,84 +33,51 @@
int test(char *URL)
{
CURL *c;
CURL *c = NULL;
CURLM *m = NULL;
int res = 0;
int running = 1;
double connect_time = 0.0;
struct timeval mp_start;
char mp_timedout = FALSE;
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
start_test_timing();
if ((c = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(c, CURLOPT_HEADER, 1L);
test_setopt(c, CURLOPT_URL, URL);
easy_init(c);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_setopt(c, CURLOPT_HEADER, 1L);
easy_setopt(c, CURLOPT_URL, URL);
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(c);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(m);
mp_timedout = FALSE;
mp_start = tutil_tvnow();
multi_add_handle(m, c);
while (running) {
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
struct timeval timeout;
fd_set fdread, fdwrite, fdexcep;
int maxfd = -1;
int maxfd = -99;
res = (int)curl_multi_perform(m, &running);
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
MULTI_PERFORM_HANG_TIMEOUT) {
mp_timedout = TRUE;
break;
}
if (running <= 0) {
fprintf(stderr, "nothing left running.\n");
break;
}
timeout.tv_sec = 0;
timeout.tv_usec = 100000L; /* 100 ms */
multi_perform(m, &running);
abort_on_test_timeout();
if(!running)
break; /* done */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
curl_multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of the
function calls. On success, the value of maxfd is guaranteed to be
greater or equal than -1. We call select(maxfd + 1, ...), specially in
case of (maxfd == -1), we call select(0, ...), which is basically equal
to sleep. */
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
res = ~CURLM_OK;
break;
}
}
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
if (mp_timedout) {
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
}
curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time);
@ -122,10 +88,10 @@ int test(char *URL)
test_cleanup:
if(m) {
/* proper cleanup sequence - type PA */
curl_multi_remove_handle(m, c);
curl_multi_cleanup(m);
}
curl_easy_cleanup(c);
curl_global_cleanup();

View File

@ -27,6 +27,8 @@
#include "warnless.h"
#include "memdebug.h"
#define TEST_HANG_TIMEOUT 60 * 1000
/* 3x download!
* 1. normal
* 2. dup handle
@ -35,26 +37,21 @@
int test(char *URL)
{
CURLMcode m;
CURL *handle = NULL, *duphandle;
CURL *handle = NULL;
CURL *duphandle = NULL;
CURLM *mhandle = NULL;
int res = 0;
int still_running = 0;
if(curl_global_init(CURL_GLOBAL_ALL)) {
fprintf(stderr, "curl_global_init() failed\n");
goto test_cleanup;
}
start_test_timing();
handle = curl_easy_init();
if(!handle) {
res = CURLE_OUT_OF_MEMORY;
goto test_cleanup;
}
global_init(CURL_GLOBAL_ALL);
test_setopt(handle, CURLOPT_URL, URL);
test_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
test_setopt(handle, CURLOPT_VERBOSE, 1L);
easy_init(handle);
easy_setopt(handle, CURLOPT_URL, URL);
easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
easy_setopt(handle, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(handle);
if(res)
@ -70,49 +67,48 @@ int test(char *URL)
curl_easy_cleanup(handle);
handle = duphandle;
mhandle = curl_multi_init();
if(!mhandle) {
fprintf(stderr, "curl_multi_init() failed\n");
goto test_cleanup;
}
multi_init(mhandle);
curl_multi_add_handle(mhandle, handle);
multi_add_handle(mhandle, handle);
curl_multi_perform(mhandle, &still_running);
multi_perform(mhandle, &still_running);
abort_on_test_timeout();
while(still_running) {
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
int rc;
struct timeval timeout;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int max_fdset = -1;
int maxfd = -99;
timeout.tv_sec = 0;
timeout.tv_usec = 100000L; /* 100 ms */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
m = curl_multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &max_fdset);
if(m != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() error\n");
goto test_cleanup;
}
/* We call select(max_fdset + 1, ...), specially in case of (maxfd == -1),
* we call select(0, ...), which is basically equal to sleep. */
rc = select(max_fdset + 1, &fdread, &fdwrite, &fdexcep, &timeout);
if(rc == -1) {
fprintf(stderr, "select() error\n");
goto test_cleanup;
}
else {
curl_multi_perform(mhandle, &still_running);
}
multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
abort_on_test_timeout();
multi_perform(mhandle, &still_running);
abort_on_test_timeout();
}
test_cleanup:
if(mhandle)
/* undocumented cleanup sequence - type UA */
curl_multi_cleanup(mhandle);
if(handle)
curl_easy_cleanup(handle);
curl_global_cleanup();
return res;
}

View File

@ -27,7 +27,7 @@
#include "warnless.h"
#include "memdebug.h"
#define MAIN_LOOP_HANG_TIMEOUT 4 * 1000
#define TEST_HANG_TIMEOUT 60 * 1000
struct Sockets
{
@ -226,30 +226,30 @@ static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset,
int test(char *URL)
{
int res = 0;
CURL *curl;
FILE *hd_src ;
CURL *curl = NULL;
FILE *hd_src = NULL;
int hd ;
int error;
struct_stat file_info;
CURLM *m = NULL;
struct timeval ml_start;
char ml_timedout = FALSE;
struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
struct timeval timeout = {-1, 0};
int success = 0;
start_test_timing();
if (!libtest_arg3) {
fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n");
return -1;
return TEST_ERR_USAGE;
}
hd_src = fopen(libtest_arg2, "rb");
if(NULL == hd_src) {
error = ERRNO;
fprintf(stderr, "fopen() failed with error: %d %s\n",
fprintf(stderr, "fopen() failed with error: %d (%s)\n",
error, strerror(error));
fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
return TEST_ERR_MAJOR_BAD;
fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
return TEST_ERR_FOPEN;
}
/* get the file size of the local file */
@ -257,71 +257,49 @@ int test(char *URL)
if(hd == -1) {
/* can't open file, bail out */
error = ERRNO;
fprintf(stderr, "fstat() failed with error: %d %s\n",
fprintf(stderr, "fstat() failed with error: %d (%s)\n",
error, strerror(error));
fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2);
fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2);
fclose(hd_src);
return -1;
return TEST_ERR_FSTAT;
}
fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size);
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
res_global_init(CURL_GLOBAL_ALL);
if(res) {
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
return res;
}
if ((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
fclose(hd_src);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_init(curl);
/* enable uploading */
test_setopt(curl, CURLOPT_UPLOAD, 1L);
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
test_setopt(curl,CURLOPT_URL, URL);
easy_setopt(curl,CURLOPT_URL, URL);
/* go verbose */
test_setopt(curl, CURLOPT_VERBOSE, 1L);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* now specify which file to upload */
test_setopt(curl, CURLOPT_READDATA, hd_src);
easy_setopt(curl, CURLOPT_READDATA, hd_src);
test_setopt(curl, CURLOPT_USERPWD, libtest_arg3);
test_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
test_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3);
easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
if ((m = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
test_multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback);
test_multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
multi_init(m);
test_multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
test_multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback);
multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_multi_cleanup(m);
curl_easy_cleanup(curl);
curl_global_cleanup();
fclose(hd_src);
return TEST_ERR_MAJOR_BAD;
}
multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
ml_timedout = FALSE;
ml_start = tutil_tvnow();
multi_add_handle(m, curl);
while (!checkForCompletion(m, &success))
{
@ -329,12 +307,6 @@ int test(char *URL)
curl_socket_t maxFd = 0;
struct timeval tv = {10, 0};
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
MAIN_LOOP_HANG_TIMEOUT) {
ml_timedout = TRUE;
break;
}
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
updateFdSet(&sockets.read, &readSet, &maxFd);
@ -363,6 +335,8 @@ int test(char *URL)
/* Curl's timer has elapsed. */
notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout");
}
abort_on_test_timeout();
}
if (!success)
@ -370,28 +344,24 @@ int test(char *URL)
fprintf(stderr, "Error uploading file.\n");
res = TEST_ERR_MAJOR_BAD;
}
else if (ml_timedout) {
fprintf(stderr, "ABORTING TEST, since it seems "
"that it would have run forever.\n");
res = TEST_ERR_RUNS_FOREVER;
}
test_cleanup:
if(m)
/* proper cleanup sequence - type PB */
curl_multi_remove_handle(m, curl);
curl_easy_cleanup(curl);
if(m) {
fprintf(stderr, "Now multi-cleanup!\n");
curl_multi_cleanup(m);
}
curl_global_cleanup();
fclose(hd_src); /* close the local file */
/* close the local file */
fclose(hd_src);
/* free local memory */
if(sockets.read.sockets)
free(sockets.read.sockets);
if(sockets.write.sockets)
free(sockets.write.sockets);
curl_global_cleanup();
return res;
}

View File

@ -33,57 +33,35 @@
int test(char *URL)
{
int stillRunning;
CURLM* multiHandle;
CURL* curl;
int res1 = 0;
int res;
CURLM* multiHandle = NULL;
CURL* curl = NULL;
int res = 0;
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n");
return TEST_ERR_MAJOR_BAD;
}
global_init(CURL_GLOBAL_ALL);
if((multiHandle = curl_multi_init()) == NULL) {
fprintf(stderr, "curl_multi_init() failed\n");
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_init(multiHandle);
if((curl = curl_easy_init()) == NULL) {
fprintf(stderr, "curl_easy_init() failed\n");
curl_multi_cleanup(multiHandle);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
easy_init(curl);
test_setopt(curl, CURLOPT_USERPWD, libtest_arg2);
test_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
test_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
easy_setopt(curl, CURLOPT_USERPWD, libtest_arg2);
easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
test_setopt(curl, CURLOPT_UPLOAD, 1);
test_setopt(curl, CURLOPT_VERBOSE, 1);
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_INFILESIZE, (long)5);
easy_setopt(curl, CURLOPT_URL, URL);
easy_setopt(curl, CURLOPT_INFILESIZE, (long)5);
if((res = (int)curl_multi_add_handle(multiHandle, curl)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_easy_cleanup(curl);
curl_multi_cleanup(multiHandle);
curl_global_cleanup();
return TEST_ERR_MAJOR_BAD;
}
multi_add_handle(multiHandle, curl);
/* this tests if removing an easy handle immediately after multi
perform has been called succeeds or not. */
fprintf(stderr, "curl_multi_perform()...\n");
res1 = (int) curl_multi_perform(multiHandle, &stillRunning);
if(res1)
fprintf(stderr, "curl_multi_perform() failed, "
"with code %d\n", res1);
else
multi_perform(multiHandle, &stillRunning);
fprintf(stderr, "curl_multi_perform() succeeded\n");
fprintf(stderr, "curl_multi_remove_handle()...\n");
@ -96,12 +74,11 @@ int test(char *URL)
test_cleanup:
/* undocumented cleanup sequence - type UB */
curl_easy_cleanup(curl);
curl_multi_cleanup(multiHandle);
curl_global_cleanup();
if(res)
return res;
else
return res1;
}

View File

@ -50,9 +50,6 @@
# include "select.h"
#endif
#define TEST_ERR_MAJOR_BAD 100
#define TEST_ERR_RUNS_FOREVER 99
#define test_setopt(A,B,C) \
if((res = curl_easy_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup
@ -66,7 +63,9 @@ extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
extern int test_argc;
extern char **test_argv;
extern int select_test(int num_fds, fd_set *rd, fd_set *wr, fd_set *exc,
extern struct timeval tv_test_start; /* for test timing */
extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc,
struct timeval *tv);
extern int test(char *URL); /* the actual test function provided by each
@ -75,3 +74,331 @@ extern int test(char *URL); /* the actual test function provided by each
#ifdef UNITTESTS
extern int unitfail;
#endif
/*
** TEST_ERR_* values must be greater than CURL_LAST CURLcode in order
** to avoid confusion with any CURLcode or CURLMcode. These TEST_ERR_*
** codes are returned to signal test specific situations and should
** not get mixed with CURLcode or CURLMcode values.
**
** For portability reasons TEST_ERR_* values should be less than 127.
*/
#define TEST_ERR_MAJOR_BAD 126
#define TEST_ERR_RUNS_FOREVER 125
#define TEST_ERR_EASY_INIT 124
#define TEST_ERR_MULTI_INIT 123
#define TEST_ERR_NUM_HANDLES 122
#define TEST_ERR_SELECT 121
#define TEST_ERR_SUCCESS 120
#define TEST_ERR_FAILURE 119
#define TEST_ERR_USAGE 118
#define TEST_ERR_FOPEN 117
#define TEST_ERR_FSTAT 116
/*
** Macros for test source code readability/maintainability.
**
** All of the following macros require that an int data type 'res' variable
** exists in scope where macro is used, and that it has been initialized to
** zero before the macro is used.
**
** exe_* and chk_* macros are helper macros not intended to be used from
** outside of this header file. Arguments 'Y' and 'Z' of these represent
** source code file and line number, while Arguments 'A', 'B', etc, are
** the arguments used to actually call a libcurl function.
**
** All easy_* and multi_* macros call a libcurl function and evaluate if
** the function has succeeded or failed. When the function succeeds 'res'
** variable is not set nor cleared and program continues normal flow. On
** the other hand if function fails 'res' variable is set and a jump to
** label 'test_cleanup' is performed.
**
** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro
** counterpart that operates in tha same way with the exception that no
** jump takes place in case of failure. res_easy_* and res_multi_* macros
** should be immediately followed by checking if 'res' variable has been
** set.
**
** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the
** TEST_ERR_* values defined above. It is advisable to return this value
** as test result.
*/
/* ---------------------------------------------------------------- */
#define exe_easy_init(A,Y,Z) do { \
if(((A) = curl_easy_init()) == NULL) { \
fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \
res = TEST_ERR_EASY_INIT; \
} \
} WHILE_FALSE
#define res_easy_init(A) \
exe_easy_init((A),(__FILE__),(__LINE__))
#define chk_easy_init(A,Y,Z) do { \
exe_easy_init((A),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define easy_init(A) \
chk_easy_init((A),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_init(A,Y,Z) do { \
if(((A) = curl_multi_init()) == NULL) { \
fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \
res = TEST_ERR_MULTI_INIT; \
} \
} WHILE_FALSE
#define res_multi_init(A) \
exe_multi_init((A),(__FILE__),(__LINE__))
#define chk_multi_init(A,Y,Z) do { \
exe_multi_init((A),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_init(A) \
chk_multi_init((A),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_easy_setopt(A,B,C,Y,Z) do { \
CURLcode ec; \
if((ec = curl_easy_setopt((A),(B),(C))) != CURLE_OK) { \
fprintf(stderr, "%s:%d curl_easy_setopt() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_easy_strerror(ec)); \
res = (int)ec; \
} \
} WHILE_FALSE
#define res_easy_setopt(A,B,C) \
exe_easy_setopt((A),(B),(C),(__FILE__),(__LINE__))
#define chk_easy_setopt(A,B,C,Y,Z) do { \
exe_easy_setopt((A),(B),(C),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define easy_setopt(A,B,C) \
chk_easy_setopt((A),(B),(C),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_setopt(A,B,C,Y,Z) do { \
CURLMcode ec; \
if((ec = curl_multi_setopt((A),(B),(C))) != CURLM_OK) { \
fprintf(stderr, "%s:%d curl_multi_setopt() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
res = (int)ec; \
} \
} WHILE_FALSE
#define res_multi_setopt(A,B,C) \
exe_multi_setopt((A),(B),(C),(__FILE__),(__LINE__))
#define chk_multi_setopt(A,B,C,Y,Z) do { \
exe_multi_setopt((A),(B),(C),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_setopt(A,B,C) \
chk_multi_setopt((A),(B),(C),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_add_handle(A,B,Y,Z) do { \
CURLMcode ec; \
if((ec = curl_multi_add_handle((A),(B))) != CURLM_OK) { \
fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
res = (int)ec; \
} \
} WHILE_FALSE
#define res_multi_add_handle(A,B) \
exe_multi_add_handle((A),(B),(__FILE__),(__LINE__))
#define chk_multi_add_handle(A,B,Y,Z) do { \
exe_multi_add_handle((A),(B),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_add_handle(A,B) \
chk_multi_add_handle((A),(B),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_perform(A,B,Y,Z) do { \
CURLMcode ec; \
if((ec = curl_multi_perform((A),(B))) != CURLM_OK) { \
fprintf(stderr, "%s:%d curl_multi_perform() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
res = (int)ec; \
} \
else if(*((B)) < 0) { \
fprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \
"but returned invalid running_handles value (%d)\n", \
(Y), (Z), (int)*((B))); \
res = TEST_ERR_NUM_HANDLES; \
} \
} WHILE_FALSE
#define res_multi_perform(A,B) \
exe_multi_perform((A),(B),(__FILE__),(__LINE__))
#define chk_multi_perform(A,B,Y,Z) do { \
exe_multi_perform((A),(B),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_perform(A,B) \
chk_multi_perform((A),(B),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_fdset(A,B,C,D,E,Y,Z) do { \
CURLMcode ec; \
if((ec = curl_multi_fdset((A),(B),(C),(D),(E))) != CURLM_OK) { \
fprintf(stderr, "%s:%d curl_multi_fdset() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
res = (int)ec; \
} \
else if(*((E)) < -1) { \
fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \
"but returned invalid max_fd value (%d)\n", \
(Y), (Z), (int)*((E))); \
res = TEST_ERR_NUM_HANDLES; \
} \
} WHILE_FALSE
#define res_multi_fdset(A,B,C,D,E) \
exe_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
#define chk_multi_fdset(A,B,C,D,E,Y,Z) do { \
exe_multi_fdset((A),(B),(C),(D),(E),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_fdset(A,B,C,D,E) \
chk_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_multi_timeout(A,B,Y,Z) do { \
CURLMcode ec; \
if((ec = curl_multi_timeout((A),(B))) != CURLM_OK) { \
fprintf(stderr, "%s:%d curl_multi_timeout() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_multi_strerror(ec)); \
res = (int)ec; \
} \
} WHILE_FALSE
#define res_multi_timeout(A,B) \
exe_multi_timeout((A),(B),(__FILE__),(__LINE__))
#define chk_multi_timeout(A,B,Y,Z) do { \
exe_multi_timeout((A),(B),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define multi_timeout(A,B) \
chk_multi_timeout((A),(B),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_select_test(A,B,C,D,E,Y,Z) do { \
int ec; \
if(select_wrapper((A),(B),(C),(D),(E)) == -1 ) { \
ec = SOCKERRNO; \
fprintf(stderr, "%s:%d select() failed, with " \
"errno %d (%s)\n", \
(Y), (Z), ec, strerror(ec)); \
res = TEST_ERR_SELECT; \
} \
} WHILE_FALSE
#define res_select_test(A,B,C,D,E) \
exe_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
#define chk_select_test(A,B,C,D,E,Y,Z) do { \
exe_select_test((A),(B),(C),(D),(E),(Y),(Z)); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define select_test(A,B,C,D,E) \
chk_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define start_test_timing() do { \
tv_test_start = tutil_tvnow(); \
} WHILE_FALSE
#define exe_test_timedout(Y,Z) do { \
if(tutil_tvdiff(tutil_tvnow(), tv_test_start) > TEST_HANG_TIMEOUT) { \
fprintf(stderr, "%s:%d ABORTING TEST, since it seems " \
"that it would have run forever.\n", (Y), (Z)); \
res = TEST_ERR_RUNS_FOREVER; \
} \
} WHILE_FALSE
#define res_test_timedout() \
exe_test_timedout((__FILE__),(__LINE__))
#define chk_test_timedout(Y,Z) do { \
exe_test_timedout(Y,Z); \
if(res) \
goto test_cleanup; \
} WHILE_FALSE
#define abort_on_test_timeout() \
chk_test_timedout((__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */
#define exe_global_init(A,Y,Z) do { \
CURLcode ec; \
if((ec = curl_global_init((A))) != CURLE_OK) { \
fprintf(stderr, "%s:%d curl_global_init() failed, " \
"with code %d (%s)\n", \
(Y), (Z), (int)ec, curl_easy_strerror(ec)); \
res = (int)ec; \
} \
} WHILE_FALSE
#define res_global_init(A) \
exe_global_init((A),(__FILE__),(__LINE__))
#define chk_global_init(A,Y,Z) do { \
exe_global_init((A),(Y),(Z)); \
if(res) \
return res; \
} WHILE_FALSE
/* global_init() is different than other macros. In case of
failure it 'return's instead of going to 'test_cleanup'. */
#define global_init(A) \
chk_global_init((A),(__FILE__),(__LINE__))
/* ---------------------------------------------------------------- */