gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] 02/02: test_quiesce: added more checking and error repor


From: gnunet
Subject: [libmicrohttpd] 02/02: test_quiesce: added more checking and error reporting
Date: Mon, 10 Jan 2022 20:48:09 +0100

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit 14a46d9c0958f7e3ac481af5175d6c53dd614ee7
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Mon Jan 10 22:47:46 2022 +0300

    test_quiesce: added more checking and error reporting
---
 src/testcurl/Makefile.am     |   2 +-
 src/testcurl/mhd_has_param.h |  53 ++++
 src/testcurl/test_quiesce.c  | 576 ++++++++++++++++++++++++++-----------------
 3 files changed, 403 insertions(+), 228 deletions(-)

diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 5d7839f1..3d9f6000 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -186,7 +186,7 @@ test_get_SOURCES = \
   test_get.c
 
 test_quiesce_SOURCES = \
-  test_quiesce.c
+  test_quiesce.c mhd_has_param.h mhd_has_in_name.h
 test_quiesce_CFLAGS = \
   $(PTHREAD_CFLAGS) $(AM_CFLAGS)
 test_quiesce_LDADD = \
diff --git a/src/testcurl/mhd_has_param.h b/src/testcurl/mhd_has_param.h
new file mode 100644
index 00000000..0186b5de
--- /dev/null
+++ b/src/testcurl/mhd_has_param.h
@@ -0,0 +1,53 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2016-2022 Karlson2k (Evgeny Grin)
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+*/
+
+/**
+ * @file testcurl/mhd_has_param.h
+ * @brief Static functions and macros helpers for testsuite.
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include <string.h>
+
+
+/**
+ * Check whether one of strings in array is equal to @a param.
+ * String @a argv[0] is ignored.
+ * @param argc number of strings in @a argv, as passed to main function
+ * @param argv array of strings, as passed to main function
+ * @param param parameter to look for.
+ * @return zero if @a argv is NULL, @a param is NULL or empty string,
+ *         @a argc is less then 2 or @a param is not found in @a argv,
+ *         non-zero if one of strings in @a argv is equal to @a param.
+ */
+static int
+has_param (int argc, char *const argv[], const char *param)
+{
+  int i;
+  if (! argv || ! param || ! param[0])
+    return 0;
+
+  for (i = 1; i < argc; i++)
+  {
+    if (argv[i] && (strcmp (argv[i], param) == 0) )
+      return ! 0;
+  }
+
+  return 0;
+}
diff --git a/src/testcurl/test_quiesce.c b/src/testcurl/test_quiesce.c
index 33d34dd5..8b350237 100644
--- a/src/testcurl/test_quiesce.c
+++ b/src/testcurl/test_quiesce.c
@@ -1,7 +1,7 @@
 /*
      This file is part of libmicrohttpd
      Copyright (C) 2013, 2015 Christian Grothoff
-     Copyright (C) 2014-2021 Evgeny Grin (Karlson2k)
+     Copyright (C) 2014-2022 Evgeny Grin (Karlson2k)
 
      libmicrohttpd is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -35,6 +35,8 @@
 #include <sys/types.h>
 #include <pthread.h>
 #include "mhd_sockets.h" /* only macros used */
+#include "mhd_has_in_name.h"
+#include "mhd_has_param.h"
 
 
 #ifndef WINDOWS
@@ -50,6 +52,120 @@
 #endif
 
 
