[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 02/02: Added tests for cleanup of unprocessed externally
From: |
gnunet |
Subject: |
[libmicrohttpd] 02/02: Added tests for cleanup of unprocessed externally added connections |
Date: |
Sun, 25 Oct 2020 15:26:25 +0100 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit fa330be735a39d30f4e025c3afdba192e6c2b1bb
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Sun Oct 25 00:43:23 2020 +0300
Added tests for cleanup of unprocessed externally added connections
---
src/testcurl/.gitignore | 2 +
src/testcurl/Makefile.am | 22 +++++
src/testcurl/test_add_conn.c | 211 ++++++++++++++++++++++++++++++++++---------
3 files changed, 190 insertions(+), 45 deletions(-)
diff --git a/src/testcurl/.gitignore b/src/testcurl/.gitignore
index 4c1c7f03..0ca3ac3c 100644
--- a/src/testcurl/.gitignore
+++ b/src/testcurl/.gitignore
@@ -113,4 +113,6 @@ test_patch
test_patch11
/test_add_conn
/test_add_conn_nolisten
+/test_add_conn_cleanup
+/test_add_conn_cleanup_nolisten
core
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index f45f13d3..6587c79a 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -23,6 +23,8 @@ THREAD_ONLY_TESTS = \
test_long_header11 \
test_iplimit11 \
test_termination \
+ test_add_conn_cleanup \
+ test_add_conn_cleanup_nolisten \
test_timeout
if HAVE_POSIX_THREADS
@@ -276,16 +278,36 @@ test_put_chunked_LDADD = \
test_add_conn_SOURCES = \
test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
test_add_conn_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
test_add_conn_nolisten_SOURCES = \
test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_nolisten_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
test_add_conn_nolisten_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_add_conn_cleanup_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_cleanup_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_cleanup_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_add_conn_cleanup_nolisten_SOURCES = \
+ test_add_conn.c $(top_srcdir)/src/microhttpd/test_helpers.h
+test_add_conn_cleanup_nolisten_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_add_conn_cleanup_nolisten_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
test_get11_SOURCES = \
test_get.c
test_get11_LDADD = \
diff --git a/src/testcurl/test_add_conn.c b/src/testcurl/test_add_conn.c
index 52aa2831..c7e49b91 100644
--- a/src/testcurl/test_add_conn.c
+++ b/src/testcurl/test_add_conn.c
@@ -57,6 +57,11 @@
#if ! defined(CPU_COUNT)
#define CPU_COUNT 2
#endif
+#if CPU_COUNT > 32
+#undef CPU_COUNT
+/* Limit to reasonable value */
+#define CPU_COUNT 32
+#endif /* CPU_COUNT > 32 */
/* Could be increased to facilitate debugging */
#define TIMEOUTS_VAL 5
@@ -65,9 +70,16 @@
#define EXPECTED_URI_QUERY "a=%26&b=c"
#define EXPECTED_URI_FULL_PATH EXPECTED_URI_BASE_PATH "?" EXPECTED_URI_QUERY
-static int oneone;
-static int no_listen;
-static int global_port;
+/* Global parameters */
+static int oneone; /**< Use HTTP/1.1 instead of HTTP/1.0 */
+static int no_listen; /**< Start MHD daemons without listen socket */
+static int global_port; /**< MHD deamons listen port number */
+static int cleanup_test; /**< Test for final cleanup */
+static int slow_reply = 0; /**< Slowdown MHD replies */
+static int ignore_response_errors = 0; /**< Do not fail test if CURL
+ returns error */
+static int response_timeout_val = TIMEOUTS_VAL;
+
struct CBC
{
@@ -165,6 +177,9 @@ ahc_echo (void *cls,
NULL == v ? "NULL" : v);
_exit (19);
}
+ if (slow_reply)
+ usleep (200000);
+
response = MHD_create_response_from_buffer (strlen (url),
(void *) url,
MHD_RESPMEM_MUST_COPY);
@@ -401,8 +416,8 @@ curlEasyInitForTest (const char *queryPath, int port,
struct CBC *pcbc)
curl_easy_setopt (c, CURLOPT_PORT, (long) port);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc);
- curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, (long) TIMEOUTS_VAL);
- curl_easy_setopt (c, CURLOPT_TIMEOUT, (long) TIMEOUTS_VAL);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, (long) response_timeout_val);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, (long) response_timeout_val);
curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
if (oneone)
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@@ -434,6 +449,11 @@ doCurlQueryInThread (struct curlQueryParams *p)
c = curlEasyInitForTest (p->queryPath, p->queryPort, &cbc);
errornum = curl_easy_perform (c);
+ if (ignore_response_errors)
+ {
+ p->queryError = 0;
+ return p->queryError;
+ }
if (CURLE_OK != errornum)
{
fprintf (stderr,
@@ -511,11 +531,11 @@ performTestQueries (struct MHD_Daemon *d, int d_port)
{
struct curlQueryParams qParam;
struct addConnParam aParam;
- int a_port = 0; /* Additional listening socket port */
- int ret = 0; /* Return value */
+ int a_port; /* Additional listening socket port */
+ int ret = 0; /* Return value */
qParam.queryPath = "http://127.0.0.1" EXPECTED_URI_FULL_PATH;
- qParam.queryPort = 0; /* autoassign */
+ a_port = 0; /* auto-assign */
aParam.d = d;
aParam.lstn_sk = createListeningSocket (&a_port); /* Sets a_port */
@@ -550,6 +570,59 @@ performTestQueries (struct MHD_Daemon *d, int d_port)
}
+/* Perform test for cleanup and shutdown MHD daemon */
+static int
+performTestCleanup (struct MHD_Daemon *d, int num_queries)
+{
+ struct curlQueryParams *qParamList;
+ struct addConnParam aParam;
+ MHD_socket lstn_sk; /* Additional listening socket */
+ int a_port; /* Additional listening socket port */
+ int i;
+ int ret = 0; /* Return value */
+
+ a_port = 0; /* auto-assign */
+
+ if (0 >= num_queries)
+ abort (); /* Test's API violation */
+
+ lstn_sk = createListeningSocket (&a_port); /* Sets a_port */
+
+ qParamList = malloc (sizeof(struct curlQueryParams) * num_queries);
+ if (NULL == qParamList)
+ externalErrorExitDesc ("malloc failed");
+
+ /* Start CURL queries */
+ for (i = 0; i < num_queries; i++)
+ {
+ qParamList[i].queryPath = "http://127.0.0.1" EXPECTED_URI_FULL_PATH;
+ qParamList[i].queryError = 0;
+ qParamList[i].queryPort = a_port;
+
+ startThreadCurlQuery (qParamList + i);
+ }
+
+ /* Accept and add required number of client sockets */
+ aParam.d = d;
+ aParam.lstn_sk = lstn_sk;
+ for (i = 0; i < num_queries; i++)
+ ret |= doAcceptAndAddConnInThread (&aParam);
+
+ /* Stop daemon while some of new connection are not yet
+ * processed because of slow response to the first queries. */
+ MHD_stop_daemon (d);
+ (void) MHD_socket_close_ (aParam.lstn_sk);
+
+ /* Wait for CURL threads to complete. */
+ /* Ignore soft CURL errors as many connection shouldn't get any response.
+ * Hard failures are detected in processing function. */
+ for (i = 0; i < num_queries; i++)
+ (void) finishThreadCurlQuery (qParamList + i);
+
+ return ret;
+}
+
+
#endif /* HAVE_PTHREAD_H */
enum testMhdThreadsType
@@ -578,7 +651,15 @@ startTestMhdDaemon (enum testMhdThreadsType thrType,
if ( (0 == *pport) &&
(MHD_NO == MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
)
- *pport = oneone ? 1550 : 1570;
+ {
+ *pport = 1550;
+ if (oneone)
+ *pport += 1;
+ if (no_listen)
+ *pport += 2;
+ if (cleanup_test)
+ *pport += 4;
+ }
if (testMhdThreadInternalPool != thrType)
d = MHD_start_daemon (((int) thrType) | ((int) pollType)
@@ -656,6 +737,10 @@ testExternalGet (void)
cbc_a.size = sizeof(buf_a);
cbc_a.pos = 0;
+ if (cleanup_test)
+ abort (); /* Not possible with "external poll" as connections are directly
+ added to the daemon processing in the mode. */
+
if (! no_listen)
c_d = curlEasyInitForTest ("http://127.0.0.1" EXPECTED_URI_FULL_PATH,
d_port, &cbc_d);
@@ -828,6 +913,8 @@ testInternalGet (enum testMhdPollType pollType)
d = startTestMhdDaemon (testMhdThreadInternal, pollType,
&d_port);
+ if (cleanup_test)
+ return performTestCleanup (d, 10);
return performTestQueries (d, d_port);
}
@@ -841,6 +928,10 @@ testMultithreadedGet (enum testMhdPollType pollType)
d = startTestMhdDaemon (testMhdThreadInternalPerConnection, pollType,
&d_port);
+ if (cleanup_test)
+ abort (); /* Cannot be tested as main daemon thread cannot be slowed down
+ by slow responses, so it processes all new connections before
+ daemon could be stopped. */
return performTestQueries (d, d_port);
}
@@ -855,6 +946,9 @@ testMultithreadedPoolGet (enum testMhdPollType pollType)
d = startTestMhdDaemon (testMhdThreadInternalPool, pollType,
&d_port);
+ if (cleanup_test)
+ return performTestCleanup (d, 10 * CPU_COUNT);
+
return performTestQueries (d, d_port);
}
@@ -930,19 +1024,40 @@ main (int argc, char *const *argv)
if ((NULL == argv) || (0 == argv[0]))
return 99;
oneone = has_in_name (argv[0], "11");
+ /* Whether to test MHD daemons without listening socket. */
no_listen = has_in_name (argv[0], "_nolisten");
+ /* Whether to test for correct final cleanup instead of
+ * of test of normal processing. */
+ cleanup_test = has_in_name (argv[0], "_cleanup");
+ /* There are almost nothing that could be tested externally
+ * for final cleanup. Cleanup test actually just tests that
+ * nothing fails or crashes when final cleanup is performed.
+ * Mostly useful when configured with '--enable-asserts. */
+ slow_reply = cleanup_test;
+ ignore_response_errors = cleanup_test;
+ if (cleanup_test)
+ response_timeout_val /= 5;
+ if (0 == response_timeout_val)
+ response_timeout_val = 1;
+#ifndef HAVE_PTHREAD_H
+ if (cleanup_test)
+ return 77; /* Cannot run without threads */
+#endif /* HAVE_PTHREAD_H */
verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv,
"--quiet");
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
/* Could be set to non-zero value to enforce using specific port
* in the test */
global_port = 0;
- test_result = testExternalGet ();
- if (test_result)
- fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
- else if (verbose)
- printf ("PASSED: testExternalGet ().\n");
- errorCount += test_result;
+ if (! cleanup_test)
+ {
+ test_result = testExternalGet ();
+ if (test_result)
+ fprintf (stderr, "FAILED: testExternalGet () - %u.\n", test_result);
+ else if (verbose)
+ printf ("PASSED: testExternalGet ().\n");
+ errorCount += test_result;
+ }
#ifdef HAVE_PTHREAD_H
if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_THREADS))
{
@@ -953,14 +1068,6 @@ main (int argc, char *const *argv)
else if (verbose)
printf ("PASSED: testInternalGet (testMhdPollBySelect).\n");
errorCount += test_result;
- test_result = testMultithreadedGet (testMhdPollBySelect);
- if (test_result)
- fprintf (stderr,
- "FAILED: testMultithreadedGet (testMhdPollBySelect) - %u.\n",
- test_result);
- else if (verbose)
- printf ("PASSED: testMultithreadedGet (testMhdPollBySelect).\n");
- errorCount += test_result;
test_result = testMultithreadedPoolGet (testMhdPollBySelect);
if (test_result)
fprintf (stderr,
@@ -969,45 +1076,59 @@ main (int argc, char *const *argv)
else if (verbose)
printf ("PASSED: testMultithreadedPoolGet (testMhdPollBySelect).\n");
errorCount += test_result;
- test_result = testStopRace (testMhdPollBySelect);
- if (test_result)
- fprintf (stderr, "FAILED: testStopRace (testMhdPollBySelect) - %u.\n",
- test_result);
- else if (verbose)
- printf ("PASSED: testStopRace (testMhdPollBySelect).\n");
- errorCount += test_result;
- if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ if (! cleanup_test)
{
- test_result = testInternalGet (testMhdPollByPoll);
+ test_result = testMultithreadedGet (testMhdPollBySelect);
if (test_result)
- fprintf (stderr, "FAILED: testInternalGet (testMhdPollByPoll) - %u.\n",
+ fprintf (stderr,
+ "FAILED: testMultithreadedGet (testMhdPollBySelect) - %u.\n",
test_result);
else if (verbose)
- printf ("PASSED: testInternalGet (testMhdPollByPoll).\n");
+ printf ("PASSED: testMultithreadedGet (testMhdPollBySelect).\n");
errorCount += test_result;
- test_result = testMultithreadedGet (testMhdPollByPoll);
+ test_result = testStopRace (testMhdPollBySelect);
if (test_result)
- fprintf (stderr,
- "FAILED: testMultithreadedGet (testMhdPollByPoll) - %u.\n",
+ fprintf (stderr, "FAILED: testStopRace (testMhdPollBySelect) - %u.\n",
test_result);
else if (verbose)
- printf ("PASSED: testMultithreadedGet (testMhdPollByPoll).\n");
+ printf ("PASSED: testStopRace (testMhdPollBySelect).\n");
errorCount += test_result;
- test_result = testMultithreadedPoolGet (testMhdPollByPoll);
+ }
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_POLL))
+ {
+ test_result = testInternalGet (testMhdPollByPoll);
if (test_result)
- fprintf (stderr,
- "FAILED: testMultithreadedPoolGet (testMhdPollByPoll) -
%u.\n",
+ fprintf (stderr, "FAILED: testInternalGet (testMhdPollByPoll) - %u.\n",
test_result);
else if (verbose)
- printf ("PASSED: testMultithreadedPoolGet (testMhdPollByPoll).\n");
+ printf ("PASSED: testInternalGet (testMhdPollByPoll).\n");
errorCount += test_result;
- test_result = testStopRace (testMhdPollByPoll);
+ test_result = testMultithreadedPoolGet (testMhdPollByPoll);
if (test_result)
- fprintf (stderr, "FAILED: testStopRace (testMhdPollByPoll) - %u.\n",
+ fprintf (stderr,
+ "FAILED: testMultithreadedPoolGet (testMhdPollByPoll) -
%u.\n",
test_result);
else if (verbose)
- printf ("PASSED: testStopRace (testMhdPollByPoll).\n");
+ printf ("PASSED: testMultithreadedPoolGet (testMhdPollByPoll).\n");
errorCount += test_result;
+ if (! cleanup_test)
+ {
+ test_result = testMultithreadedGet (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr,
+ "FAILED: testMultithreadedGet (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testMultithreadedGet (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ test_result = testStopRace (testMhdPollByPoll);
+ if (test_result)
+ fprintf (stderr, "FAILED: testStopRace (testMhdPollByPoll) - %u.\n",
+ test_result);
+ else if (verbose)
+ printf ("PASSED: testStopRace (testMhdPollByPoll).\n");
+ errorCount += test_result;
+ }
}
if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
{
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.