Mercurial > hg > nginx-tests
annotate lib/Test/Nginx/Stream.pm @ 1752:ba6e24e38f03
Tests: improved stop_daemons() to send signal again.
As was observed, it's possible that a signal to complete a uwsgi daemon
can be ignored while it is starting up, which results in tests hang due
to eternal waiting on child processes termination. Notably, it is seen
when running tests with a high number of prove jobs on a low-profile VM
against nginx with broken modules and/or configuration. To reproduce:
$ TEST_NGINX_GLOBALS=ERROR prove -j16 uwsgi*.t
Inspecting uwsgi under ktrace on FreeBSD confirms that a SIGTERM signal
is ignored at the very beginning of uwsgi startup. It is then replaced
with a default action after listen(), thus waiting until uwsgi is ready
to accept new TCP connections doesn't completely solve the hang window.
The fix is to retry sending a signal some time after waitpid(WNOHANG)
continuously demonstrated no progress with reaping a signaled process.
It is modelled after f13ead27f89c that improved stop() for nginx.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Wed, 29 Dec 2021 22:29:23 +0300 |
parents | 29d0961bc3f7 |
children | 5d3aee48ed8e |
rev | line source |
---|---|
816 | 1 package Test::Nginx::Stream; |
2 | |
3 # (C) Andrey Zelenkov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Module for nginx stream tests. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use base qw/ Exporter /; | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
14 our @EXPORT_OK = qw/ stream dgram /; |
816 | 15 |
16 use Test::More qw//; | |
17 use IO::Select; | |
18 use IO::Socket; | |
19 | |
20 use Test::Nginx; | |
21 | |
22 sub stream { | |
23 return Test::Nginx::Stream->new(@_); | |
24 } | |
25 | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
26 sub dgram { |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
27 unshift(@_, "PeerAddr") if @_ == 1; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
28 |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
29 return Test::Nginx::Stream->new( |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
30 Proto => "udp", |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
31 @_ |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
32 ); |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
33 } |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
34 |
816 | 35 sub new { |
36 my $self = {}; | |
37 bless $self, shift @_; | |
38 | |
39 unshift(@_, "PeerAddr") if @_ == 1; | |
40 | |
41 $self->{_socket} = IO::Socket::INET->new( | |
42 Proto => "tcp", | |
951
9361c7eddfc1
Tests: parallel tests support.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
935
diff
changeset
|
43 PeerAddr => '127.0.0.1', |
816 | 44 @_ |
45 ) | |
46 or die "Can't connect to nginx: $!\n"; | |
47 | |
48 if ({@_}->{'SSL'}) { | |
49 require IO::Socket::SSL; | |
50 IO::Socket::SSL->start_SSL($self->{_socket}, @_) | |
51 or die $IO::Socket::SSL::SSL_ERROR . "\n"; | |
52 } | |
53 | |
54 $self->{_socket}->autoflush(1); | |
55 | |
56 return $self; | |
57 } | |
58 | |
59 sub write { | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
60 my ($self, $message, %extra) = @_; |
816 | 61 my $s = $self->{_socket}; |
62 | |
63 local $SIG{PIPE} = 'IGNORE'; | |
64 | |
65 $s->blocking(0); | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
66 while (IO::Select->new($s)->can_write($extra{write_timeout} || 1.5)) { |
816 | 67 my $n = $s->syswrite($message); |
68 log_out(substr($message, 0, $n)); | |
69 last unless $n; | |
70 | |
71 $message = substr($message, $n); | |
72 last unless length $message; | |
73 } | |
74 | |
75 if (length $message) { | |
76 $s->close(); | |
77 } | |
78 } | |
79 | |
80 sub read { | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
81 my ($self, %extra) = @_; |
816 | 82 my ($s, $buf); |
83 | |
84 $s = $self->{_socket}; | |
85 | |
86 $s->blocking(0); | |
1423
29d0961bc3f7
Tests: aligned generic read timeouts in stream and mail tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1235
diff
changeset
|
87 if (IO::Select->new($s)->can_read($extra{read_timeout} || 8)) { |
816 | 88 $s->sysread($buf, 1024); |
89 }; | |
90 | |
91 log_in($buf); | |
92 return $buf; | |
93 } | |
94 | |
95 sub io { | |
96 my $self = shift; | |
97 | |
98 my ($data, %extra) = @_; | |
99 my $length = $extra{length}; | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
100 my $read = $extra{read}; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
101 |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
102 $read = 1 if !defined $read |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
103 && $self->{_socket}->socktype() == &SOCK_DGRAM; |
816 | 104 |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
105 $self->write($data, %extra); |
816 | 106 |
107 $data = ''; | |
108 while (1) { | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
109 last if defined $read && --$read < 0; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
110 |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
111 my $buf = $self->read(%extra); |
875
c380b4b7e2e4
Tests: compatibility with perl < 5.12 in Stream.pm.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
868
diff
changeset
|
112 last unless defined $buf and length($buf); |
816 | 113 |
114 $data .= $buf; | |
115 last if defined $length && length($data) >= $length; | |
116 } | |
117 | |
118 return $data; | |
119 } | |
120 | |
1024
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
121 sub sockaddr { |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
122 my $self = shift; |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
123 return $self->{_socket}->sockaddr(); |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
124 } |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
125 |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
126 sub sockhost { |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
127 my $self = shift; |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
128 return $self->{_socket}->sockhost(); |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
129 } |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
130 |
816 | 131 sub sockport { |
132 my $self = shift; | |
133 return $self->{_socket}->sockport(); | |
134 } | |
135 | |
136 ############################################################################### | |
137 | |
138 1; | |
139 | |
140 ############################################################################### |