+#if defined(HAVE___FUNC__)
+#define externalErrorExit(ignore) \
+    _externalErrorExit_func(NULL, __func__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+    _externalErrorExit_func(errDesc, __func__, __LINE__)
+#define libcurlErrorExit(ignore) \
+    _libcurlErrorExit_func(NULL, __func__, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+    _libcurlErrorExit_func(errDesc, __func__, __LINE__)
+#define mhdErrorExit(ignore) \
+    _mhdErrorExit_func(NULL, __func__, __LINE__)
+#define mhdErrorExitDesc(errDesc) \
+    _mhdErrorExit_func(errDesc, __func__, __LINE__)
+#elif defined(HAVE___FUNCTION__)
+#define externalErrorExit(ignore) \
+    _externalErrorExit_func(NULL, __FUNCTION__, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+    _externalErrorExit_func(errDesc, __FUNCTION__, __LINE__)
+#define libcurlErrorExit(ignore) \
+    _libcurlErrorExit_func(NULL, __FUNCTION__, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+    _libcurlErrorExit_func(errDesc, __FUNCTION__, __LINE__)
+#define mhdErrorExit(ignore) \
+    _mhdErrorExit_func(NULL, __FUNCTION__, __LINE__)
+#define mhdErrorExitDesc(errDesc) \
+    _mhdErrorExit_func(errDesc, __FUNCTION__, __LINE__)
+#else
+#define externalErrorExit(ignore) _externalErrorExit_func(NULL, NULL, __LINE__)
+#define externalErrorExitDesc(errDesc) \
+  _externalErrorExit_func(errDesc, NULL, __LINE__)
+#define libcurlErrorExit(ignore) _libcurlErrorExit_func(NULL, NULL, __LINE__)
+#define libcurlErrorExitDesc(errDesc) \
+  _libcurlErrorExit_func(errDesc, NULL, __LINE__)
+#define mhdErrorExit(ignore) _mhdErrorExit_func(NULL, NULL, __LINE__)
+#define mhdErrorExitDesc(errDesc) _mhdErrorExit_func(errDesc, NULL, __LINE__)
+#endif
+
+
+_MHD_NORETURN static void
+_externalErrorExit_func (const char *errDesc, const char *funcName, int 
lineNum)
+{
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "System or external library call failed");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+#ifdef MHD_WINSOCK_SOCKETS
+  fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ());
+#endif /* MHD_WINSOCK_SOCKETS */
+  fflush (stderr);
+  exit (99);
+}
+
+
+static char libcurl_errbuf[CURL_ERROR_SIZE] = "";
+
+_MHD_NORETURN static void
+_libcurlErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "CURL library call failed");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+  if (0 != libcurl_errbuf[0])
+    fprintf (stderr, "Last libcurl error details: %s\n", libcurl_errbuf);
+
+  fflush (stderr);
+  exit (99);
+}
+
+
+_MHD_NORETURN static void
+_mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum)
+{
+  if ((NULL != errDesc) && (0 != errDesc[0]))
+    fprintf (stderr, "%s", errDesc);
+  else
+    fprintf (stderr, "MHD unexpected error");
+  if ((NULL != funcName) && (0 != funcName[0]))
+    fprintf (stderr, " in %s", funcName);
+  if (0 < lineNum)
+    fprintf (stderr, " at line %d", lineNum);
+
+  fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno,
+           strerror (errno));
+
+  fflush (stderr);
+  exit (8);
+}
+
+
+/* Could be increased to facilitate debugging */
+#define TIMEOUTS_VAL 4
+
+#define MHD_URI_BASE_PATH "/hello_world"
+
+/* Global parameters */
+static int verbose;                 /**< Be verbose */
+static int oneone;                  /**< If false use HTTP/1.0 for requests*/
+static int global_port;             /**< MHD daemons listen port number */
+
 struct CBC
 {
   char *buf;
@@ -57,8 +173,6 @@ struct CBC
   size_t size;
 };
 
