mirror of
https://github.com/moparisthebest/curl
synced 2024-11-15 05:55:04 -05:00
multi tests: OOM handling fixes
Additionally, improved error checking and logging.
This commit is contained in:
parent
90fcad63cb
commit
629d2e3450
@ -35,9 +35,10 @@ http://%HOSTIP:%HTTPSPORT/504 %HOSTIP:55555
|
|||||||
</client>
|
</client>
|
||||||
|
|
||||||
# Verify data after the test has been "shot"
|
# Verify data after the test has been "shot"
|
||||||
|
# TEST_ERR_SUCCESS is errorcode 120
|
||||||
<verify>
|
<verify>
|
||||||
<errorcode>
|
<errorcode>
|
||||||
100
|
120
|
||||||
</errorcode>
|
</errorcode>
|
||||||
</verify>
|
</verify>
|
||||||
</testcase>
|
</testcase>
|
||||||
|
@ -32,11 +32,10 @@ ftp://%HOSTIP:%FTPPORT/538
|
|||||||
</client>
|
</client>
|
||||||
|
|
||||||
# Verify data after the test has been "shot"
|
# Verify data after the test has been "shot"
|
||||||
|
# TEST_ERR_SUCCESS is errorcode 120
|
||||||
<verify>
|
<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>
|
<errorcode>
|
||||||
100
|
120
|
||||||
</errorcode>
|
</errorcode>
|
||||||
<protocol>
|
<protocol>
|
||||||
USER anonymous
|
USER anonymous
|
||||||
|
@ -93,7 +93,7 @@ lib537_SOURCES = lib537.c $(SUPPORTFILES) $(WARNLESS)
|
|||||||
|
|
||||||
lib539_SOURCES = lib539.c $(SUPPORTFILES)
|
lib539_SOURCES = lib539.c $(SUPPORTFILES)
|
||||||
|
|
||||||
lib540_SOURCES = lib540.c $(SUPPORTFILES) $(WARNLESS)
|
lib540_SOURCES = lib540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
|
|
||||||
lib541_SOURCES = lib541.c $(SUPPORTFILES)
|
lib541_SOURCES = lib541.c $(SUPPORTFILES)
|
||||||
|
|
||||||
@ -125,11 +125,11 @@ lib556_SOURCES = lib556.c $(SUPPORTFILES)
|
|||||||
|
|
||||||
lib557_SOURCES = lib557.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)
|
lib574_SOURCES = lib574.c $(SUPPORTFILES)
|
||||||
|
|
||||||
lib575_SOURCES = lib575.c $(SUPPORTFILES) $(WARNLESS)
|
lib575_SOURCES = lib575.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||||
|
|
||||||
lib576_SOURCES = lib576.c $(SUPPORTFILES)
|
lib576_SOURCES = lib576.c $(SUPPORTFILES)
|
||||||
|
|
||||||
|
@ -30,19 +30,25 @@
|
|||||||
# include "memdebug.h"
|
# include "memdebug.h"
|
||||||
#endif
|
#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)
|
struct timeval *tv)
|
||||||
{
|
{
|
||||||
|
if(nfds < 0) {
|
||||||
|
SET_SOCKERRNO(EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#ifdef USE_WINSOCK
|
#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);
|
Sleep(1000*tv->tv_sec + tv->tv_usec/1000);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return select(num_fds, rd, wr, exc, tv);
|
return select(nfds, rd, wr, exc, tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *libtest_arg2=NULL;
|
char *libtest_arg2=NULL;
|
||||||
@ -50,6 +56,8 @@ char *libtest_arg3=NULL;
|
|||||||
int test_argc;
|
int test_argc;
|
||||||
char **test_argv;
|
char **test_argv;
|
||||||
|
|
||||||
|
struct timeval tv_test_start; /* for test timing */
|
||||||
|
|
||||||
#ifdef UNITTESTS
|
#ifdef UNITTESTS
|
||||||
int unitfail; /* for unittests */
|
int unitfail; /* for unittests */
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a single URL without select().
|
* Get a single URL without select().
|
||||||
@ -34,90 +33,57 @@
|
|||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL *c;
|
CURL *c = NULL;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int running=1;
|
int running;
|
||||||
struct timeval mp_start;
|
|
||||||
char mp_timedout = FALSE;
|
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(c, CURLOPT_URL, URL);
|
easy_init(c);
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
easy_setopt(c, CURLOPT_URL, URL);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_easy_cleanup(c);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_timedout = FALSE;
|
multi_add_handle(m, c);
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while (running) {
|
for(;;) {
|
||||||
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
|
struct timeval timeout;
|
||||||
fd_set fdread, fdwrite, fdexcep;
|
fd_set fdread, fdwrite, fdexcep;
|
||||||
int maxfd = -1;
|
int maxfd = -99;
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
timeout.tv_sec = 0;
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
timeout.tv_usec = 100000L; /* 100 ms */
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
multi_perform(m, &running);
|
||||||
break;
|
|
||||||
}
|
abort_on_test_timeout();
|
||||||
if (running <= 0) {
|
|
||||||
fprintf(stderr, "nothing left running.\n");
|
if(!running)
|
||||||
break;
|
break; /* done */
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
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
|
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
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. */
|
|
||||||
|
|
||||||
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
res = ~CURLM_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_timedout) {
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
|
|
||||||
"that it would have run forever.\n");
|
abort_on_test_timeout();
|
||||||
res = TEST_ERR_RUNS_FOREVER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, c);
|
|
||||||
curl_multi_cleanup(m);
|
curl_multi_remove_handle(m, c);
|
||||||
}
|
curl_multi_cleanup(m);
|
||||||
curl_easy_cleanup(c);
|
curl_easy_cleanup(c);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source code in here hugely as reported in bug report 651460 by
|
* Source code in here hugely as reported in bug report 651460 by
|
||||||
@ -38,121 +37,62 @@
|
|||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL *c;
|
CURL *c = NULL;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int running;
|
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) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
|
easy_init(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);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
easy_setopt(c, CURLOPT_URL, URL);
|
||||||
curl_easy_cleanup(c);
|
easy_setopt(c, CURLOPT_USERPWD, "test:ing");
|
||||||
curl_global_cleanup();
|
easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
|
||||||
return TEST_ERR_MAJOR_BAD;
|
easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||||
}
|
easy_setopt(c, CURLOPT_HEADER, 1L);
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
multi_add_handle(m, c);
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while(!done) {
|
for(;;) {
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
done = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_timedout || done)
|
if(!running)
|
||||||
break;
|
break; /* done */
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
|
||||||
fprintf(stderr, "not okay???\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 89;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 95;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
|
|
||||||
if (ml_timedout || mp_timedout) {
|
abort_on_test_timeout();
|
||||||
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:
|
test_cleanup:
|
||||||
|
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, c);
|
|
||||||
curl_multi_cleanup(m);
|
curl_multi_remove_handle(m, c);
|
||||||
}
|
curl_multi_cleanup(m);
|
||||||
curl_easy_cleanup(c);
|
curl_easy_cleanup(c);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Source code in here hugely as reported in bug report 651464 by
|
* Source code in here hugely as reported in bug report 651464 by
|
||||||
@ -37,81 +36,41 @@
|
|||||||
*/
|
*/
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL *c;
|
CURL *c = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
fd_set rd, wr, exc;
|
fd_set rd, wr, exc;
|
||||||
CURLMcode ret;
|
|
||||||
char done = FALSE;
|
|
||||||
int running;
|
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) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
easy_init(c);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The point here is that there must not be anything running on the given
|
/* The point here is that there must not be anything running on the given
|
||||||
proxy port */
|
proxy port */
|
||||||
if (libtest_arg2)
|
if (libtest_arg2)
|
||||||
test_setopt(c, CURLOPT_PROXY, libtest_arg2);
|
easy_setopt(c, CURLOPT_PROXY, libtest_arg2);
|
||||||
test_setopt(c, CURLOPT_URL, URL);
|
easy_setopt(c, CURLOPT_URL, URL);
|
||||||
test_setopt(c, CURLOPT_VERBOSE, 1L);
|
easy_setopt(c, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
multi_init(m);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_easy_cleanup(c);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = curl_multi_add_handle(m, c)) != CURLM_OK) {
|
multi_add_handle(m, c);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
for(;;) {
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while (!done) {
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
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");
|
fprintf(stderr, "curl_multi_perform()\n");
|
||||||
|
|
||||||
ret = curl_multi_perform(m, &running);
|
multi_perform(m, &running);
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
abort_on_test_timeout();
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (mp_timedout)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!running) {
|
if(!running) {
|
||||||
/* This is where this code is expected to reach */
|
/* 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);
|
CURLMsg *msg = curl_multi_info_read(m, &numleft);
|
||||||
fprintf(stderr, "Expected: not running\n");
|
fprintf(stderr, "Expected: not running\n");
|
||||||
if(msg && !numleft)
|
if(msg && !numleft)
|
||||||
res = 100; /* this is where we should be */
|
res = TEST_ERR_SUCCESS; /* this is where we should be */
|
||||||
else
|
else
|
||||||
res = 99; /* not correct */
|
res = TEST_ERR_FAILURE; /* not correct */
|
||||||
break;
|
break; /* done */
|
||||||
}
|
|
||||||
fprintf(stderr, "running == %d, ret == %d\n", running, ret);
|
|
||||||
|
|
||||||
if (ret != CURLM_OK) {
|
|
||||||
res = 2;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "running == %d\n", running);
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
fprintf(stderr, "curl_multi_fdset()\n");
|
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) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
|
||||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
|
||||||
"that it would have run forever.\n");
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
res = TEST_ERR_RUNS_FOREVER;
|
|
||||||
|
abort_on_test_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, c);
|
|
||||||
curl_multi_cleanup(m);
|
curl_multi_remove_handle(m, c);
|
||||||
}
|
curl_multi_cleanup(m);
|
||||||
curl_easy_cleanup(c);
|
curl_easy_cleanup(c);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -25,71 +25,40 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL* curls;
|
CURL* curls = NULL;
|
||||||
CURLM* multi;
|
CURLM* multi = NULL;
|
||||||
int still_running;
|
int still_running;
|
||||||
int i = -1;
|
int i = -1;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURLMsg *msg;
|
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) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((multi = curl_multi_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((curls = curl_easy_init()) == NULL) {
|
multi_init(multi);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_multi_cleanup(multi);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(curls, CURLOPT_URL, URL);
|
easy_init(curls);
|
||||||
test_setopt(curls, CURLOPT_HEADER, 1L);
|
|
||||||
|
|
||||||
if ((ret = curl_multi_add_handle(multi, curls)) != CURLM_OK) {
|
easy_setopt(curls, CURLOPT_URL, URL);
|
||||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
easy_setopt(curls, CURLOPT_HEADER, 1L);
|
||||||
"with code %d\n", ret);
|
|
||||||
curl_easy_cleanup(curls);
|
|
||||||
curl_multi_cleanup(multi);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_timedout = FALSE;
|
multi_add_handle(multi, curls);
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
ret = curl_multi_perform(multi, &still_running);
|
multi_perform(multi, &still_running);
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT)
|
|
||||||
mp_timedout = TRUE;
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
abort_on_test_timeout();
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while ((!ml_timedout) && (!mp_timedout) && (still_running)) {
|
while(still_running) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int rc;
|
|
||||||
fd_set fdread;
|
fd_set fdread;
|
||||||
fd_set fdwrite;
|
fd_set fdwrite;
|
||||||
fd_set fdexcep;
|
fd_set fdexcep;
|
||||||
int maxfd;
|
int maxfd = -99;
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
@ -97,47 +66,29 @@ int test(char *URL)
|
|||||||
timeout.tv_sec = 1;
|
timeout.tv_sec = 1;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
rc = select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
|
||||||
switch(rc) {
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
case -1:
|
|
||||||
break;
|
abort_on_test_timeout();
|
||||||
case 0:
|
|
||||||
default:
|
multi_perform(multi, &still_running);
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
abort_on_test_timeout();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
test_cleanup:
|
||||||
|
|
||||||
|
/* undocumented cleanup sequence - type UA */
|
||||||
|
|
||||||
curl_multi_cleanup(multi);
|
curl_multi_cleanup(multi);
|
||||||
curl_easy_cleanup(curls);
|
curl_easy_cleanup(curls);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
@ -27,37 +27,39 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl;
|
CURL *curl = NULL;
|
||||||
FILE *hd_src ;
|
FILE *hd_src = NULL;
|
||||||
int hd ;
|
int hd ;
|
||||||
int error;
|
int error;
|
||||||
struct_stat file_info;
|
struct_stat file_info;
|
||||||
int running;
|
|
||||||
char done=FALSE;
|
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
struct timeval ml_start;
|
int running;
|
||||||
struct timeval mp_start;
|
|
||||||
char ml_timedout = FALSE;
|
|
||||||
char mp_timedout = FALSE;
|
|
||||||
|
|
||||||
if (!libtest_arg2) {
|
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");
|
fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n");
|
||||||
return -1;
|
#endif
|
||||||
|
return TEST_ERR_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hd_src = fopen(libtest_arg2, "rb");
|
hd_src = fopen(libtest_arg2, "rb");
|
||||||
if(NULL == hd_src) {
|
if(NULL == hd_src) {
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
fprintf(stderr, "fopen() failed with error: %d %s\n",
|
fprintf(stderr, "fopen() failed with error: %d (%s)\n",
|
||||||
error, strerror(error));
|
error, strerror(error));
|
||||||
fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
|
fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
return TEST_ERR_FOPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the file size of the local file */
|
/* get the file size of the local file */
|
||||||
@ -65,40 +67,35 @@ int test(char *URL)
|
|||||||
if(hd == -1) {
|
if(hd == -1) {
|
||||||
/* can't open file, bail out */
|
/* can't open file, bail out */
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
fprintf(stderr, "fstat() failed with error: %d %s\n",
|
fprintf(stderr, "fstat() failed with error: %d (%s)\n",
|
||||||
error, strerror(error));
|
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);
|
fclose(hd_src);
|
||||||
return -1;
|
return TEST_ERR_FSTAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
res_global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
if(res) {
|
||||||
fclose(hd_src);
|
fclose(hd_src);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((curl = curl_easy_init()) == NULL) {
|
easy_init(curl);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
fclose(hd_src);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enable uploading */
|
/* enable uploading */
|
||||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
|
|
||||||
/* specify target */
|
/* specify target */
|
||||||
test_setopt(curl,CURLOPT_URL, URL);
|
easy_setopt(curl,CURLOPT_URL, URL);
|
||||||
|
|
||||||
/* go verbose */
|
/* go verbose */
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
/* use active FTP */
|
/* use active FTP */
|
||||||
test_setopt(curl, CURLOPT_FTPPORT, "-");
|
easy_setopt(curl, CURLOPT_FTPPORT, "-");
|
||||||
|
|
||||||
/* now specify which file to upload */
|
/* 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
|
/* 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
|
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
|
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
|
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
|
||||||
make sure that to pass in a type 'long' argument. */
|
make sure that to pass in a type 'long' argument. */
|
||||||
test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
|
||||||
(curl_off_t)file_info.st_size);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
multi_init(m);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_global_cleanup();
|
|
||||||
fclose(hd_src);
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
multi_add_handle(m, curl);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
for(;;) {
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while (!done) {
|
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
done = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
if(!running)
|
||||||
fprintf(stderr, "not okay???\n");
|
break; /* done */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 189;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 195;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = CURLM_CALL_MULTI_PERFORM;
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
}
|
|
||||||
|
|
||||||
if (ml_timedout || mp_timedout) {
|
abort_on_test_timeout();
|
||||||
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:
|
test_cleanup:
|
||||||
|
|
||||||
#ifdef LIB529
|
#ifdef LIB529
|
||||||
/* test 529 */
|
/* test 529 */
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, curl);
|
curl_multi_remove_handle(m, curl);
|
||||||
curl_multi_cleanup(m);
|
curl_multi_cleanup(m);
|
||||||
}
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
|
curl_global_cleanup();
|
||||||
#else
|
#else
|
||||||
/* test 525 */
|
/* test 525 */
|
||||||
if(m)
|
/* proper cleanup sequence - type PB */
|
||||||
curl_multi_remove_handle(m, curl);
|
curl_multi_remove_handle(m, curl);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
if(m)
|
curl_multi_cleanup(m);
|
||||||
curl_multi_cleanup(m);
|
curl_global_cleanup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fclose(hd_src); /* close the local file */
|
/* close the local file */
|
||||||
|
fclose(hd_src);
|
||||||
|
|
||||||
curl_global_cleanup();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
#define NUM_HANDLES 4
|
#define NUM_HANDLES 4
|
||||||
|
|
||||||
@ -56,109 +55,51 @@ int test(char *URL)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl[NUM_HANDLES];
|
CURL *curl[NUM_HANDLES];
|
||||||
int running;
|
int running;
|
||||||
char done=FALSE;
|
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int current=0;
|
int current = 0;
|
||||||
int i, j;
|
int i;
|
||||||
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) {
|
for(i=0; i < NUM_HANDLES; i++)
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
curl[i] = NULL;
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
start_test_timing();
|
||||||
|
|
||||||
|
global_init(CURL_GLOBAL_ALL);
|
||||||
|
|
||||||
/* get NUM_HANDLES easy handles */
|
/* get NUM_HANDLES easy handles */
|
||||||
for(i=0; i < NUM_HANDLES; i++) {
|
for(i=0; i < NUM_HANDLES; i++) {
|
||||||
curl[i] = curl_easy_init();
|
easy_init(curl[i]);
|
||||||
if(!curl[i]) {
|
/* specify target */
|
||||||
fprintf(stderr, "curl_easy_init() failed "
|
easy_setopt(curl[i], CURLOPT_URL, URL);
|
||||||
"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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go verbose */
|
/* go verbose */
|
||||||
res = curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl[current])) != CURLM_OK) {
|
multi_add_handle(m, curl[current]);
|
||||||
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();
|
|
||||||
|
|
||||||
fprintf(stderr, "Start at URL 0\n");
|
fprintf(stderr, "Start at URL 0\n");
|
||||||
|
|
||||||
while (!done) {
|
for(;;) {
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
if(!running) {
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
#ifdef LIB527
|
#ifdef LIB527
|
||||||
/* NOTE: this code does not remove the handle from the multi handle
|
/* NOTE: this code does not remove the handle from the multi handle
|
||||||
here, which would be the nice, sane and documented way of working.
|
here, which would be the nice, sane and documented way of working.
|
||||||
This however tests that the API survives this abuse gracefully. */
|
This however tests that the API survives this abuse gracefully. */
|
||||||
curl_easy_cleanup(curl[current]);
|
curl_easy_cleanup(curl[current]);
|
||||||
|
curl[current] = NULL;
|
||||||
#endif
|
#endif
|
||||||
if(++current < NUM_HANDLES) {
|
if(++current < NUM_HANDLES) {
|
||||||
fprintf(stderr, "Advancing to URL %d\n", current);
|
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
|
/* make us re-use the same handle all the time, and try resetting
|
||||||
the handle first too */
|
the handle first too */
|
||||||
curl_easy_reset(curl[0]);
|
curl_easy_reset(curl[0]);
|
||||||
test_setopt(curl[0], CURLOPT_URL, URL);
|
easy_setopt(curl[0], CURLOPT_URL, URL);
|
||||||
test_setopt(curl[0], CURLOPT_VERBOSE, 1L);
|
/* go verbose */
|
||||||
|
easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
/* re-add it */
|
/* re-add it */
|
||||||
res = (int)curl_multi_add_handle(m, curl[0]);
|
multi_add_handle(m, curl[0]);
|
||||||
#else
|
#else
|
||||||
res = (int)curl_multi_add_handle(m, curl[current]);
|
multi_add_handle(m, curl[current]);
|
||||||
#endif
|
#endif
|
||||||
if(res) {
|
|
||||||
fprintf(stderr, "add handle failed: %d.\n", res);
|
|
||||||
res = 243;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
done = TRUE; /* bail out */
|
break; /* done */
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
|
||||||
fprintf(stderr, "not okay???\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 189;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 195;
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
break;
|
|
||||||
}
|
abort_on_test_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
test_cleanup:
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef LIB527
|
#if defined(LIB526)
|
||||||
/* get NUM_HANDLES easy handles */
|
|
||||||
|
/* test 526 and 528 */
|
||||||
|
/* proper cleanup sequence - type PB */
|
||||||
|
|
||||||
for(i=0; i < NUM_HANDLES; i++) {
|
for(i=0; i < NUM_HANDLES; i++) {
|
||||||
#ifdef LIB526
|
curl_multi_remove_handle(m, curl[i]);
|
||||||
if(m)
|
|
||||||
curl_multi_remove_handle(m, curl[i]);
|
|
||||||
#endif
|
|
||||||
curl_easy_cleanup(curl[i]);
|
curl_easy_cleanup(curl[i]);
|
||||||
}
|
}
|
||||||
#endif
|
curl_multi_cleanup(m);
|
||||||
if(m)
|
|
||||||
curl_multi_cleanup(m);
|
|
||||||
|
|
||||||
curl_global_cleanup();
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
#define NUM_HANDLES 4
|
#define NUM_HANDLES 4
|
||||||
|
|
||||||
@ -35,169 +34,71 @@ int test(char *URL)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl[NUM_HANDLES];
|
CURL *curl[NUM_HANDLES];
|
||||||
int running;
|
int running;
|
||||||
char done=FALSE;
|
CURLM *m = NULL;
|
||||||
CURLM *m;
|
int i;
|
||||||
int i, j;
|
|
||||||
struct timeval ml_start;
|
|
||||||
struct timeval mp_start;
|
|
||||||
char ml_timedout = FALSE;
|
|
||||||
char mp_timedout = FALSE;
|
|
||||||
char target_url[256];
|
char target_url[256];
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
for(i=0; i < NUM_HANDLES; i++)
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
curl[i] = NULL;
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
global_init(CURL_GLOBAL_ALL);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
multi_init(m);
|
||||||
|
|
||||||
/* get NUM_HANDLES easy handles */
|
/* get NUM_HANDLES easy handles */
|
||||||
for(i=0; i < NUM_HANDLES; i++) {
|
for(i=0; i < NUM_HANDLES; i++) {
|
||||||
curl[i] = curl_easy_init();
|
/* get an easy handle */
|
||||||
if(!curl[i]) {
|
easy_init(curl[i]);
|
||||||
fprintf(stderr, "curl_easy_init() failed "
|
/* specify target */
|
||||||
"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;
|
|
||||||
}
|
|
||||||
sprintf(target_url, "%s%04i", URL, i + 1);
|
sprintf(target_url, "%s%04i", URL, i + 1);
|
||||||
target_url[sizeof(target_url) - 1] = '\0';
|
target_url[sizeof(target_url) - 1] = '\0';
|
||||||
|
easy_setopt(curl[i], CURLOPT_URL, target_url);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* go verbose */
|
/* go verbose */
|
||||||
res = curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* include headers */
|
/* include headers */
|
||||||
res = curl_easy_setopt(curl[i], CURLOPT_HEADER, 1L);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add handle to multi */
|
/* add handle to multi */
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl[i])) != CURLM_OK) {
|
multi_add_handle(m, curl[i]);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi_setopt(m, CURLMOPT_PIPELINING, 1L);
|
multi_setopt(m, CURLMOPT_PIPELINING, 1L);
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
fprintf(stderr, "Start at URL 0\n");
|
fprintf(stderr, "Start at URL 0\n");
|
||||||
|
|
||||||
while (!done) {
|
for(;;) {
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
done = TRUE; /* bail out */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
if(!running)
|
||||||
fprintf(stderr, "not okay???\n");
|
break; /* done */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 189;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 195;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = CURLM_CALL_MULTI_PERFORM;
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
|
|
||||||
|
abort_on_test_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ml_timedout || mp_timedout) {
|
test_cleanup:
|
||||||
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: */
|
/* proper cleanup sequence - type PB */
|
||||||
|
|
||||||
/* cleanup NUM_HANDLES easy handles */
|
|
||||||
for(i=0; i < NUM_HANDLES; i++) {
|
for(i=0; i < NUM_HANDLES; i++) {
|
||||||
curl_multi_remove_handle(m, curl[i]);
|
curl_multi_remove_handle(m, curl[i]);
|
||||||
curl_easy_cleanup(curl[i]);
|
curl_easy_cleanup(curl[i]);
|
||||||
|
@ -29,81 +29,45 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl;
|
CURL *curl = NULL;
|
||||||
int running;
|
int running;
|
||||||
char done=FALSE;
|
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int current=0;
|
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) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((curl = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
easy_init(curl);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1);
|
|
||||||
test_setopt(curl, CURLOPT_FAILONERROR, 1);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
easy_setopt(curl, CURLOPT_URL, URL);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
curl_easy_cleanup(curl);
|
easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
multi_add_handle(m, curl);
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
fprintf(stderr, "Start at URL 0\n");
|
fprintf(stderr, "Start at URL 0\n");
|
||||||
|
|
||||||
while (!done) {
|
for(;;) {
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
if(!running) {
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
if(!current++) {
|
if(!current++) {
|
||||||
fprintf(stderr, "Advancing to URL 1\n");
|
fprintf(stderr, "Advancing to URL 1\n");
|
||||||
/* remove the handle we use */
|
/* remove the handle we use */
|
||||||
@ -112,62 +76,36 @@ int test(char *URL)
|
|||||||
/* make us re-use the same handle all the time, and try resetting
|
/* make us re-use the same handle all the time, and try resetting
|
||||||
the handle first too */
|
the handle first too */
|
||||||
curl_easy_reset(curl);
|
curl_easy_reset(curl);
|
||||||
test_setopt(curl, CURLOPT_URL, libtest_arg2);
|
easy_setopt(curl, CURLOPT_URL, libtest_arg2);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1);
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
test_setopt(curl, CURLOPT_FAILONERROR, 1);
|
easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||||
|
|
||||||
/* re-add it */
|
/* re-add it */
|
||||||
res = (int)curl_multi_add_handle(m, curl);
|
multi_add_handle(m, curl);
|
||||||
if(res) {
|
|
||||||
fprintf(stderr, "add handle failed: %d.\n", res);
|
|
||||||
res = 243;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
done = TRUE; /* bail out */
|
break; /* done */
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
|
||||||
fprintf(stderr, "not okay???\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 189;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 195;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = CURLM_CALL_MULTI_PERFORM;
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
}
|
|
||||||
|
|
||||||
if (ml_timedout || mp_timedout) {
|
abort_on_test_timeout();
|
||||||
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:
|
test_cleanup:
|
||||||
|
|
||||||
|
/* undocumented cleanup sequence - type UB */
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
if(m)
|
curl_multi_cleanup(m);
|
||||||
curl_multi_cleanup(m);
|
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -27,118 +27,111 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
static CURLMcode perform(CURLM * multi)
|
static int perform(CURLM *multi)
|
||||||
{
|
{
|
||||||
int handles;
|
int handles;
|
||||||
CURLMcode code;
|
|
||||||
fd_set fdread, fdwrite, fdexcep;
|
fd_set fdread, fdwrite, fdexcep;
|
||||||
struct timeval mp_start;
|
int res = 0;
|
||||||
char mp_timedout = FALSE;
|
|
||||||
|
|
||||||
mp_timedout = FALSE;
|
for(;;) {
|
||||||
mp_start = tutil_tvnow();
|
struct timeval interval;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
for (;;) {
|
interval.tv_sec = 0;
|
||||||
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
|
interval.tv_usec = 100000L; /* 100 ms */
|
||||||
int maxfd = -1;
|
|
||||||
|
|
||||||
code = curl_multi_perform(multi, &handles);
|
res_multi_perform(multi, &handles);
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
if(res)
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
return res;
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (handles <= 0)
|
|
||||||
return CURLM_OK;
|
|
||||||
|
|
||||||
switch (code) {
|
res_test_timedout();
|
||||||
case CURLM_OK:
|
if(res)
|
||||||
break;
|
return res;
|
||||||
default:
|
|
||||||
return code;
|
if(!handles)
|
||||||
}
|
break; /* done */
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
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
|
res_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
function calls. On success, the value of maxfd is guaranteed to be
|
if(res)
|
||||||
greater or equal than -1. We call select(maxfd + 1, ...), specially in
|
return res;
|
||||||
case of (maxfd == -1), we call select(0, ...), which is basically equal
|
|
||||||
to sleep. */
|
|
||||||
|
|
||||||
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1)
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
return (CURLMcode) ~CURLM_OK;
|
|
||||||
|
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) */
|
return 0; /* success */
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURLM *multi;
|
CURLM *multi = NULL;
|
||||||
CURL *easy;
|
CURL *easy = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
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) {
|
res = perform(multi);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
if(res) {
|
||||||
curl_global_cleanup();
|
printf("retrieve 1 failed\n");
|
||||||
return TEST_ERR_MAJOR_BAD;
|
goto test_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((easy = curl_easy_init()) == NULL) {
|
curl_multi_remove_handle(multi, easy);
|
||||||
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)
|
|
||||||
printf("retrieve 1 failed\n");
|
|
||||||
|
|
||||||
curl_multi_remove_handle(multi, easy);
|
|
||||||
}
|
|
||||||
curl_easy_reset(easy);
|
curl_easy_reset(easy);
|
||||||
|
|
||||||
test_setopt(easy, CURLOPT_FAILONERROR, 1L);
|
easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
|
||||||
test_setopt(easy, CURLOPT_URL, libtest_arg2);
|
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");
|
printf("curl_multi_add_handle() 2 failed\n");
|
||||||
res = TEST_ERR_MAJOR_BAD;
|
goto test_cleanup;
|
||||||
} else {
|
|
||||||
if (perform(multi) != CURLM_OK)
|
|
||||||
printf("retrieve 2 failed\n");
|
|
||||||
|
|
||||||
curl_multi_remove_handle(multi, easy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = perform(multi);
|
||||||
|
if(res) {
|
||||||
|
printf("retrieve 2 failed\n");
|
||||||
|
goto test_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_remove_handle(multi, easy);
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
|
/* undocumented cleanup sequence - type UB */
|
||||||
|
|
||||||
curl_easy_cleanup(easy);
|
curl_easy_cleanup(easy);
|
||||||
curl_multi_cleanup(multi);
|
curl_multi_cleanup(multi);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
@ -30,105 +30,111 @@
|
|||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "testutil.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
|
|
||||||
#define PROXY libtest_arg2
|
#define PROXY libtest_arg2
|
||||||
#define PROXYUSERPWD libtest_arg3
|
#define PROXYUSERPWD libtest_arg3
|
||||||
#define HOST test_argv[4]
|
#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)
|
struct curl_slist *headers)
|
||||||
{
|
{
|
||||||
int res;
|
int res = 0;
|
||||||
|
|
||||||
if ((eh = curl_easy_init()) == NULL) {
|
res_easy_init(eh[num]);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
goto init_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_URL, url);
|
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_PROXY, PROXY);
|
res_easy_setopt(eh[num], CURLOPT_URL, url);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_PROXYUSERPWD, userpwd);
|
res_easy_setopt(eh[num], CURLOPT_PROXY, PROXY);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
res_easy_setopt(eh[num], CURLOPT_PROXYUSERPWD, userpwd);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_VERBOSE, 1L);
|
res_easy_setopt(eh[num], CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_HEADER, 1L);
|
res_easy_setopt(eh[num], CURLOPT_VERBOSE, 1L);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
res = curl_easy_setopt(eh, CURLOPT_HTTPHEADER, headers); /* custom Host: */
|
res_easy_setopt(eh[num], CURLOPT_HEADER, 1L);
|
||||||
if(res)
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(cm, eh)) != CURLM_OK) {
|
res_easy_setopt(eh[num], CURLOPT_HTTPHEADER, headers); /* custom Host: */
|
||||||
fprintf(stderr, "curl_multi_add_handle() failed, with code %d\n", res);
|
if(res)
|
||||||
|
goto init_failed;
|
||||||
|
|
||||||
|
res_multi_add_handle(cm, eh[num]);
|
||||||
|
if(res)
|
||||||
goto init_failed;
|
goto init_failed;
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
|
|
||||||
init_failed:
|
init_failed:
|
||||||
if(eh) {
|
|
||||||
curl_easy_cleanup(eh);
|
|
||||||
eh = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1; /* failure */
|
curl_easy_cleanup(eh[num]);
|
||||||
|
eh[num] = NULL;
|
||||||
|
|
||||||
|
return res; /* 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)
|
struct curl_slist *headers)
|
||||||
{
|
{
|
||||||
CURLMsg *msg;
|
CURLMsg *msg;
|
||||||
long L;
|
long L;
|
||||||
int M, Q, U = -1;
|
int Q, U = -1;
|
||||||
fd_set R, W, E;
|
fd_set R, W, E;
|
||||||
struct timeval T;
|
struct timeval T;
|
||||||
CURLMcode rc;
|
int res = 0;
|
||||||
|
|
||||||
if(init(cm, url, userpwd, headers))
|
res = init(num, cm, url, userpwd, headers);
|
||||||
return 1; /* failure */
|
if(res)
|
||||||
|
return res;
|
||||||
|
|
||||||
while (U) {
|
while (U) {
|
||||||
|
|
||||||
rc = curl_multi_perform(cm, &U);
|
int M = -99;
|
||||||
if(rc == CURLM_OUT_OF_MEMORY)
|
|
||||||
return 1; /* failure */
|
res_multi_perform(cm, &U);
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
res_test_timedout();
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
|
|
||||||
if (U) {
|
if (U) {
|
||||||
FD_ZERO(&R);
|
FD_ZERO(&R);
|
||||||
FD_ZERO(&W);
|
FD_ZERO(&W);
|
||||||
FD_ZERO(&E);
|
FD_ZERO(&E);
|
||||||
|
|
||||||
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
|
res_multi_fdset(cm, &R, &W, &E, &M);
|
||||||
fprintf(stderr, "E: curl_multi_fdset\n");
|
if(res)
|
||||||
return 1; /* failure */
|
return res;
|
||||||
}
|
|
||||||
|
|
||||||
/* In a real-world program you OF COURSE check the return that maxfd is
|
/* At this point, M is guaranteed to be greater or equal than -1. */
|
||||||
bigger than -1 so that the call to select() below makes sense! */
|
|
||||||
|
|
||||||
if (curl_multi_timeout(cm, &L)) {
|
res_multi_timeout(cm, &L);
|
||||||
fprintf(stderr, "E: curl_multi_timeout\n");
|
if(res)
|
||||||
return 1; /* failure */
|
return res;
|
||||||
}
|
|
||||||
|
|
||||||
if(L != -1) {
|
if(L != -1) {
|
||||||
T.tv_sec = L/1000;
|
T.tv_sec = L/1000;
|
||||||
@ -139,25 +145,33 @@ static int loop(CURLM *cm, const char* url, const char* userpwd,
|
|||||||
T.tv_usec = 0;
|
T.tv_usec = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 > select(M+1, &R, &W, &E, &T)) {
|
res_select_test(M+1, &R, &W, &E, &T);
|
||||||
fprintf(stderr, "E: select\n");
|
if(res)
|
||||||
return 1; /* failure */
|
return res;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((msg = curl_multi_info_read(cm, &Q))) {
|
while((msg = curl_multi_info_read(cm, &Q)) != NULL) {
|
||||||
if (msg->msg == CURLMSG_DONE) {
|
if(msg->msg == CURLMSG_DONE) {
|
||||||
|
int i;
|
||||||
CURL *e = msg->easy_handle;
|
CURL *e = msg->easy_handle;
|
||||||
fprintf(stderr, "R: %d - %s\n", (int)msg->data.result,
|
fprintf(stderr, "R: %d - %s\n", (int)msg->data.result,
|
||||||
curl_easy_strerror(msg->data.result));
|
curl_easy_strerror(msg->data.result));
|
||||||
curl_multi_remove_handle(cm, e);
|
curl_multi_remove_handle(cm, e);
|
||||||
curl_easy_cleanup(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);
|
fprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res_test_timedout();
|
||||||
|
if(res)
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
@ -168,7 +182,13 @@ int test(char *URL)
|
|||||||
CURLM *cm = NULL;
|
CURLM *cm = NULL;
|
||||||
struct curl_slist *headers = NULL;
|
struct curl_slist *headers = NULL;
|
||||||
char buffer[246]; /* naively fixed-size */
|
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)
|
if(test_argc < 4)
|
||||||
return 99;
|
return 99;
|
||||||
@ -182,37 +202,37 @@ int test(char *URL)
|
|||||||
return TEST_ERR_MAJOR_BAD;
|
return TEST_ERR_MAJOR_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
res_global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
if(res) {
|
||||||
curl_slist_free_all(headers);
|
curl_slist_free_all(headers);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cm = curl_multi_init()) == NULL) {
|
res_multi_init(cm);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
if(res) {
|
||||||
curl_slist_free_all(headers);
|
|
||||||
curl_global_cleanup();
|
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)
|
if(res)
|
||||||
goto test_cleanup;
|
goto test_cleanup;
|
||||||
|
|
||||||
fprintf(stderr, "lib540: now we do the request again\n");
|
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:
|
test_cleanup:
|
||||||
|
|
||||||
if(cm && eh)
|
/* proper cleanup sequence - type PB */
|
||||||
curl_multi_remove_handle(cm, eh);
|
|
||||||
|
|
||||||
if(eh)
|
for(i=0; i < NUM_HANDLES; i++) {
|
||||||
curl_easy_cleanup(eh);
|
curl_multi_remove_handle(cm, eh[i]);
|
||||||
|
curl_easy_cleanup(eh[i]);
|
||||||
if(cm)
|
}
|
||||||
curl_multi_cleanup(cm);
|
|
||||||
|
|
||||||
|
curl_multi_cleanup(cm);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
curl_slist_free_all(headers);
|
curl_slist_free_all(headers);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.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"
|
#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 test(char *URL)
|
||||||
{
|
{
|
||||||
int res;
|
int res = 0;
|
||||||
CURL *curl;
|
CURL *curl = NULL;
|
||||||
int counter=0;
|
int counter=0;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int running=1;
|
int running=1;
|
||||||
struct timeval mp_start;
|
|
||||||
char mp_timedout = FALSE;
|
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((curl = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
easy_init(curl);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
|
||||||
test_setopt(curl, CURLOPT_HEADER, 1L);
|
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 */
|
/* read the POST data from a callback */
|
||||||
test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
|
easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
|
||||||
test_setopt(curl, CURLOPT_IOCTLDATA, &counter);
|
easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
|
||||||
test_setopt(curl, CURLOPT_READFUNCTION, readcallback);
|
easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
|
||||||
test_setopt(curl, CURLOPT_READDATA, &counter);
|
easy_setopt(curl, CURLOPT_READDATA, &counter);
|
||||||
/* We CANNOT do the POST fine without setting the size (or choose chunked)! */
|
/* 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
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
/* Convert the POST data to ASCII. */
|
/* Convert the POST data to ASCII. */
|
||||||
test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
|
easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
|
||||||
#endif
|
#endif
|
||||||
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||||
test_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
|
easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
|
||||||
test_setopt(curl, CURLOPT_PROXYAUTH,
|
easy_setopt(curl, CURLOPT_PROXYAUTH,
|
||||||
(long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
|
(long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
multi_init(m);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
multi_add_handle(m, curl);
|
||||||
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();
|
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
|
struct timeval timeout;
|
||||||
fd_set fdread, fdwrite, fdexcep;
|
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
|
#ifdef TPF
|
||||||
sleep(1); /* avoid ctl-10 dump */
|
sleep(1); /* avoid ctl-10 dump */
|
||||||
#endif
|
#endif
|
||||||
if (running <= 0) {
|
|
||||||
fprintf(stderr, "nothing left running.\n");
|
if(!running)
|
||||||
break;
|
break; /* done */
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
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
|
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
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. */
|
|
||||||
|
|
||||||
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
res = ~CURLM_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_timedout) {
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
|
|
||||||
"that it would have run forever.\n");
|
abort_on_test_timeout();
|
||||||
res = TEST_ERR_RUNS_FOREVER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, curl);
|
|
||||||
curl_multi_cleanup(m);
|
curl_multi_remove_handle(m, curl);
|
||||||
}
|
curl_multi_cleanup(m);
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
|
#include "testutil.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simply download a HTTPS file!
|
* Simply download a HTTPS file!
|
||||||
*
|
*
|
||||||
@ -36,43 +39,44 @@
|
|||||||
*/
|
*/
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL *http_handle;
|
CURL *http_handle = NULL;
|
||||||
CURLM *multi_handle = NULL;
|
CURLM *multi_handle = NULL;
|
||||||
int res;
|
int res = 0;
|
||||||
|
|
||||||
int still_running; /* keep number of running handles */
|
int still_running; /* keep number of running handles */
|
||||||
|
|
||||||
http_handle = curl_easy_init();
|
start_test_timing();
|
||||||
if (!http_handle)
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
/*
|
||||||
|
** curl_global_init called indirectly from curl_easy_init.
|
||||||
|
*/
|
||||||
|
|
||||||
|
easy_init(http_handle);
|
||||||
|
|
||||||
/* set options */
|
/* set options */
|
||||||
test_setopt(http_handle, CURLOPT_URL, URL);
|
easy_setopt(http_handle, CURLOPT_URL, URL);
|
||||||
test_setopt(http_handle, CURLOPT_HEADER, 1L);
|
easy_setopt(http_handle, CURLOPT_HEADER, 1L);
|
||||||
test_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
test_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
easy_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||||
|
|
||||||
/* init a multi stack */
|
/* init a multi stack */
|
||||||
multi_handle = curl_multi_init();
|
multi_init(multi_handle);
|
||||||
if (!multi_handle) {
|
|
||||||
curl_easy_cleanup(http_handle);
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the individual transfers */
|
/* 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 */
|
/* 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) {
|
while(still_running) {
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int rc; /* select() return code */
|
|
||||||
|
|
||||||
fd_set fdread;
|
fd_set fdread;
|
||||||
fd_set fdwrite;
|
fd_set fdwrite;
|
||||||
fd_set fdexcep;
|
fd_set fdexcep;
|
||||||
int maxfd;
|
int maxfd = -99;
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
@ -83,31 +87,25 @@ int test(char *URL)
|
|||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
/* get file descriptors from the transfers */
|
/* 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
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
function calls, *and* you make sure that maxfd is bigger than -1 so
|
|
||||||
that the call to select() below makes sense! */
|
|
||||||
|
|
||||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
|
|
||||||
switch(rc) {
|
abort_on_test_timeout();
|
||||||
case -1:
|
|
||||||
/* select error */
|
/* timeout or readable/writable sockets */
|
||||||
break;
|
multi_perform(multi_handle, &still_running);
|
||||||
case 0:
|
|
||||||
default:
|
abort_on_test_timeout();
|
||||||
/* timeout or readable/writable sockets */
|
|
||||||
(void) curl_multi_perform(multi_handle, &still_running);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
if(multi_handle)
|
/* undocumented cleanup sequence - type UA */
|
||||||
curl_multi_cleanup(multi_handle);
|
|
||||||
|
|
||||||
|
curl_multi_cleanup(multi_handle);
|
||||||
curl_easy_cleanup(http_handle);
|
curl_easy_cleanup(http_handle);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -27,121 +27,66 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl;
|
CURL *curl = NULL;
|
||||||
int running;
|
int running;
|
||||||
char done=FALSE;
|
|
||||||
CURLM *m = NULL;
|
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) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((curl = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
easy_init(curl);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1);
|
|
||||||
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
|
||||||
test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
easy_setopt(curl, CURLOPT_URL, URL);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
curl_easy_cleanup(curl);
|
easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||||
curl_global_cleanup();
|
easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
multi_add_handle(m, curl);
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
fprintf(stderr, "Start at URL 0\n");
|
fprintf(stderr, "Start at URL 0\n");
|
||||||
|
|
||||||
while (!done) {
|
for(;;) {
|
||||||
fd_set rd, wr, exc;
|
|
||||||
int max_fd;
|
|
||||||
struct timeval interval;
|
struct timeval interval;
|
||||||
|
fd_set rd, wr, exc;
|
||||||
|
int maxfd = -99;
|
||||||
|
|
||||||
interval.tv_sec = 1;
|
interval.tv_sec = 1;
|
||||||
interval.tv_usec = 0;
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
multi_perform(m, &running);
|
||||||
MAIN_LOOP_HANG_TIMEOUT) {
|
|
||||||
ml_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mp_timedout = FALSE;
|
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
abort_on_test_timeout();
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (running <= 0) {
|
|
||||||
done = TRUE; /* bail out */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != CURLM_OK) {
|
if(!running)
|
||||||
fprintf(stderr, "not okay???\n");
|
break; /* done */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_ZERO(&wr);
|
FD_ZERO(&wr);
|
||||||
FD_ZERO(&exc);
|
FD_ZERO(&exc);
|
||||||
max_fd = 0;
|
|
||||||
|
|
||||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
multi_fdset(m, &rd, &wr, &exc, &maxfd);
|
||||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
|
||||||
res = 189;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
fprintf(stderr, "bad select??\n");
|
|
||||||
res = 195;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ml_timedout || mp_timedout) {
|
select_test(maxfd+1, &rd, &wr, &exc, &interval);
|
||||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
|
||||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
abort_on_test_timeout();
|
||||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
|
||||||
"that it would have run forever.\n");
|
|
||||||
res = TEST_ERR_RUNS_FOREVER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
|
/* undocumented cleanup sequence - type UB */
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
if(m)
|
curl_multi_cleanup(m);
|
||||||
curl_multi_cleanup(m);
|
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -25,8 +25,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a single URL without select().
|
* Get a single URL without select().
|
||||||
@ -34,84 +33,51 @@
|
|||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURL *c;
|
CURL *c = NULL;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int running=1;
|
int running = 1;
|
||||||
double connect_time = 0.0;
|
double connect_time = 0.0;
|
||||||
struct timeval mp_start;
|
|
||||||
char mp_timedout = FALSE;
|
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((c = curl_easy_init()) == NULL) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(c, CURLOPT_HEADER, 1L);
|
easy_init(c);
|
||||||
test_setopt(c, CURLOPT_URL, URL);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
easy_setopt(c, CURLOPT_HEADER, 1L);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
easy_setopt(c, CURLOPT_URL, URL);
|
||||||
curl_easy_cleanup(c);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
|
multi_init(m);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_timedout = FALSE;
|
multi_add_handle(m, c);
|
||||||
mp_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
|
struct timeval timeout;
|
||||||
fd_set fdread, fdwrite, fdexcep;
|
fd_set fdread, fdwrite, fdexcep;
|
||||||
int maxfd = -1;
|
int maxfd = -99;
|
||||||
|
|
||||||
res = (int)curl_multi_perform(m, &running);
|
timeout.tv_sec = 0;
|
||||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
timeout.tv_usec = 100000L; /* 100 ms */
|
||||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
|
||||||
mp_timedout = TRUE;
|
multi_perform(m, &running);
|
||||||
break;
|
|
||||||
}
|
abort_on_test_timeout();
|
||||||
if (running <= 0) {
|
|
||||||
fprintf(stderr, "nothing left running.\n");
|
if(!running)
|
||||||
break;
|
break; /* done */
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fdread);
|
FD_ZERO(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
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
|
multi_fdset(m, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
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. */
|
|
||||||
|
|
||||||
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) == -1) {
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
res = ~CURLM_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mp_timedout) {
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
fprintf(stderr, "mp_timedout\nABORTING TEST, since it seems "
|
|
||||||
"that it would have run forever.\n");
|
abort_on_test_timeout();
|
||||||
res = TEST_ERR_RUNS_FOREVER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time);
|
curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time);
|
||||||
@ -122,10 +88,10 @@ int test(char *URL)
|
|||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
if(m) {
|
/* proper cleanup sequence - type PA */
|
||||||
curl_multi_remove_handle(m, c);
|
|
||||||
curl_multi_cleanup(m);
|
curl_multi_remove_handle(m, c);
|
||||||
}
|
curl_multi_cleanup(m);
|
||||||
curl_easy_cleanup(c);
|
curl_easy_cleanup(c);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
|
|
||||||
/* 3x download!
|
/* 3x download!
|
||||||
* 1. normal
|
* 1. normal
|
||||||
* 2. dup handle
|
* 2. dup handle
|
||||||
@ -35,26 +37,21 @@
|
|||||||
|
|
||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
CURLMcode m;
|
CURL *handle = NULL;
|
||||||
CURL *handle = NULL, *duphandle;
|
CURL *duphandle = NULL;
|
||||||
CURLM *mhandle = NULL;
|
CURLM *mhandle = NULL;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int still_running = 0;
|
int still_running = 0;
|
||||||
|
|
||||||
if(curl_global_init(CURL_GLOBAL_ALL)) {
|
start_test_timing();
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
goto test_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle = curl_easy_init();
|
global_init(CURL_GLOBAL_ALL);
|
||||||
if(!handle) {
|
|
||||||
res = CURLE_OUT_OF_MEMORY;
|
|
||||||
goto test_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(handle, CURLOPT_URL, URL);
|
easy_init(handle);
|
||||||
test_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
|
||||||
test_setopt(handle, CURLOPT_VERBOSE, 1L);
|
easy_setopt(handle, CURLOPT_URL, URL);
|
||||||
|
easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
||||||
|
easy_setopt(handle, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
res = curl_easy_perform(handle);
|
res = curl_easy_perform(handle);
|
||||||
if(res)
|
if(res)
|
||||||
@ -70,49 +67,48 @@ int test(char *URL)
|
|||||||
curl_easy_cleanup(handle);
|
curl_easy_cleanup(handle);
|
||||||
handle = duphandle;
|
handle = duphandle;
|
||||||
|
|
||||||
mhandle = curl_multi_init();
|
multi_init(mhandle);
|
||||||
if(!mhandle) {
|
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
goto test_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
while(still_running) {
|
||||||
static struct timeval timeout = /* 100 ms */ { 0, 100000L };
|
struct timeval timeout;
|
||||||
int rc;
|
|
||||||
fd_set fdread;
|
fd_set fdread;
|
||||||
fd_set fdwrite;
|
fd_set fdwrite;
|
||||||
fd_set fdexcep;
|
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(&fdread);
|
||||||
FD_ZERO(&fdwrite);
|
FD_ZERO(&fdwrite);
|
||||||
FD_ZERO(&fdexcep);
|
FD_ZERO(&fdexcep);
|
||||||
|
|
||||||
m = curl_multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &max_fdset);
|
multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
if(m != CURLM_OK) {
|
|
||||||
fprintf(stderr, "curl_multi_fdset() error\n");
|
/* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
goto test_cleanup;
|
|
||||||
}
|
select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
/* We call select(max_fdset + 1, ...), specially in case of (maxfd == -1),
|
|
||||||
* we call select(0, ...), which is basically equal to sleep. */
|
abort_on_test_timeout();
|
||||||
rc = select(max_fdset + 1, &fdread, &fdwrite, &fdexcep, &timeout);
|
|
||||||
if(rc == -1) {
|
multi_perform(mhandle, &still_running);
|
||||||
fprintf(stderr, "select() error\n");
|
|
||||||
goto test_cleanup;
|
abort_on_test_timeout();
|
||||||
}
|
|
||||||
else {
|
|
||||||
curl_multi_perform(mhandle, &still_running);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
if(mhandle)
|
|
||||||
curl_multi_cleanup(mhandle);
|
/* undocumented cleanup sequence - type UA */
|
||||||
if(handle)
|
|
||||||
curl_easy_cleanup(handle);
|
curl_multi_cleanup(mhandle);
|
||||||
|
curl_easy_cleanup(handle);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#define MAIN_LOOP_HANG_TIMEOUT 4 * 1000
|
#define TEST_HANG_TIMEOUT 60 * 1000
|
||||||
|
|
||||||
struct Sockets
|
struct Sockets
|
||||||
{
|
{
|
||||||
@ -226,30 +226,30 @@ static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset,
|
|||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
CURL *curl;
|
CURL *curl = NULL;
|
||||||
FILE *hd_src ;
|
FILE *hd_src = NULL;
|
||||||
int hd ;
|
int hd ;
|
||||||
int error;
|
int error;
|
||||||
struct_stat file_info;
|
struct_stat file_info;
|
||||||
CURLM *m = NULL;
|
CURLM *m = NULL;
|
||||||
struct timeval ml_start;
|
|
||||||
char ml_timedout = FALSE;
|
|
||||||
struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
|
struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}};
|
||||||
struct timeval timeout = {-1, 0};
|
struct timeval timeout = {-1, 0};
|
||||||
int success = 0;
|
int success = 0;
|
||||||
|
|
||||||
|
start_test_timing();
|
||||||
|
|
||||||
if (!libtest_arg3) {
|
if (!libtest_arg3) {
|
||||||
fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n");
|
fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n");
|
||||||
return -1;
|
return TEST_ERR_USAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hd_src = fopen(libtest_arg2, "rb");
|
hd_src = fopen(libtest_arg2, "rb");
|
||||||
if(NULL == hd_src) {
|
if(NULL == hd_src) {
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
fprintf(stderr, "fopen() failed with error: %d %s\n",
|
fprintf(stderr, "fopen() failed with error: %d (%s)\n",
|
||||||
error, strerror(error));
|
error, strerror(error));
|
||||||
fprintf(stderr, "Error opening file: %s\n", libtest_arg2);
|
fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
return TEST_ERR_FOPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the file size of the local file */
|
/* get the file size of the local file */
|
||||||
@ -257,71 +257,49 @@ int test(char *URL)
|
|||||||
if(hd == -1) {
|
if(hd == -1) {
|
||||||
/* can't open file, bail out */
|
/* can't open file, bail out */
|
||||||
error = ERRNO;
|
error = ERRNO;
|
||||||
fprintf(stderr, "fstat() failed with error: %d %s\n",
|
fprintf(stderr, "fstat() failed with error: %d (%s)\n",
|
||||||
error, strerror(error));
|
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);
|
fclose(hd_src);
|
||||||
return -1;
|
return TEST_ERR_FSTAT;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size);
|
fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size);
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
res_global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
if(res) {
|
||||||
fclose(hd_src);
|
fclose(hd_src);
|
||||||
return TEST_ERR_MAJOR_BAD;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((curl = curl_easy_init()) == NULL) {
|
easy_init(curl);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
fclose(hd_src);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enable uploading */
|
/* enable uploading */
|
||||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
|
|
||||||
/* specify target */
|
/* specify target */
|
||||||
test_setopt(curl,CURLOPT_URL, URL);
|
easy_setopt(curl,CURLOPT_URL, URL);
|
||||||
|
|
||||||
/* go verbose */
|
/* go verbose */
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
/* now specify which file to upload */
|
/* 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);
|
easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3);
|
||||||
test_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
|
easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
|
||||||
test_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
|
easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
|
||||||
(curl_off_t)file_info.st_size);
|
|
||||||
|
|
||||||
if ((m = curl_multi_init()) == NULL) {
|
multi_init(m);
|
||||||
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);
|
|
||||||
|
|
||||||
test_multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
|
multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback);
|
||||||
test_multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
|
multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets);
|
||||||
|
|
||||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback);
|
||||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
multi_setopt(m, CURLMOPT_TIMERDATA, &timeout);
|
||||||
"with code %d\n", res);
|
|
||||||
curl_multi_cleanup(m);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
curl_global_cleanup();
|
|
||||||
fclose(hd_src);
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
ml_timedout = FALSE;
|
multi_add_handle(m, curl);
|
||||||
ml_start = tutil_tvnow();
|
|
||||||
|
|
||||||
while (!checkForCompletion(m, &success))
|
while (!checkForCompletion(m, &success))
|
||||||
{
|
{
|
||||||
@ -329,12 +307,6 @@ int test(char *URL)
|
|||||||
curl_socket_t maxFd = 0;
|
curl_socket_t maxFd = 0;
|
||||||
struct timeval tv = {10, 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(&readSet);
|
||||||
FD_ZERO(&writeSet);
|
FD_ZERO(&writeSet);
|
||||||
updateFdSet(&sockets.read, &readSet, &maxFd);
|
updateFdSet(&sockets.read, &readSet, &maxFd);
|
||||||
@ -363,6 +335,8 @@ int test(char *URL)
|
|||||||
/* Curl's timer has elapsed. */
|
/* Curl's timer has elapsed. */
|
||||||
notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout");
|
notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abort_on_test_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
@ -370,28 +344,24 @@ int test(char *URL)
|
|||||||
fprintf(stderr, "Error uploading file.\n");
|
fprintf(stderr, "Error uploading file.\n");
|
||||||
res = TEST_ERR_MAJOR_BAD;
|
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:
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(hd_src); /* close the local file */
|
curl_multi_remove_handle(m, curl);
|
||||||
if (sockets.read.sockets)
|
curl_easy_cleanup(curl);
|
||||||
|
curl_multi_cleanup(m);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
/* close the local file */
|
||||||
|
fclose(hd_src);
|
||||||
|
|
||||||
|
/* free local memory */
|
||||||
|
if(sockets.read.sockets)
|
||||||
free(sockets.read.sockets);
|
free(sockets.read.sockets);
|
||||||
if (sockets.write.sockets)
|
if(sockets.write.sockets)
|
||||||
free(sockets.write.sockets);
|
free(sockets.write.sockets);
|
||||||
|
|
||||||
curl_global_cleanup();
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -33,58 +33,36 @@
|
|||||||
int test(char *URL)
|
int test(char *URL)
|
||||||
{
|
{
|
||||||
int stillRunning;
|
int stillRunning;
|
||||||
CURLM* multiHandle;
|
CURLM* multiHandle = NULL;
|
||||||
CURL* curl;
|
CURL* curl = NULL;
|
||||||
int res1 = 0;
|
int res = 0;
|
||||||
int res;
|
|
||||||
|
|
||||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
global_init(CURL_GLOBAL_ALL);
|
||||||
fprintf(stderr, "curl_global_init() failed\n");
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((multiHandle = curl_multi_init()) == NULL) {
|
multi_init(multiHandle);
|
||||||
fprintf(stderr, "curl_multi_init() failed\n");
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((curl = curl_easy_init()) == NULL) {
|
easy_init(curl);
|
||||||
fprintf(stderr, "curl_easy_init() failed\n");
|
|
||||||
curl_multi_cleanup(multiHandle);
|
|
||||||
curl_global_cleanup();
|
|
||||||
return TEST_ERR_MAJOR_BAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_USERPWD, libtest_arg2);
|
easy_setopt(curl, CURLOPT_USERPWD, libtest_arg2);
|
||||||
test_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
|
easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub");
|
||||||
test_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
|
easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key");
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_UPLOAD, 1);
|
easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
test_setopt(curl, CURLOPT_VERBOSE, 1);
|
easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
easy_setopt(curl, CURLOPT_URL, URL);
|
||||||
test_setopt(curl, CURLOPT_INFILESIZE, (long)5);
|
easy_setopt(curl, CURLOPT_INFILESIZE, (long)5);
|
||||||
|
|
||||||
if((res = (int)curl_multi_add_handle(multiHandle, curl)) != CURLM_OK) {
|
multi_add_handle(multiHandle, curl);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this tests if removing an easy handle immediately after multi
|
/* this tests if removing an easy handle immediately after multi
|
||||||
perform has been called succeeds or not. */
|
perform has been called succeeds or not. */
|
||||||
|
|
||||||
fprintf(stderr, "curl_multi_perform()...\n");
|
fprintf(stderr, "curl_multi_perform()...\n");
|
||||||
res1 = (int) curl_multi_perform(multiHandle, &stillRunning);
|
|
||||||
if(res1)
|
multi_perform(multiHandle, &stillRunning);
|
||||||
fprintf(stderr, "curl_multi_perform() failed, "
|
|
||||||
"with code %d\n", res1);
|
fprintf(stderr, "curl_multi_perform() succeeded\n");
|
||||||
else
|
|
||||||
fprintf(stderr, "curl_multi_perform() succeeded\n");
|
|
||||||
|
|
||||||
fprintf(stderr, "curl_multi_remove_handle()...\n");
|
fprintf(stderr, "curl_multi_remove_handle()...\n");
|
||||||
res = (int) curl_multi_remove_handle(multiHandle, curl);
|
res = (int) curl_multi_remove_handle(multiHandle, curl);
|
||||||
@ -96,12 +74,11 @@ int test(char *URL)
|
|||||||
|
|
||||||
test_cleanup:
|
test_cleanup:
|
||||||
|
|
||||||
|
/* undocumented cleanup sequence - type UB */
|
||||||
|
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_multi_cleanup(multiHandle);
|
curl_multi_cleanup(multiHandle);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
if(res)
|
return res;
|
||||||
return res;
|
|
||||||
else
|
|
||||||
return res1;
|
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,6 @@
|
|||||||
# include "select.h"
|
# include "select.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEST_ERR_MAJOR_BAD 100
|
|
||||||
#define TEST_ERR_RUNS_FOREVER 99
|
|
||||||
|
|
||||||
#define test_setopt(A,B,C) \
|
#define test_setopt(A,B,C) \
|
||||||
if((res = curl_easy_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup
|
if((res = curl_easy_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup
|
||||||
|
|
||||||
@ -66,8 +63,10 @@ extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */
|
|||||||
extern int test_argc;
|
extern int test_argc;
|
||||||
extern char **test_argv;
|
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 */
|
||||||
struct timeval *tv);
|
|
||||||
|
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
|
extern int test(char *URL); /* the actual test function provided by each
|
||||||
individual libXXX.c file */
|
individual libXXX.c file */
|
||||||
@ -75,3 +74,331 @@ extern int test(char *URL); /* the actual test function provided by each
|
|||||||
#ifdef UNITTESTS
|
#ifdef UNITTESTS
|
||||||
extern int unitfail;
|
extern int unitfail;
|
||||||
#endif
|
#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__))
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- */
|
||||||
|
Loading…
Reference in New Issue
Block a user