[nginx-tests] Tests: improved timeout handling on Windows.
Maxim Dounin
mdounin at mdounin.ru
Fri Jan 30 10:36:20 UTC 2026
details: http://freenginx.org/hg/nginx-tests/rev/e7094af5cc2d
branches:
changeset: 2038:e7094af5cc2d
user: Maxim Dounin <mdounin at mdounin.ru>
date: Fri Jan 30 13:22:30 2026 +0300
description:
Tests: improved timeout handling on Windows.
On Windows, the eval + alarm model does not work (see perlport(1) for alarm,
as well as 1678:d0025a0dead7 and 1705:99a9b8b50f21 for previous related
fixes). Most notably, trying to rely on it for timeout handling around
accept() in the main test process results in infinite hangs on Windows
if something goes wrong and the timeout is indeed needed.
A similar issue in grpc.t was fixed in 1705:99a9b8b50f21, though other
similar constructs, originally introduced in 542:e7e3ced702f5, remained
in the code. At least grpc_ssl.t was seen hanging indefinitely after
an SSL handshake failure with the "certificate is not yet valid" error
due to the time adjusted backwards during the test.
With this change, all eval + alarm constructs around accept() calls are
replaced with IO::Select can_read() calls (with appropriate timeouts)
to check if there is a connection to accept. Code in grpc.t, which was
previously fixed in 1705:99a9b8b50f21, was slightly adjusted to match
other tests.
diffstat:
fastcgi_request_buffering.t | 21 +++++++--------------
fastcgi_request_buffering_chunked.t | 21 +++++++--------------
grpc.t | 8 +++-----
grpc_request_buffering.t | 14 +++-----------
grpc_ssl.t | 16 ++++------------
proxy_request_buffering.t | 21 +++++++--------------
proxy_request_buffering_chunked.t | 21 +++++++--------------
proxy_request_buffering_ssl.t | 21 +++++++--------------
8 files changed, 45 insertions(+), 98 deletions(-)
diffs (283 lines):
diff --git a/fastcgi_request_buffering.t b/fastcgi_request_buffering.t
--- a/fastcgi_request_buffering.t
+++ b/fastcgi_request_buffering.t
@@ -12,6 +12,8 @@ use warnings;
use strict;
use Test::More;
+
+use IO::Select;
use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -233,23 +235,14 @@ EOF
$s = http($r, start => 1);
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- local $SIG{PIPE} = sub { die "sigpipe\n" };
- alarm(5);
-
- $client = $server->accept();
-
- log2c("(new connection $client)");
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept();
+ log2c("(new connection $client)");
+
$client->sysread(my $buf, 1024);
log2i($buf);
diff --git a/fastcgi_request_buffering_chunked.t b/fastcgi_request_buffering_chunked.t
--- a/fastcgi_request_buffering_chunked.t
+++ b/fastcgi_request_buffering_chunked.t
@@ -13,6 +13,8 @@ use warnings;
use strict;
use Test::More;
+
+use IO::Select;
use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -262,23 +264,14 @@ EOF
$s = http($r, start => 1);
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- local $SIG{PIPE} = sub { die "sigpipe\n" };
- alarm(5);
-
- $client = $server->accept();
-
- log2c("(new connection $client)");
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept();
+ log2c("(new connection $client)");
+
$client->sysread(my $buf, 1024);
log2i($buf);
diff --git a/grpc.t b/grpc.t
--- a/grpc.t
+++ b/grpc.t
@@ -715,16 +715,14 @@ sub grpc {
{ name => 'te', value => 'trailers', mode => 2 }]});
if (!$extra{reuse}) {
- if (IO::Select->new($server)->can_read(5)) {
- $client = $server->accept();
-
- } else {
- log_in("timeout");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
# connection could be unexpectedly reused
goto reused if $client;
return undef;
}
+ $client = $server->accept();
log2c("(new connection $client)");
$n++;
diff --git a/grpc_request_buffering.t b/grpc_request_buffering.t
--- a/grpc_request_buffering.t
+++ b/grpc_request_buffering.t
@@ -133,20 +133,12 @@ sub grpc {
{ name => 'content-length', value => length($body) }]});
if (!$extra{reuse}) {
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- alarm(5);
-
- $client = $server->accept() or return;
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept() or return;
log2c("(new connection $client)");
$client->sysread(my $buf, 24) == 24 or return; # preface
diff --git a/grpc_ssl.t b/grpc_ssl.t
--- a/grpc_ssl.t
+++ b/grpc_ssl.t
@@ -259,20 +259,12 @@ sub grpc {
{ name => 'te', value => 'trailers', mode => 2 }]});
if (!$extra{reuse}) {
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- alarm(5);
-
- $client = $server->accept() or return;
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
-
+
+ $client = $server->accept() or return;
log2c("(new connection $client)");
$client->sysread(my $buf, 24) == 24 or return; # preface
diff --git a/proxy_request_buffering.t b/proxy_request_buffering.t
--- a/proxy_request_buffering.t
+++ b/proxy_request_buffering.t
@@ -12,6 +12,8 @@ use warnings;
use strict;
use Test::More;
+
+use IO::Select;
use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -200,23 +202,14 @@ EOF
$s = http($r, start => 1);
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- local $SIG{PIPE} = sub { die "sigpipe\n" };
- alarm(5);
-
- $client = $server->accept();
-
- log2c("(new connection $client)");
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept();
+ log2c("(new connection $client)");
+
$client->sysread(my $buf, 1024);
log2i($buf);
diff --git a/proxy_request_buffering_chunked.t b/proxy_request_buffering_chunked.t
--- a/proxy_request_buffering_chunked.t
+++ b/proxy_request_buffering_chunked.t
@@ -12,6 +12,8 @@ use warnings;
use strict;
use Test::More;
+
+use IO::Select;
use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -235,23 +237,14 @@ EOF
$s = http($r, start => 1);
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- local $SIG{PIPE} = sub { die "sigpipe\n" };
- alarm(5);
-
- $client = $server->accept();
-
- log2c("(new connection $client)");
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept();
+ log2c("(new connection $client)");
+
$client->sysread(my $buf, 1024);
log2i($buf);
diff --git a/proxy_request_buffering_ssl.t b/proxy_request_buffering_ssl.t
--- a/proxy_request_buffering_ssl.t
+++ b/proxy_request_buffering_ssl.t
@@ -12,6 +12,8 @@ use warnings;
use strict;
use Test::More;
+
+use IO::Select;
use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -221,23 +223,14 @@ EOF
$s = http($r, start => 1);
- eval {
- local $SIG{ALRM} = sub { die "timeout\n" };
- local $SIG{PIPE} = sub { die "sigpipe\n" };
- alarm(5);
-
- $client = $server->accept();
-
- log2c("(new connection $client)");
-
- alarm(0);
- };
- alarm(0);
- if ($@) {
- log_in("died: $@");
+ if (!IO::Select->new($server)->can_read(5)) {
+ log2c("timeout");
return undef;
}
+ $client = $server->accept();
+ log2c("(new connection $client)");
+
$client->sysread(my $buf, 1024);
log2i($buf);
More information about the nginx-devel
mailing list