-static int port;
-
 static size_t
 copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
 {
@@ -84,11 +198,13 @@ ahc_echo (void *cls,
   static int ptr;
   const char *me = cls;
   struct MHD_Response *response;
-  enum MHD_Result ret;
   (void) version; (void) upload_data; (void) upload_data_size;       /* 
Unused. Silent compiler warning. */
 
   if (0 != strcmp (me, method))
-    return MHD_NO;              /* unexpected method */
+  {
+    fprintf (stderr, "Unexpected HTTP method '%s'. ", method);
+    externalErrorExit ();
+  }
   if (&ptr != *unused)
   {
     *unused = &ptr;
@@ -98,11 +214,16 @@ ahc_echo (void *cls,
   response = MHD_create_response_from_buffer (strlen (url),
                                               (void *) url,
                                               MHD_RESPMEM_MUST_COPY);
-  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  if (NULL == response)
+    mhdErrorExitDesc ("MHD_create_response failed");
+  /* Make sure that connection will not be reused */
+  if (MHD_NO == MHD_add_response_header (response, MHD_HTTP_HEADER_CONNECTION,
+                                         "close"))
+    mhdErrorExitDesc ("MHD_add_response_header() failed");
+  if (MHD_NO == MHD_queue_response (connection, MHD_HTTP_OK, response))
+    mhdErrorExitDesc ("MHD_queue_response() failed");
   MHD_destroy_response (response);
-  if (ret == MHD_NO)
-    abort ();
-  return ret;
+  return MHD_YES;
 }
 
 
@@ -112,7 +233,14 @@ request_completed (void *cls, struct MHD_Connection 
*connection,
 {
   int *done = (int *) cls;
   (void) connection; (void) con_cls; (void) code;    /* Unused. Silent 
compiler warning. */
+  if (MHD_REQUEST_TERMINATED_COMPLETED_OK != code)
+  {
+    fprintf (stderr, "Unexpected termination code: %d. ", (int) code);
+    mhdErrorExit ();
+  }
   *done = 1;
+  if (verbose)
+    printf ("Notify callback has been called with OK code.\n");
 }
 
 
@@ -126,9 +254,12 @@ ServeOneRequest (void *param)
   MHD_socket fd, max;
   time_t start;
   struct timeval tv;
-  int done = 0;
+  volatile int done = 0;
+
+  if (NULL == param)
+    externalErrorExit ();
 
-  fd = (MHD_socket) (intptr_t) param;
+  fd = *((MHD_socket *) param);
 
   d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                         0, NULL, NULL, &ahc_echo, "GET",
@@ -136,47 +267,44 @@ ServeOneRequest (void *param)
                         MHD_OPTION_NOTIFY_COMPLETED, &request_completed, &done,
                         MHD_OPTION_END);
   if (d == NULL)
-    return "MHD_start_daemon() failed";
+    mhdErrorExit ();
+
+  if (verbose)
+    printf ("Started MHD daemon in ServeOneRequest().\n");
 
   start = time (NULL);
-  while ((time (NULL) - start < 5) && done == 0)
+  while ((time (NULL) - start < TIMEOUTS_VAL * 2) && done == 0)
   {
     max = 0;
     FD_ZERO (&rs);
     FD_ZERO (&ws);
     FD_ZERO (&es);
     if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
-    {
-      MHD_stop_daemon (d);
-      MHD_socket_close_chk_ (fd);
-      return "MHD_get_fdset() failed";
-    }
+      mhdErrorExit ("MHD_get_fdset() failed");
     tv.tv_sec = 0;
-    tv.tv_usec = 1000;
+    tv.tv_usec = 100000;
     if (-1 == MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv))
     {
 #ifdef MHD_POSIX_SOCKETS
       if (EINTR != errno)
-        abort ();
+        externalErrorExitDesc ("Unexpected select() error");
 #else
-      if ((WSAEINVAL != WSAGetLastError ()) || (0 != rs.fd_count) || (0 !=
-                                                                      ws.
-                                                                      fd_count)
-          || (0 != es.fd_count) )
-        abort ();
-      Sleep (1000);
+      if ((WSAEINVAL != WSAGetLastError ()) ||
+          (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
+        externalErrorExitDesc ("Unexpected select() error");
+      Sleep (tv.tv_sec * 1000 + tv.tv_usec / 1000);
 #endif
     }
     MHD_run (d);
   }
+  if (! done)
+    mhdErrorExit ("ServeOneRequest() failed and finished by timeout");
   fd = MHD_quiesce_daemon (d);
   if (MHD_INVALID_SOCKET == fd)
-  {
-    MHD_stop_daemon (d);
-    return "MHD_quiesce_daemon() failed in ServeOneRequest()";
-  }
+    mhdErrorExit ("MHD_quiesce_daemon() failed in ServeOneRequest()");
+
   MHD_stop_daemon (d);
-  return done ? NULL : "Requests was not served by ServeOneRequest()";
+  return NULL;
 }
 
 
@@ -186,19 +314,29 @@ setupCURL (void *cbc)
   CURL *c;
 
   c = curl_easy_init ();
-  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world";);
-  curl_easy_setopt (c, CURLOPT_PORT, (long) port);
-  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
-  curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc);
-  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
-  curl_easy_setopt (c, CURLOPT_TIMEOUT_MS, 150L);
-  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, 150L);
-  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
-  /* NOTE: use of CONNECTTIMEOUT without also
-     setting NOSIGNAL results in really weird
-     crashes on my system!*/
-  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
-
+  if (NULL == c)
+    libcurlErrorExitDesc ("curl_easy_init() failed");
+
+  if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL,
+                                     "http://127.0.0.1"; MHD_URI_BASE_PATH)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, (long) global_port)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION,
+                                     &copyBuffer)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT,
+                                     (long) (TIMEOUTS_VAL / 2))) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT,
+                                     (long) TIMEOUTS_VAL)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER,
+                                     libcurl_errbuf)) ||
+      (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L)) ||
+      ((oneone) ?
+       (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+                                      CURL_HTTP_VERSION_1_1)) :
+       (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION,
+                                      CURL_HTTP_VERSION_1_0))))
+    libcurlErrorExitDesc ("curl_easy_setopt() failed");
   return c;
 }
 
