mirror of
https://github.com/curl/curl.git
synced 2025-09-09 21:52:40 +03:00
curl: --test-duphandle in debug builds runs "duphandled"
Using this option (only available in debug builds) makes curl always call curl_easy_duphandle() on the handle before using it. To help us catch curl_easy_duphandle() mistakes better. Add a CI job using this. Bonus: the previous runtests option -e is now also supported as --test-event Closes #15504
This commit is contained in:
parent
354f3f96a1
commit
cbafcec50b
7
.github/workflows/linux.yml
vendored
7
.github/workflows/linux.yml
vendored
|
@ -248,7 +248,12 @@ jobs:
|
||||||
- name: event-based
|
- name: event-based
|
||||||
install_packages: libssh-dev
|
install_packages: libssh-dev
|
||||||
configure: --enable-debug --disable-shared --disable-threaded-resolver --with-libssh --with-openssl
|
configure: --enable-debug --disable-shared --disable-threaded-resolver --with-libssh --with-openssl
|
||||||
tflags: -n -e '!TLS-SRP'
|
tflags: -n --test-event '!TLS-SRP'
|
||||||
|
|
||||||
|
- name: duphandle
|
||||||
|
install_packages: libssh-dev
|
||||||
|
configure: --enable-debug --disable-shared --disable-threaded-resolver --with-libssh --with-openssl
|
||||||
|
tflags: -n --test-duphandle '!TLS-SRP'
|
||||||
|
|
||||||
- name: rustls valgrind
|
- name: rustls valgrind
|
||||||
install_packages: valgrind
|
install_packages: valgrind
|
||||||
|
|
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
|
@ -136,7 +136,7 @@ jobs:
|
||||||
compiler: clang
|
compiler: clang
|
||||||
configure: --enable-debug --with-openssl=$(brew --prefix openssl)
|
configure: --enable-debug --with-openssl=$(brew --prefix openssl)
|
||||||
macos-version-min: '10.9'
|
macos-version-min: '10.9'
|
||||||
tflags: -e
|
tflags: --test-event
|
||||||
- name: 'OpenSSL libssh2 !ldap 10.15'
|
- name: 'OpenSSL libssh2 !ldap 10.15'
|
||||||
compiler: clang
|
compiler: clang
|
||||||
configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl)
|
configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl)
|
||||||
|
|
|
@ -330,6 +330,7 @@ struct GlobalConfig {
|
||||||
long ms_per_transfer; /* start next transfer after (at least) this
|
long ms_per_transfer; /* start next transfer after (at least) this
|
||||||
many milliseconds */
|
many milliseconds */
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
|
bool test_duphandle;
|
||||||
bool test_event_based;
|
bool test_event_based;
|
||||||
#endif
|
#endif
|
||||||
bool parallel;
|
bool parallel;
|
||||||
|
|
|
@ -312,7 +312,10 @@ static const struct LongShort aliases[]= {
|
||||||
{"tcp-fastopen", ARG_BOOL, ' ', C_TCP_FASTOPEN},
|
{"tcp-fastopen", ARG_BOOL, ' ', C_TCP_FASTOPEN},
|
||||||
{"tcp-nodelay", ARG_BOOL, ' ', C_TCP_NODELAY},
|
{"tcp-nodelay", ARG_BOOL, ' ', C_TCP_NODELAY},
|
||||||
{"telnet-option", ARG_STRG, 't', C_TELNET_OPTION},
|
{"telnet-option", ARG_STRG, 't', C_TELNET_OPTION},
|
||||||
|
#ifdef DEBUGBUILD
|
||||||
|
{"test-duphandle", ARG_BOOL, ' ', C_TEST_DUPHANDLE},
|
||||||
{"test-event", ARG_BOOL, ' ', C_TEST_EVENT},
|
{"test-event", ARG_BOOL, ' ', C_TEST_EVENT},
|
||||||
|
#endif
|
||||||
{"tftp-blksize", ARG_STRG, ' ', C_TFTP_BLKSIZE},
|
{"tftp-blksize", ARG_STRG, ' ', C_TFTP_BLKSIZE},
|
||||||
{"tftp-no-options", ARG_BOOL, ' ', C_TFTP_NO_OPTIONS},
|
{"tftp-no-options", ARG_BOOL, ' ', C_TFTP_NO_OPTIONS},
|
||||||
{"time-cond", ARG_STRG, 'z', C_TIME_COND},
|
{"time-cond", ARG_STRG, 'z', C_TIME_COND},
|
||||||
|
@ -1653,13 +1656,14 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
||||||
case C_SASL_IR: /* --sasl-ir */
|
case C_SASL_IR: /* --sasl-ir */
|
||||||
config->sasl_ir = toggle;
|
config->sasl_ir = toggle;
|
||||||
break;
|
break;
|
||||||
case C_TEST_EVENT: /* --test-event */
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
global->test_event_based = toggle;
|
case C_TEST_DUPHANDLE: /* --test-duphandle */
|
||||||
#else
|
global->test_duphandle = toggle;
|
||||||
warnf(global, "--test-event is ignored unless a debug build");
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
case C_TEST_EVENT: /* --test-event */
|
||||||
|
global->test_event_based = toggle;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case C_UNIX_SOCKET: /* --unix-socket */
|
case C_UNIX_SOCKET: /* --unix-socket */
|
||||||
config->abstract_unix_socket = FALSE;
|
config->abstract_unix_socket = FALSE;
|
||||||
err = getstr(&config->unix_socket_path, nextarg, DENY_BLANK);
|
err = getstr(&config->unix_socket_path, nextarg, DENY_BLANK);
|
||||||
|
|
|
@ -267,6 +267,7 @@ typedef enum {
|
||||||
C_TCP_FASTOPEN,
|
C_TCP_FASTOPEN,
|
||||||
C_TCP_NODELAY,
|
C_TCP_NODELAY,
|
||||||
C_TELNET_OPTION,
|
C_TELNET_OPTION,
|
||||||
|
C_TEST_DUPHANDLE,
|
||||||
C_TEST_EVENT,
|
C_TEST_EVENT,
|
||||||
C_TFTP_BLKSIZE,
|
C_TFTP_BLKSIZE,
|
||||||
C_TFTP_NO_OPTIONS,
|
C_TFTP_NO_OPTIONS,
|
||||||
|
|
|
@ -2885,6 +2885,17 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
|
||||||
if(getenv("CURL_FORBID_REUSE"))
|
if(getenv("CURL_FORBID_REUSE"))
|
||||||
(void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L);
|
(void)curl_easy_setopt(per->curl, CURLOPT_FORBID_REUSE, 1L);
|
||||||
|
|
||||||
|
if(global->test_duphandle) {
|
||||||
|
CURL *dup = curl_easy_duphandle(per->curl);
|
||||||
|
curl_easy_cleanup(per->curl);
|
||||||
|
per->curl = dup;
|
||||||
|
if(!dup) {
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* a duplicate needs the share re-added */
|
||||||
|
(void)curl_easy_setopt(per->curl, CURLOPT_SHARE, share);
|
||||||
|
}
|
||||||
if(global->test_event_based)
|
if(global->test_event_based)
|
||||||
result = curl_easy_perform_ev(per->curl);
|
result = curl_easy_perform_ev(per->curl);
|
||||||
else
|
else
|
||||||
|
|
|
@ -522,6 +522,7 @@ the `unit/` directory (if the tool name starts with `unit`).
|
||||||
Brief test case description, shown when the test runs.
|
Brief test case description, shown when the test runs.
|
||||||
|
|
||||||
### `<setenv>`
|
### `<setenv>`
|
||||||
|
|
||||||
variable1=contents1
|
variable1=contents1
|
||||||
variable2=contents2
|
variable2=contents2
|
||||||
variable3
|
variable3
|
||||||
|
@ -606,6 +607,11 @@ Pass this given data on stdin to the tool.
|
||||||
If `nonewline` is set, we cut off the trailing newline of this given data
|
If `nonewline` is set, we cut off the trailing newline of this given data
|
||||||
before comparing with the one actually received by the client
|
before comparing with the one actually received by the client
|
||||||
|
|
||||||
|
## `<disable>`
|
||||||
|
|
||||||
|
If `test-duphandle` is a listed item here, this is not run when
|
||||||
|
`--test-duphandle` is used.
|
||||||
|
|
||||||
## `<verify>`
|
## `<verify>`
|
||||||
### `<errorcode>`
|
### `<errorcode>`
|
||||||
numerical error code curl is supposed to return. Specify a list of accepted
|
numerical error code curl is supposed to return. Specify a list of accepted
|
||||||
|
|
|
@ -44,6 +44,10 @@ HSTS with trailing-dot host name in URL but none in hsts file
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example./%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example./%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
||||||
</command>
|
</command>
|
||||||
|
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -44,6 +44,9 @@ HSTS with no t-dot host name in URL but t-dot in file
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -43,6 +43,9 @@ HSTS and %{url_effective} after upgrade
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -w '%{url_effective}\n'
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -55,6 +55,9 @@ HSTS with updated expiry in response
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -57,6 +57,9 @@ HSTS update expiry, with parent includeSubDomains domain present
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -57,6 +57,9 @@ HSTS update expiry, with two includeSubDomains domains present
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -57,6 +57,9 @@ HSTS update expiry, removing includesubdomains in update
|
||||||
<command>
|
<command>
|
||||||
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
-x http://%HOSTIP:%PROXYPORT http://this.hsts.example:%HTTPSPORT/%TESTNUMBER --hsts %LOGDIR/input%TESTNUMBER -k
|
||||||
</command>
|
</command>
|
||||||
|
<disable>
|
||||||
|
test-duphandle
|
||||||
|
</disable>
|
||||||
</client>
|
</client>
|
||||||
|
|
||||||
<verify>
|
<verify>
|
||||||
|
|
|
@ -54,6 +54,7 @@ BEGIN {
|
||||||
$PROXYIN
|
$PROXYIN
|
||||||
$pwd
|
$pwd
|
||||||
$randseed
|
$randseed
|
||||||
|
$run_duphandle
|
||||||
$run_event_based
|
$run_event_based
|
||||||
$SERVERCMD
|
$SERVERCMD
|
||||||
$SERVERIN
|
$SERVERIN
|
||||||
|
@ -83,6 +84,7 @@ our $verbose; # 1 to show verbose test output
|
||||||
our $torture; # 1 to enable torture testing
|
our $torture; # 1 to enable torture testing
|
||||||
our $proxy_address; # external HTTP proxy address
|
our $proxy_address; # external HTTP proxy address
|
||||||
our $listonly; # only list the tests
|
our $listonly; # only list the tests
|
||||||
|
our $run_duphandle; # run curl with --test-duphandle to verify handle duplication
|
||||||
our $run_event_based; # run curl with --test-event to test the event API
|
our $run_event_based; # run curl with --test-event to test the event API
|
||||||
our $automakestyle; # use automake-like test status output format
|
our $automakestyle; # use automake-like test status output format
|
||||||
our $anyway; # continue anyway, even if a test fail
|
our $anyway; # continue anyway, even if a test fail
|
||||||
|
|
|
@ -894,6 +894,18 @@ sub singletest_run {
|
||||||
$cmdargs .= "--test-event ";
|
$cmdargs .= "--test-event ";
|
||||||
$fail_due_event_based--;
|
$fail_due_event_based--;
|
||||||
}
|
}
|
||||||
|
if($run_duphandle) {
|
||||||
|
$cmdargs .= "--test-duphandle ";
|
||||||
|
my @dis = getpart("client", "disable");
|
||||||
|
if(@dis) {
|
||||||
|
chomp $dis[0] if($dis[0]);
|
||||||
|
if($dis[0] eq "test-duphandle") {
|
||||||
|
# marked to not run with duphandle
|
||||||
|
logmsg "test $testnum: IGNORED: can't run test-duphandle\n";
|
||||||
|
return (-1, 0, 0, "", "", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
$cmdargs .= $cmd;
|
$cmdargs .= $cmd;
|
||||||
if ($proxy_address) {
|
if ($proxy_address) {
|
||||||
$cmdargs .= " --proxy $proxy_address ";
|
$cmdargs .= " --proxy $proxy_address ";
|
||||||
|
|
|
@ -118,7 +118,7 @@ exclusion, the second field contains a pattern and the final field contains
|
||||||
the reason why matching tests should be skipped. The exclusion types are
|
the reason why matching tests should be skipped. The exclusion types are
|
||||||
*keyword*, *test*, and *tool*.
|
*keyword*, *test*, and *tool*.
|
||||||
|
|
||||||
## `-e`
|
## `-e` or `--test-event`
|
||||||
|
|
||||||
Run the test event-based (if possible). This makes runtests invoke curl with
|
Run the test event-based (if possible). This makes runtests invoke curl with
|
||||||
--test-event option. This option only works if both curl and libcurl were
|
--test-event option. This option only works if both curl and libcurl were
|
||||||
|
@ -263,6 +263,19 @@ the allocation with that number to be set to fail at once instead of looping
|
||||||
through everyone, which is handy when debugging and then often in combination
|
through everyone, which is handy when debugging and then often in combination
|
||||||
with *-g*.
|
with *-g*.
|
||||||
|
|
||||||
|
## `--test-duphandle`
|
||||||
|
|
||||||
|
Passes the `--test-duphandle` option to curl when invoked. This command line
|
||||||
|
option only exists in debug builds and runs curl normally, but duplicates the
|
||||||
|
easy handle before the transfer and use the duplicate instead of the original
|
||||||
|
handle. This verifies that the duplicate works exactly as good as the original
|
||||||
|
handle.
|
||||||
|
|
||||||
|
Because of how the curl tool uses a share object to store and keep some data,
|
||||||
|
not everything is however perfectly copied in the duplicate. In particular
|
||||||
|
HSTS data is not. A specific test case can be set to avoid using
|
||||||
|
`--test-duphandle` by disabling it on a per test basis.
|
||||||
|
|
||||||
## `-u`
|
## `-u`
|
||||||
|
|
||||||
Error instead of warning on server unexpectedly alive.
|
Error instead of warning on server unexpectedly alive.
|
||||||
|
|
|
@ -871,7 +871,8 @@ sub checksystemfeatures {
|
||||||
"*\n");
|
"*\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
logmsg sprintf("* Env: %s%s%s%s", $valgrind?"Valgrind ":"",
|
logmsg sprintf("* Env: %s%s%s%s%s", $valgrind?"Valgrind ":"",
|
||||||
|
$run_duphandle?"test-duphandle ":"",
|
||||||
$run_event_based?"event-based ":"",
|
$run_event_based?"event-based ":"",
|
||||||
$bundle?"bundle ":"",
|
$bundle?"bundle ":"",
|
||||||
$nghttpx_h3);
|
$nghttpx_h3);
|
||||||
|
@ -2270,10 +2271,14 @@ while(@ARGV) {
|
||||||
# have the servers display protocol output
|
# have the servers display protocol output
|
||||||
$debugprotocol=1;
|
$debugprotocol=1;
|
||||||
}
|
}
|
||||||
elsif($ARGV[0] eq "-e") {
|
elsif(($ARGV[0] eq "-e") || ($ARGV[0] eq "--test-event")) {
|
||||||
# run the tests cases event based if possible
|
# run the tests cases event based if possible
|
||||||
$run_event_based=1;
|
$run_event_based=1;
|
||||||
}
|
}
|
||||||
|
elsif($ARGV[0] eq "--test-duphandle") {
|
||||||
|
# run the tests with --test-duphandle
|
||||||
|
$run_duphandle=1;
|
||||||
|
}
|
||||||
elsif($ARGV[0] eq "-f") {
|
elsif($ARGV[0] eq "-f") {
|
||||||
# force - run the test case even if listed in DISABLED
|
# force - run the test case even if listed in DISABLED
|
||||||
$run_disabled=1;
|
$run_disabled=1;
|
||||||
|
|
|
@ -180,6 +180,7 @@ my %opts = (
|
||||||
'--include' => 6,
|
'--include' => 6,
|
||||||
|
|
||||||
# for tests and debug only, can remain hidden
|
# for tests and debug only, can remain hidden
|
||||||
|
'--test-duphandle' => 6,
|
||||||
'--test-event' => 6,
|
'--test-event' => 6,
|
||||||
'--wdebug' => 6,
|
'--wdebug' => 6,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user