Commit 629d2e34 authored by Yang Tse's avatar Yang Tse
Browse files

multi tests: OOM handling fixes

Additionally, improved error checking and logging.
parent 90fcad63
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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>
+2 −3
Original line number Original line Diff line number Diff line
@@ -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
+3 −3
Original line number Original line Diff line number Diff line
@@ -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)


+14 −6
Original line number Original line Diff line number Diff line
@@ -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
+33 −67
Original line number Original line Diff line number Diff line
@@ -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;
    select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
    }
  }


  if (mp_timedout) {
    abort_on_test_timeout();
    fprintf(stderr, "mp_timedout\nABORTING 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_remove_handle(m, c);
  curl_multi_cleanup(m);
  curl_multi_cleanup(m);
  }
  curl_easy_cleanup(c);
  curl_easy_cleanup(c);
  curl_global_cleanup();
  curl_global_cleanup();


Loading