@@ -215,38 +353,37 @@ testGet (int type, int pool_count, int poll_flag)
   pthread_t thrd;
   const char *thrdRet;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1480;
+  if (verbose)
+    printf ("testGet(%d, %d, %d) test started.\n",
+            type, pool_count, poll_flag);
 
   cbc.buf = buf;
-  cbc.size = 2048;
+  cbc.size = sizeof(buf);
   cbc.pos = 0;
   if (pool_count > 0)
   {
     d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
-                          port, NULL, NULL, &ahc_echo, "GET",
-                          MHD_OPTION_THREAD_POOL_SIZE, pool_count,
+                          global_port, NULL, NULL, &ahc_echo, "GET",
+                          MHD_OPTION_THREAD_POOL_SIZE,
+                          (unsigned int) pool_count,
                           MHD_OPTION_END);
 
   }
   else
   {
     d = MHD_start_daemon (type | MHD_USE_ERROR_LOG | MHD_USE_ITC | poll_flag,
-                          port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+                          global_port, NULL, NULL, &ahc_echo, "GET",
+                          MHD_OPTION_END);
   }
   if (d == NULL)
-    return 1;
-  if (0 == port)
+    mhdErrorExitDesc ("MHD_start_daemon() failed");
+  if (0 == global_port)
   {
     const union MHD_DaemonInfo *dinfo;
     dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
     if ((NULL == dinfo) || (0 == dinfo->port) )
-    {
-      MHD_stop_daemon (d); return 32;
-    }
-    port = (int) dinfo->port;
+      mhdErrorExit ();
+    global_port = (int) dinfo->port;
   }
 
   c = setupCURL (&cbc);
@@ -254,108 +391,101 @@ testGet (int type, int pool_count, int poll_flag)
   if (CURLE_OK != (errornum = curl_easy_perform (c)))
   {
     fprintf (stderr,
-             "curl_easy_perform failed: `%s'\n",
+             "curl_easy_perform() failed: '%s'. ",
              curl_easy_strerror (errornum));
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 2;
+    libcurlErrorExit ();
   }
 
-  if (cbc.pos != strlen ("/hello_world"))
+  if (cbc.pos != strlen (MHD_URI_BASE_PATH))
   {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 4;
+    fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+             (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+             (unsigned) strlen (MHD_URI_BASE_PATH));
+    mhdErrorExitDesc ("Wrong returned data length");
   }
-  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+  if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf, strlen (MHD_URI_BASE_PATH)))
   {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 8;
+    fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos, cbc.buf);
+    mhdErrorExitDesc ("Wrong returned data");
   }
+  if (verbose)
+    printf ("Received valid response data.\n");
 
   fd = MHD_quiesce_daemon (d);
   if (MHD_INVALID_SOCKET == fd)
-  {
-    fprintf (stderr,
-             "MHD_quiesce_daemon failed.\n");
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 2;
-  }
+    mhdErrorExitDesc ("MHD_quiesce_daemon failed");
+
   if (0 != pthread_create (&thrd, NULL, &ServeOneRequest,
-                           (void *) (intptr_t) fd))
-  {
-    fprintf (stderr, "pthread_create failed\n");
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 16;
-  }
+                           (void *) &fd))
+    externalErrorExitDesc ("pthread_create() failed");
 
