tets: testrunner fairness

Collect all ready runners from select() and process in a loop. This
assures fairness in processing among all runners.

Formerly, only the first ready runner in the list of all was processed,
leading to later runners being delayed in processing and reporting
overly long test durations.

Also, reduce the backend idle timeout for the h2/h3 test servers so that
process shutdowns take less time.

Closes #14967
This commit is contained in:
Stefan Eissing 2024-09-19 15:59:20 +02:00 committed by Daniel Stenberg
parent 8498b1b953
commit 9413949397
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 60 additions and 52 deletions

View File

@ -108,6 +108,7 @@ $certfile = abs_path($certfile);
$keyfile = abs_path($keyfile);
my $cmdline="$nghttpx --backend=$connect ".
"--backend-keep-alive-timeout=500ms ".
"--frontend=\"*,$listenport;no-tls\" ".
"--frontend=\"*,$listenport2\" ".
"--log-level=INFO ".

View File

@ -108,6 +108,7 @@ $certfile = abs_path($certfile);
$keyfile = abs_path($keyfile);
my $cmdline="$nghttpx --http2-proxy --backend=$connect ".
"--backend-keep-alive-timeout=500ms ".
"--frontend=\"*,$listenport\" ".
"--frontend=\"*,$listenport;quic\" ".
"--log-level=INFO ".

View File

@ -1361,6 +1361,7 @@ sub runnerar_ready {
my $rin = "";
my %idbyfileno;
my $maxfileno=0;
my @ready_runners = ();
foreach my $p (keys(%controllerr)) {
my $fd = fileno($controllerr{$p});
vec($rin, $fd, 1) = 1;
@ -1383,10 +1384,11 @@ sub runnerar_ready {
return (undef, $idbyfileno{$fd});
}
if(vec($rout, $fd, 1)) {
return ($idbyfileno{$fd}, undef);
push(@ready_runners, $idbyfileno{$fd});
}
}
die "Internal pipe readiness inconsistency\n";
die "Internal pipe readiness inconsistency\n" if(!@ready_runners);
return (@ready_runners, undef);
}
return (undef, undef);
}

View File

@ -2945,63 +2945,67 @@ while () {
# one immediately. If all runners are busy, wait a fraction of a second
# for one to finish so we can still loop around to check the abort flag.
my $runnerwait = scalar(@runnersidle) && scalar(@runtests) ? 0 : 1.0;
my ($ridready, $riderror) = runnerar_ready($runnerwait);
if($ridready && ! defined $runnersrunning{$ridready}) {
# On Linux, a closed pipe still shows up as ready instead of error.
# Detect this here by seeing if we are expecting it to be ready and
# treat it as an error if not.
logmsg "ERROR: Runner $ridready is unexpectedly ready; is probably actually dead\n";
$riderror = $ridready;
undef $ridready;
}
if($ridready) {
# This runner is ready to be serviced
my $testnum = $runnersrunning{$ridready};
defined $testnum || die "Internal error: test for runner $ridready unknown";
delete $runnersrunning{$ridready};
my ($error, $again) = singletest($ridready, $testnum, $countforrunner{$ridready}, $totaltests);
if($again) {
# this runner is busy running a test
$runnersrunning{$ridready} = $testnum;
} else {
# Test is complete
$runner_wait_cnt = 0;
runnerready($ridready);
if($error < 0) {
# not a test we can run
next;
my (@ridsready, $riderror) = runnerar_ready($runnerwait);
if(@ridsready) {
for my $ridready (@ridsready) {
if($ridready && ! defined $runnersrunning{$ridready}) {
# On Linux, a closed pipe still shows up as ready instead of error.
# Detect this here by seeing if we are expecting it to be ready and
# treat it as an error if not.
logmsg "ERROR: Runner $ridready is unexpectedly ready; is probably actually dead\n";
$riderror = $ridready;
undef $ridready;
}
if($ridready) {
# This runner is ready to be serviced
my $testnum = $runnersrunning{$ridready};
defined $testnum || die "Internal error: test for runner $ridready unknown";
delete $runnersrunning{$ridready};
my ($error, $again) = singletest($ridready, $testnum, $countforrunner{$ridready}, $totaltests);
if($again) {
# this runner is busy running a test
$runnersrunning{$ridready} = $testnum;
} else {
# Test is complete
$runner_wait_cnt = 0;
runnerready($ridready);
$total++; # number of tests we've run
if($error < 0) {
# not a test we can run
next;
}
if($error>0) {
if($error==2) {
# ignored test failures
$failedign .= "$testnum ";
$total++; # number of tests we've run
if($error>0) {
if($error==2) {
# ignored test failures
$failedign .= "$testnum ";
}
else {
$failed.= "$testnum ";
}
if($postmortem) {
# display all files in $LOGDIR/ in a nice way
displaylogs($ridready, $testnum);
}
if($error==2) {
$ign++; # ignored test result counter
}
elsif(!$anyway) {
# a test failed, abort
logmsg "\n - abort tests\n";
undef @runtests; # empty out the remaining tests
}
}
elsif(!$error) {
$ok++; # successful test counter
}
}
else {
$failed.= "$testnum ";
}
if($postmortem) {
# display all files in $LOGDIR/ in a nice way
displaylogs($ridready, $testnum);
}
if($error==2) {
$ign++; # ignored test result counter
}
elsif(!$anyway) {
# a test failed, abort
logmsg "\n - abort tests\n";
undef @runtests; # empty out the remaining tests
}
}
elsif(!$error) {
$ok++; # successful test counter
}
}
}
if(!$ridready && $runnerwait && !$torture && scalar(%runnersrunning)) {
if(!@ridsready && $runnerwait && !$torture && scalar(%runnersrunning)) {
$runner_wait_cnt++;
if($runner_wait_cnt >= 5) {
my $msg = "waiting for " . scalar(%runnersrunning) . " results:";