diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2020-10-27 21:22:33 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2020-10-27 21:22:33 +0300 |
commit | eb1a0307e5c007790bf6cc4d1a7bb018c3008ccf (patch) | |
tree | 86ad0b4389f32d3f4b3f863e13717ed915a278ae /src/testcurl | |
parent | 155ac53ed4221c4af0a00e85b90a6a10a32e4c75 (diff) | |
download | libmicrohttpd-eb1a0307e5c007790bf6cc4d1a7bb018c3008ccf.tar.gz libmicrohttpd-eb1a0307e5c007790bf6cc4d1a7bb018c3008ccf.zip |
test_add_conn: added check for amount of available resources,
fixed leaks, added more error checks and reporting
Diffstat (limited to 'src/testcurl')
-rw-r--r-- | src/testcurl/test_add_conn.c | 103 |
1 files changed, 86 insertions, 17 deletions
diff --git a/src/testcurl/test_add_conn.c b/src/testcurl/test_add_conn.c index db6e85fd..b91ec3c9 100644 --- a/src/testcurl/test_add_conn.c +++ b/src/testcurl/test_add_conn.c | |||
@@ -47,6 +47,10 @@ | |||
47 | #include <sys/socket.h> | 47 | #include <sys/socket.h> |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #ifdef HAVE_LIMITS_H | ||
51 | #include <limits.h> | ||
52 | #endif /* HAVE_LIMITS_H */ | ||
53 | |||
50 | #ifdef HAVE_PTHREAD_H | 54 | #ifdef HAVE_PTHREAD_H |
51 | #include <pthread.h> | 55 | #include <pthread.h> |
52 | #endif /* HAVE_PTHREAD_H */ | 56 | #endif /* HAVE_PTHREAD_H */ |
@@ -66,6 +70,17 @@ | |||
66 | /* Could be increased to facilitate debugging */ | 70 | /* Could be increased to facilitate debugging */ |
67 | #define TIMEOUTS_VAL 5 | 71 | #define TIMEOUTS_VAL 5 |
68 | 72 | ||
73 | /* Number of requests per daemon in cleanup test, | ||
74 | * the number must be more than one as the first connection | ||
75 | * will be processed and the rest will stay in the list of unprocessed */ | ||
76 | #define CLEANUP_NUM_REQS_PER_DAEMON 6 | ||
77 | |||
78 | /* Cleanup test: max number of concurrent daemons depending on maximum number | ||
79 | * of open FDs. */ | ||
80 | #define CLEANUP_MAX_DAEMONS(max_fds) (((max_fds) - 10) / \ | ||
81 | (CLEANUP_NUM_REQS_PER_DAEMON * 5 \ | ||
82 | + 3)) | ||
83 | |||
69 | #define EXPECTED_URI_BASE_PATH "/hello_world" | 84 | #define EXPECTED_URI_BASE_PATH "/hello_world" |
70 | #define EXPECTED_URI_QUERY "a=%26&b=c" | 85 | #define EXPECTED_URI_QUERY "a=%26&b=c" |
71 | #define EXPECTED_URI_FULL_PATH EXPECTED_URI_BASE_PATH "?" EXPECTED_URI_QUERY | 86 | #define EXPECTED_URI_FULL_PATH EXPECTED_URI_BASE_PATH "?" EXPECTED_URI_QUERY |
@@ -79,6 +94,8 @@ static int slow_reply = 0; /**< Slowdown MHD replies */ | |||
79 | static int ignore_response_errors = 0; /**< Do not fail test if CURL | 94 | static int ignore_response_errors = 0; /**< Do not fail test if CURL |
80 | returns error */ | 95 | returns error */ |
81 | static int response_timeout_val = TIMEOUTS_VAL; | 96 | static int response_timeout_val = TIMEOUTS_VAL; |
97 | static int sys_max_fds; /**< Current system limit for number of open | ||
98 | files. */ | ||
82 | 99 | ||
83 | 100 | ||
84 | struct CBC | 101 | struct CBC |
@@ -413,18 +430,26 @@ curlEasyInitForTest (const char *queryPath, int port, struct CBC *pcbc) | |||
413 | fprintf (stderr, "curl_easy_init() failed.\n"); | 430 | fprintf (stderr, "curl_easy_init() failed.\n"); |
414 | _exit (99); | 431 | _exit (99); |
415 | } | 432 | } |
416 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); | 433 | if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) || |
417 | curl_easy_setopt (c, CURLOPT_URL, queryPath); | 434 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, queryPath)) || |
418 | curl_easy_setopt (c, CURLOPT_PORT, (long) port); | 435 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, (long) port)) || |
419 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | 436 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, |
420 | curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc); | 437 | ©Buffer)) || |
421 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, (long) response_timeout_val); | 438 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc)) || |
422 | curl_easy_setopt (c, CURLOPT_TIMEOUT, (long) response_timeout_val); | 439 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, |
423 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L); | 440 | (long) response_timeout_val)) || |
424 | if (oneone) | 441 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT, |
425 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | 442 | (long) response_timeout_val)) || |
426 | else | 443 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L)) || |
427 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | 444 | (oneone) ? |
445 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION, | ||
446 | CURL_HTTP_VERSION_1_1)) : | ||
447 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION, | ||
448 | CURL_HTTP_VERSION_1_0))) | ||
449 | { | ||
450 | fprintf (stderr, "curl_easy_setopt() failed.\n"); | ||
451 | _exit (99); | ||
452 | } | ||
428 | 453 | ||
429 | return c; | 454 | return c; |
430 | } | 455 | } |
@@ -454,6 +479,8 @@ doCurlQueryInThread (struct curlQueryParams *p) | |||
454 | if (ignore_response_errors) | 479 | if (ignore_response_errors) |
455 | { | 480 | { |
456 | p->queryError = 0; | 481 | p->queryError = 0; |
482 | curl_easy_cleanup (c); | ||
483 | |||
457 | return p->queryError; | 484 | return p->queryError; |
458 | } | 485 | } |
459 | if (CURLE_OK != errornum) | 486 | if (CURLE_OK != errornum) |
@@ -642,6 +669,9 @@ performTestCleanup (struct MHD_Daemon *d, int num_queries) | |||
642 | for (i = 0; i < num_queries; i++) | 669 | for (i = 0; i < num_queries; i++) |
643 | (void) finishThreadCurlQuery (qParamList + i); | 670 | (void) finishThreadCurlQuery (qParamList + i); |
644 | 671 | ||
672 | free (clntSkList); | ||
673 | free (qParamList); | ||
674 | |||
645 | return ret; | 675 | return ret; |
646 | } | 676 | } |
647 | 677 | ||
@@ -665,6 +695,26 @@ enum testMhdPollType | |||
665 | testMhdPollAuto = MHD_USE_AUTO | 695 | testMhdPollAuto = MHD_USE_AUTO |
666 | }; | 696 | }; |
667 | 697 | ||
698 | /* Get number of threads for thread pool depending | ||
699 | * on used poll function and test type. */ | ||
700 | static unsigned int | ||
701 | testNumThreadsForPool (enum testMhdPollType pollType) | ||
702 | { | ||
703 | int numThreads = MHD_CPU_COUNT; | ||
704 | if (! cleanup_test) | ||
705 | return numThreads; /* No practical limit for non-cleanup test */ | ||
706 | if (CLEANUP_MAX_DAEMONS (sys_max_fds) < numThreads) | ||
707 | numThreads = CLEANUP_MAX_DAEMONS (sys_max_fds); | ||
708 | if ((testMhdPollBySelect == pollType) && | ||
709 | (CLEANUP_MAX_DAEMONS (FD_SETSIZE) < numThreads)) | ||
710 | numThreads = CLEANUP_MAX_DAEMONS (FD_SETSIZE); | ||
711 | |||
712 | if (2 > numThreads) | ||
713 | abort (); | ||
714 | return (unsigned int) numThreads; | ||
715 | } | ||
716 | |||
717 | |||
668 | static struct MHD_Daemon * | 718 | static struct MHD_Daemon * |
669 | startTestMhdDaemon (enum testMhdThreadsType thrType, | 719 | startTestMhdDaemon (enum testMhdThreadsType thrType, |
670 | enum testMhdPollType pollType, int *pport) | 720 | enum testMhdPollType pollType, int *pport) |
@@ -701,8 +751,8 @@ startTestMhdDaemon (enum testMhdThreadsType thrType, | |||
701 | | MHD_USE_ERROR_LOG, | 751 | | MHD_USE_ERROR_LOG, |
702 | *pport, NULL, NULL, | 752 | *pport, NULL, NULL, |
703 | &ahc_echo, "GET", | 753 | &ahc_echo, "GET", |
704 | MHD_OPTION_THREAD_POOL_SIZE, (unsigned | 754 | MHD_OPTION_THREAD_POOL_SIZE, |
705 | int) MHD_CPU_COUNT, | 755 | testNumThreadsForPool (pollType), |
706 | MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL, | 756 | MHD_OPTION_URI_LOG_CALLBACK, &log_cb, NULL, |
707 | MHD_OPTION_END); | 757 | MHD_OPTION_END); |
708 | 758 | ||
@@ -938,7 +988,7 @@ testInternalGet (enum testMhdPollType pollType) | |||
938 | d = startTestMhdDaemon (testMhdThreadInternal, pollType, | 988 | d = startTestMhdDaemon (testMhdThreadInternal, pollType, |
939 | &d_port); | 989 | &d_port); |
940 | if (cleanup_test) | 990 | if (cleanup_test) |
941 | return performTestCleanup (d, 10); | 991 | return performTestCleanup (d, CLEANUP_NUM_REQS_PER_DAEMON); |
942 | 992 | ||
943 | return performTestQueries (d, d_port); | 993 | return performTestQueries (d, d_port); |
944 | } | 994 | } |
@@ -971,8 +1021,8 @@ testMultithreadedPoolGet (enum testMhdPollType pollType) | |||
971 | &d_port); | 1021 | &d_port); |
972 | 1022 | ||
973 | if (cleanup_test) | 1023 | if (cleanup_test) |
974 | return performTestCleanup (d, 10 * MHD_CPU_COUNT); | 1024 | return performTestCleanup (d, CLEANUP_NUM_REQS_PER_DAEMON |
975 | 1025 | * testNumThreadsForPool (pollType)); | |
976 | return performTestQueries (d, d_port); | 1026 | return performTestQueries (d, d_port); |
977 | } | 1027 | } |
978 | 1028 | ||
@@ -1065,6 +1115,25 @@ main (int argc, char *const *argv) | |||
1065 | return 77; /* Cannot run without threads */ | 1115 | return 77; /* Cannot run without threads */ |
1066 | #endif /* HAVE_PTHREAD_H */ | 1116 | #endif /* HAVE_PTHREAD_H */ |
1067 | verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv, "--quiet"); | 1117 | verbose = ! has_param (argc, argv, "-q") || has_param (argc, argv, "--quiet"); |
1118 | if (cleanup_test) | ||
1119 | { | ||
1120 | /* Find system limit for number of open FDs. */ | ||
1121 | #if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) | ||
1122 | sys_max_fds = sysconf (_SC_OPEN_MAX); | ||
1123 | #else /* ! HAVE_SYSCONF || ! _SC_OPEN_MAX */ | ||
1124 | sys_max_fds = -1; | ||
1125 | #endif /* ! HAVE_SYSCONF || ! _SC_OPEN_MAX */ | ||
1126 | if (0 > sys_max_fds) | ||
1127 | { | ||
1128 | #if defined(OPEN_MAX) && (0 < ((OPEN_MAX) +1)) | ||
1129 | sys_max_fds = OPEN_MAX; | ||
1130 | #else /* ! OPEN_MAX */ | ||
1131 | sys_max_fds = 256; /* Use reasonable value */ | ||
1132 | #endif /* ! OPEN_MAX */ | ||
1133 | if (2 > CLEANUP_MAX_DAEMONS (sys_max_fds)) | ||
1134 | return 77; /* Multithreaded test cannot be run */ | ||
1135 | } | ||
1136 | } | ||
1068 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) | 1137 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) |
1069 | return 99; | 1138 | return 99; |
1070 | /* Could be set to non-zero value to enforce using specific port | 1139 | /* Could be set to non-zero value to enforce using specific port |