+  /* No need for the thread sync as socket is already listening,
+   * so libcurl may start connecting before MHD is started in another thread */
   cbc.pos = 0;
   if (CURLE_OK != (errornum = curl_easy_perform (c)))
   {
     fprintf (stderr,
-             "curl_easy_perform failed: `%s'\n",
+             "curl_easy_perform() failed: `%s'\n",
              curl_easy_strerror (errornum));
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 2;
+    mhdErrorExit ();
   }
 
-  if (0 != pthread_join (thrd, (void **) &thrdRet))
+  if (cbc.pos != strlen (MHD_URI_BASE_PATH))
   {
-    fprintf (stderr, "pthread_join failed\n");
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 16;
+    fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+             (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+             (unsigned) strlen (MHD_URI_BASE_PATH));
+    mhdErrorExitDesc ("Wrong returned data length");
   }
-  if (NULL != thrdRet)
+  if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf, strlen (MHD_URI_BASE_PATH)))
   {
-    fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 16;
+    fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos, cbc.buf);
+    mhdErrorExitDesc ("Wrong returned data");
   }
 
-  if (cbc.pos != strlen ("/hello_world"))
-  {
-    fprintf (stderr, "%s\n", cbc.buf);
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    MHD_socket_close_chk_ (fd);
-    return 4;
-  }
-  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+  if (0 != pthread_join (thrd, (void **) &thrdRet))
+    externalErrorExitDesc ("pthread_join() failed");
+  if (NULL != thrdRet)
+    externalErrorExitDesc ("ServeOneRequest() returned non-NULL result");
+
+  if (verbose)
   {
-    fprintf (stderr, "%s\n", cbc.buf);
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    MHD_socket_close_chk_ (fd);
-    return 8;
+    printf ("ServeOneRequest() thread was joined.\n");
+    fflush (stdout);
   }
 
-  /* at this point, the forked server quit, and the new
-   * server has quiesced, so new requests should fail
+  /* at this point, the forked server quiesced and quit,
+   * so new requests should fail
    */
+  cbc.pos = 0;
   if (CURLE_OK == curl_easy_perform (c))
   {
-    fprintf (stderr, "curl_easy_perform should fail\n");
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    MHD_socket_close_chk_ (fd);
-    return 2;
+    fprintf (stderr, "curl_easy_perform() succeed while it should fail. ");
+    fprintf (stderr, "Got %u bytes ('%.*s'), "
+             "valid data would be %u bytes (%s). ",
+             (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+             (unsigned) strlen (MHD_URI_BASE_PATH), MHD_URI_BASE_PATH);
+    mhdErrorExitDesc ("Unexpected succeed request");
   }
+  if (verbose)
+    printf ("curl_easy_perform() failed as expected.\n");
   curl_easy_cleanup (c);
   MHD_stop_daemon (d);
   MHD_socket_close_chk_ (fd);
 
+  if (verbose)
+  {
+    printf ("testGet(%d, %d, %d) test succeed.\n",
+            type, pool_count, poll_flag);
+    fflush (stdout);
+  }
+
   return 0;
 }
 
 
 static int
