diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/data/Makefile.inc | 6 | ||||
-rw-r--r-- | tests/data/test1592 | 37 | ||||
-rw-r--r-- | tests/libtest/Makefile.inc | 6 | ||||
-rw-r--r-- | tests/libtest/lib1592.c | 119 |
4 files changed, 164 insertions, 4 deletions
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 59635be04..23ee19b36 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -179,8 +179,8 @@ test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \ \ test1560 test1561 \ \ -test1590 \ -test1591 \ +test1590 test1591 test1592 \ +\ test1600 test1601 test1602 test1603 test1604 test1605 test1606 test1607 \ test1608 test1609 test1620 \ \ diff --git a/tests/data/test1592 b/tests/data/test1592 new file mode 100644 index 000000000..d1346e1e3 --- /dev/null +++ b/tests/data/test1592 @@ -0,0 +1,37 @@ +<testcase> +<info> +<keywords> +HTTP +multi +resolve +speedcheck +</keywords> +</info> + +# Client-side +<client> +<server> +none +</server> +<tool> +lib1592 +</tool> + <name> +HTTP request, remove handle while resolving, don't block + </name> + + <command> +http://a-site-never-accessed.example.org/1592 +</command> +</client> + +# Verify data after the test has been "shot" +<verify> +<valgrind> +disable +</valgrind> +<errorcode> +0 +</errorcode> +</verify> +</testcase> diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 4c41fe7a1..497c4832a 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -31,7 +31,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1540 \ lib1550 lib1551 lib1552 lib1553 lib1554 lib1555 lib1556 lib1557 \ lib1560 \ - lib1591 \ + lib1591 lib1592 \ lib1900 \ lib2033 @@ -523,6 +523,10 @@ lib1591_SOURCES = lib1591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1591_LDADD = $(TESTUTIL_LIBS) lib1591_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1591 +lib1592_SOURCES = lib1592.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1592_LDADD = $(TESTUTIL_LIBS) +lib1592_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1592 + lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) lib1900_LDADD = $(TESTUTIL_LIBS) lib1900_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/tests/libtest/lib1592.c b/tests/libtest/lib1592.c new file mode 100644 index 000000000..5e6bf04eb --- /dev/null +++ b/tests/libtest/lib1592.c @@ -0,0 +1,119 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * See https://github.com/curl/curl/issues/3371 + * + * This test case checks whether curl_multi_remove_handle() cancels + * asynchronous DNS resolvers without blocking where possible. Obviously, it + * only tests whichever resolver cURL is actually built with. + */ + +/* We're willing to wait a very generous two seconds for the removal. This is + as low as we can go while still easily supporting SIGALRM timing for the + non-threaded blocking resolver. It doesn't matter that much because when + the test passes, we never wait this long. */ +#define TEST_HANG_TIMEOUT 2 * 1000 + +#include "test.h" +#include "testutil.h" + +#include <sys/stat.h> + +int test(char *URL) +{ + int stillRunning; + CURLM *multiHandle = NULL; + CURL *curl = NULL; + CURLMcode res = CURLM_OK; + int timeout; + + global_init(CURL_GLOBAL_ALL); + + multi_init(multiHandle); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + easy_setopt(curl, CURLOPT_URL, URL); + + /* Set a DNS server that hopefully will not respond when using c-ares. */ + if(curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, "0.0.0.0") == CURLE_OK) + /* Since we could set the DNS server, presume we are working with a + resolver that can be cancelled (i.e. c-ares). Thus, + curl_multi_remove_handle() should not block even when the resolver + request is outstanding. So, set a request timeout _longer_ than the + test hang timeout so we will fail if the handle removal call incorrectly + blocks. */ + timeout = TEST_HANG_TIMEOUT * 2; + else { + /* If we can't set the DNS server, presume that we are configured to use a + resolver that can't be cancelled (i.e. the threaded resolver or the + non-threaded blocking resolver). So, we just test that the + curl_multi_remove_handle() call does finish well within our test + timeout. + + But, it is very unlikely that the resolver request will take any time at + all because we haven't been able to configure the resolver to use an + non-responsive DNS server. At least we exercise the flow. + */ + fprintf(stderr, + "CURLOPT_DNS_SERVERS not supported; " + "assuming curl_multi_remove_handle() will block\n"); + timeout = TEST_HANG_TIMEOUT / 2; + } + + /* Setting a timeout on the request should ensure that even if we have to + wait for the resolver during curl_multi_remove_handle(), it won't take + longer than this, because the resolver request inherits its timeout from + this. */ + easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout); + + multi_add_handle(multiHandle, curl); + + /* This should move the handle from INIT => CONNECT => WAITRESOLVE. */ + fprintf(stderr, "curl_multi_perform()...\n"); + multi_perform(multiHandle, &stillRunning); + fprintf(stderr, "curl_multi_perform() succeeded\n"); + + /* Start measuring how long it takes to remove the handle. */ + fprintf(stderr, "curl_multi_remove_handle()...\n"); + start_test_timing(); + res = curl_multi_remove_handle(multiHandle, curl); + if(res) { + fprintf(stderr, "curl_multi_remove_handle() failed, " + "with code %d\n", (int)res); + goto test_cleanup; + } + fprintf(stderr, "curl_multi_remove_handle() succeeded\n"); + + /* Fail the test if it took too long to remove. This happens after the fact, + and says "it seems that it would have run forever", which isn't true, but + it's close enough, and simple to do. */ + abort_on_test_timeout(); + +test_cleanup: + curl_easy_cleanup(curl); + curl_multi_cleanup(multiHandle); + curl_global_cleanup(); + + return (int)res; +} |