-testExternalGet ()
+testExternalGet (void)
 {
   struct MHD_Daemon *d;
   CURL *c;
@@ -366,12 +496,6 @@ testExternalGet ()
   fd_set rs;
   fd_set ws;
   fd_set es;
-  MHD_socket maxsock;
-#ifdef MHD_WINSOCK_SOCKETS
-  int maxposixs; /* Max socket number unused on W32 */
-#else  /* MHD_POSIX_SOCKETS */
-#define maxposixs maxsock
-#endif /* MHD_POSIX_SOCKETS */
   int running;
   struct CURLMsg *msg;
   time_t start;
@@ -379,56 +503,48 @@ testExternalGet ()
   int i;
   MHD_socket fd;
 
-  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
-    port = 0;
-  else
-    port = 1481;
+  if (verbose)
+    printf ("testExternalGet test started.\n");
 
+  fd = MHD_INVALID_SOCKET;
   multi = NULL;
   cbc.buf = buf;
-  cbc.size = 2048;
+  cbc.size = sizeof(buf);
   cbc.pos = 0;
   d = MHD_start_daemon (MHD_USE_ERROR_LOG,
-                        port,
+                        global_port,
                         NULL, NULL,
                         &ahc_echo, "GET",
                         MHD_OPTION_END);
   if (d == NULL)
-    return 256;
-  if (0 == port)
+    mhdErrorExitDesc ("Failed to start MHD daemon");
+  if (0 == global_port)
   {
     const union MHD_DaemonInfo *dinfo;
     dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
     if ((NULL == dinfo) || (0 == dinfo->port) )
-    {
-      MHD_stop_daemon (d); return 32;
-    }
-    port = (int) dinfo->port;
-  }
-  c = setupCURL (&cbc);
-
-  multi = curl_multi_init ();
-  if (multi == NULL)
-  {
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 512;
-  }
-  mret = curl_multi_add_handle (multi, c);
-  if (mret != CURLM_OK)
-  {
-    curl_multi_cleanup (multi);
-    curl_easy_cleanup (c);
-    MHD_stop_daemon (d);
-    return 1024;
+      mhdErrorExit ();
+    global_port = (int) dinfo->port;
   }
 
   for (i = 0; i < 2; i++)
   {
+    c = setupCURL (&cbc);
+
+    multi = curl_multi_init ();
+    if (multi == NULL)
+      libcurlErrorExit ();
+
+    mret = curl_multi_add_handle (multi, c);
+    if (mret != CURLM_OK)
+      libcurlErrorExit ();
+
     start = time (NULL);
-    while ( (time (NULL) - start < 5) &&
+    while ( (time (NULL) - start < TIMEOUTS_VAL * 2) &&
             (NULL != multi) )
     {
+      MHD_socket maxsock;
+      int maxposixs;
       maxsock = MHD_INVALID_SOCKET;
       maxposixs = -1;
       FD_ZERO (&rs);
@@ -437,44 +553,26 @@ testExternalGet ()
       curl_multi_perform (multi, &running);
       mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
       if (mret != CURLM_OK)
-      {
-        curl_multi_remove_handle (multi, c);
-        curl_multi_cleanup (multi);
-        curl_easy_cleanup (c);
-        MHD_stop_daemon (d);
-        return 2048;
-      }
+        libcurlErrorExit ();
       if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
-      {
-        curl_multi_remove_handle (multi, c);
-        curl_multi_cleanup (multi);
-        curl_easy_cleanup (c);
-        MHD_stop_daemon (d);
-        return 4096;
-      }
+        mhdErrorExit ();
+#ifndef MHD_WINSOCK_SOCKETS
+      if (maxsock > maxposixs)
+        maxposixs = maxsock;
+#endif /* MHD_POSIX_SOCKETS */
       tv.tv_sec = 0;
-      tv.tv_usec = 1000;
+      tv.tv_usec = 100000;
       if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
       {
-  #ifdef MHD_POSIX_SOCKETS
+#ifdef MHD_POSIX_SOCKETS
         if (EINTR != errno)
-        {
-          fprintf (stderr, "Unexpected select() error: %d. Line: %d\n",
-                   (int) errno, __LINE__);
-          fflush (stderr);
-          exit (99);
-        }
-  #else
+          externalErrorExitDesc ("Unexpected select() error");
+#else
         if ((WSAEINVAL != WSAGetLastError ()) ||
             (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) )
-        {
-          fprintf (stderr, "Unexpected select() error: %d. Line: %d\n",
-                   (int) WSAGetLastError (), __LINE__);
-          fflush (stderr);
-          exit (99);
-        }
-        Sleep (1);
-  #endif
+          externalErrorExitDesc ("Unexpected select() error");
+        Sleep (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+#endif
       }
       curl_multi_perform (multi, &running);
       if (0 == running)
@@ -486,26 +584,57 @@ testExternalGet ()
           if (msg->msg == CURLMSG_DONE)
           {
             if (msg->data.result == CURLE_OK)
+            {
               curl_fine = 1;
+              if (verbose)
+                printf ("libcurl reported success.\n");
+            }
             else if (i == 0)
             {
               fprintf (stderr,
-                       "%s failed at %s:%d: `%s'\n",
-                       "curl_multi_perform",
-                       __FILE__,
-                       __LINE__, curl_easy_strerror (msg->data.result));
+                       "curl_multi_perform() failed with '%s'. ",
+                       curl_easy_strerror (msg->data.result));
+              mhdErrorExit ();
             }
           }
         }
-        if ((i == 0) && (! curl_fine))
+        if (i == 0)
         {
-          fprintf (stderr, "libcurl haven't returned OK code\n");
-          abort ();
+          if (! curl_fine)
+          {
+            fprintf (stderr, "libcurl haven't returned OK code\n");
+            mhdErrorExit ();
+          }
+          /* MHD is running, result should be correct */
+          if (cbc.pos != strlen (MHD_URI_BASE_PATH))
+          {
+            fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ",
+                     (unsigned) cbc.pos, (int) cbc.pos, cbc.buf,
+                     (unsigned) strlen (MHD_URI_BASE_PATH));
+            mhdErrorExitDesc ("Wrong returned data length");
+          }
+          if (0 != strncmp (MHD_URI_BASE_PATH, cbc.buf,
+                            strlen (MHD_URI_BASE_PATH)))
+          {
+            fprintf (stderr, "Got invalid response '%.*s'. ", (int) cbc.pos,
+                     cbc.buf);
+            mhdErrorExitDesc ("Wrong returned data");
+          }
+          if (verbose)
+          {
+            printf ("First request was successful.\n");
+            fflush (stdout);
+          }
         }
-        else if ((i == 1) && (curl_fine))
+        else if (i == 1)
         {
-          fprintf (stderr, "libcurl returned OK code, while it shouldn't\n");
-          abort ();
+          if  (curl_fine)
+          {
+            fprintf (stderr, "libcurl returned OK code, while it shouldn't\n");
+            mhdErrorExit ();
+          }
+          if (verbose)
+            printf ("Second request failed as expected.\n");
         }
         curl_multi_remove_handle (multi, c);
         curl_multi_cleanup (multi);
@@ -517,45 +646,31 @@ testExternalGet ()
       MHD_run (d);
     }
 
+    if (NULL != multi)
+      mhdErrorExitDesc ("Test failed and finished by timeout");
+
     if (0 == i)
     {
       /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
       fd = MHD_quiesce_daemon (d);
       if (MHD_INVALID_SOCKET == fd)
-      {
-        fprintf (stderr,
-                 "MHD_quiesce_daemon failed.\n");
-        curl_multi_remove_handle (multi, c);
-        curl_multi_cleanup (multi);
-        curl_easy_cleanup (c);
-        MHD_stop_daemon (d);
-        return 2;
-      }
-      c = setupCURL (&cbc);
-      multi = curl_multi_init ();
-      mret = curl_multi_add_handle (multi, c);
-      if (mret != CURLM_OK)
-      {
-        curl_multi_remove_handle (multi, c);
-        curl_multi_cleanup (multi);
-        curl_easy_cleanup (c);
-        MHD_stop_daemon (d);
-        return 32768;
-      }
+        mhdErrorExitDesc ("MHD_quiesce_daemon() failed");
     }
   }
-  if (NULL != multi)
+  MHD_stop_daemon (d);
+  if (MHD_INVALID_SOCKET == fd)
   {
-    curl_multi_remove_handle (multi, c);
-    curl_easy_cleanup (c);
-    curl_multi_cleanup (multi);
+    fprintf (stderr, "Failed to MHD_quiesce_daemon() at some point. ");
+    externalErrorExit ();
   }
-  MHD_stop_daemon (d);
   MHD_socket_close_chk_ (fd);
-  if (cbc.pos != strlen ("/hello_world"))
-    return 8192;
-  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
-    return 16384;
+
+  if (verbose)
+  {
+    printf ("testExternalGet succeed.\n");
+    fflush (stdout);
+  }
+
   return 0;
 }
 
@@ -564,10 +679,17 @@ int
 main (int argc, char *const *argv)
 {
   unsigned int errorCount = 0;
-  (void) argc; (void) argv; /* Unused. Silent compiler warning. */
+  oneone = ! has_in_name (argv[0], "10");
+  verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv, 
"--quiet");
 
   if (0 != curl_global_init (CURL_GLOBAL_WIN32))
     return 2;
+
+  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+    global_port = 0;
+  else
+    global_port = 1480 + (oneone ? 1 : 0);
+
   errorCount += testExternalGet ();
   if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
   {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]