Mercurial > hg > nginx-tests
comparison stream_upstream_max_conns.t @ 1391:62f06d8dfc63
Tests: ported upstream max_conns tests to stream, reduced diffs.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Wed, 07 Nov 2018 14:49:34 +0300 |
parents | upstream_max_conns.t@766bcbb632ee |
children | 3c101e516213 |
comparison
equal
deleted
inserted
replaced
1390:2c0955286894 | 1391:62f06d8dfc63 |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Nginx, Inc. | |
4 # (C) Sergey Kandaurov | |
5 | |
6 # Tests for stream upstream module with max_conns feature. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use Test::More; | |
14 | |
15 use IO::Select; | |
16 | |
17 BEGIN { use FindBin; chdir($FindBin::Bin); } | |
18 | |
19 use lib 'lib'; | |
20 use Test::Nginx qw/ :DEFAULT http_end /; | |
21 | |
22 ############################################################################### | |
23 | |
24 select STDERR; $| = 1; | |
25 select STDOUT; $| = 1; | |
26 | |
27 my $t = Test::Nginx->new()->has(qw/stream stream_upstream_least_conn/) | |
28 ->plan(12); | |
29 | |
30 $t->write_file_expand('nginx.conf', <<'EOF'); | |
31 | |
32 %%TEST_GLOBALS%% | |
33 | |
34 daemon off; | |
35 | |
36 events { | |
37 } | |
38 | |
39 stream { | |
40 upstream u_unlim { | |
41 server 127.0.0.1:8081 max_conns=0; | |
42 server 127.0.0.1:8082; | |
43 } | |
44 upstream u_lim { | |
45 server 127.0.0.1:8081 max_conns=3; | |
46 } | |
47 | |
48 upstream u_backup { | |
49 server 127.0.0.1:8081 max_conns=2; | |
50 server 127.0.0.1:8082 backup; | |
51 } | |
52 upstream u_backup_lim { | |
53 server 127.0.0.1:8081 max_conns=2; | |
54 server 127.0.0.1:8082 backup max_conns=3; | |
55 } | |
56 | |
57 upstream u_two { | |
58 server 127.0.0.1:8081 max_conns=1; | |
59 server 127.0.0.1:8082 max_conns=1; | |
60 } | |
61 upstream u_some { | |
62 server 127.0.0.1:8081 max_conns=1; | |
63 server 127.0.0.1:8082; | |
64 } | |
65 upstream u_many { | |
66 server 127.0.0.1:8081 max_conns=1; | |
67 server 127.0.0.1:8081 max_conns=1; | |
68 server 127.0.0.1:8082; | |
69 } | |
70 | |
71 upstream u_weight { | |
72 server 127.0.0.1:8081 weight=2 max_conns=1; | |
73 server 127.0.0.1:8082; | |
74 } | |
75 | |
76 upstream u_lc { | |
77 least_conn; | |
78 server 127.0.0.1:8081 max_conns=1; | |
79 server 127.0.0.1:8082; | |
80 } | |
81 upstream u_lc_backup { | |
82 least_conn; | |
83 server 127.0.0.1:8081 max_conns=2; | |
84 server 127.0.0.1:8082 backup; | |
85 } | |
86 upstream u_lc_backup_lim { | |
87 least_conn; | |
88 server 127.0.0.1:8081 max_conns=2; | |
89 server 127.0.0.1:8082 backup max_conns=3; | |
90 } | |
91 | |
92 server { | |
93 listen 127.0.0.1:8086; | |
94 proxy_pass u_unlim; | |
95 } | |
96 | |
97 server { | |
98 listen 127.0.0.1:8087; | |
99 proxy_pass u_lim; | |
100 } | |
101 | |
102 server { | |
103 listen 127.0.0.1:8088; | |
104 proxy_pass u_backup; | |
105 } | |
106 | |
107 server { | |
108 listen 127.0.0.1:8089; | |
109 proxy_pass u_backup_lim; | |
110 } | |
111 | |
112 server { | |
113 listen 127.0.0.1:8090; | |
114 proxy_pass u_two; | |
115 } | |
116 | |
117 server { | |
118 listen 127.0.0.1:8091; | |
119 proxy_pass u_some; | |
120 } | |
121 | |
122 server { | |
123 listen 127.0.0.1:8092; | |
124 proxy_pass u_many; | |
125 } | |
126 | |
127 server { | |
128 listen 127.0.0.1:8093; | |
129 proxy_pass u_weight; | |
130 } | |
131 | |
132 server { | |
133 listen 127.0.0.1:8094; | |
134 proxy_pass u_lc; | |
135 } | |
136 | |
137 server { | |
138 listen 127.0.0.1:8095; | |
139 proxy_pass u_lc_backup; | |
140 } | |
141 | |
142 server { | |
143 listen 127.0.0.1:8096; | |
144 proxy_pass u_lc_backup_lim; | |
145 } | |
146 } | |
147 | |
148 EOF | |
149 | |
150 $t->run_daemon(\&http_daemon, port(8081), port(8082), port(8085)); | |
151 $t->run(); | |
152 | |
153 $t->waitforsocket('127.0.0.1:' . port(8081)); | |
154 $t->waitforsocket('127.0.0.1:' . port(8082)); | |
155 $t->waitforsocket('127.0.0.1:' . port(8085)); | |
156 | |
157 ############################################################################### | |
158 | |
159 my @ports = my ($p1, $p2) = (port(8081), port(8082)); | |
160 | |
161 # two peers without max_conns | |
162 | |
163 is(parallel(8086, '/u_unlim?delay=0', 4), "$p1: 2, $p2: 2", 'unlimited'); | |
164 | |
165 # reopen connection to test connection subtraction | |
166 | |
167 my @s = http_get_multi(8087, '/u_lim', 2, 1.1); | |
168 get(8087, '/close'); | |
169 push @s, http_get_multi(8087, '/u_lim', 1, 1.1); | |
170 get(8085, '/closeall'); | |
171 | |
172 is(http_end_multi(\@s), "$p1: 3", 'conn subtraction'); | |
173 | |
174 # simple test with limited peer | |
175 | |
176 is(parallel(8087, '/u_lim', 4), "$p1: 3", 'single'); | |
177 | |
178 # limited peer with backup peer | |
179 | |
180 is(peers(8088, '/u_backup', 6), "$p1 $p1 $p2 $p2 $p2 $p2", 'backup'); | |
181 | |
182 # peer and backup peer, both limited | |
183 | |
184 is(peers(8089, '/u_backup_lim', 6), "$p1 $p1 $p2 $p2 $p2 ", 'backup limited'); | |
185 | |
186 # all peers limited | |
187 | |
188 is(parallel(8090, '/u_two', 4), "$p1: 1, $p2: 1", 'all peers'); | |
189 | |
190 # subset of peers limited | |
191 | |
192 is(parallel(8091, '/u_some', 4), "$p1: 1, $p2: 3", 'some peers'); | |
193 | |
194 # ensure that peer "weight" does not affect its max_conns limit | |
195 | |
196 is(parallel(8093, '/u_weight', 4), "$p1: 1, $p2: 3", 'weight'); | |
197 | |
198 # peers with equal server value aggregate max_conns limit | |
199 | |
200 is(parallel(8092, '/u_many', 6), "$p1: 2, $p2: 4", 'equal peer'); | |
201 | |
202 # least_conn balancer tests | |
203 | |
204 is(parallel(8094, '/u_lc', 4), "$p1: 1, $p2: 3", 'least_conn'); | |
205 is(peers(8095, '/u_lc_backup', 6), "$p1 $p1 $p2 $p2 $p2 $p2", | |
206 'least_conn backup'); | |
207 is(peers(8096, '/u_lc_backup_lim', 6), "$p1 $p1 $p2 $p2 $p2 ", | |
208 'least_conn backup limited'); | |
209 | |
210 ############################################################################### | |
211 | |
212 sub peers { | |
213 my ($port, $uri, $count) = @_; | |
214 | |
215 my @sockets = http_get_multi($port, $uri, $count, 1.1); | |
216 get(8085, '/closeall'); | |
217 | |
218 join ' ', map { defined $_ && /X-Port: (\d+)/ && $1 } | |
219 map { http_end $_ } (@sockets); | |
220 } | |
221 | |
222 sub parallel { | |
223 my ($port, $uri, $count) = @_; | |
224 | |
225 my @sockets = http_get_multi($port, $uri, $count); | |
226 for (1 .. 20) { | |
227 last if IO::Select->new(@sockets)->can_read(3) == $count; | |
228 select undef, undef, undef, 0.01; | |
229 } | |
230 get(8085, '/closeall'); | |
231 return http_end_multi(\@sockets); | |
232 } | |
233 | |
234 sub get { | |
235 my ($port, $uri, %opts) = @_; | |
236 my $s = IO::Socket::INET->new( | |
237 Proto => 'tcp', | |
238 PeerAddr => '127.0.0.1', | |
239 PeerPort => port($port), | |
240 ) | |
241 or die "Can't connect to nginx: $!\n"; | |
242 | |
243 http_get($uri, socket => $s, %opts); | |
244 } | |
245 | |
246 sub http_get_multi { | |
247 my ($port, $uri, $count, $wait) = @_; | |
248 my @sockets; | |
249 | |
250 for (0 .. $count - 1) { | |
251 $sockets[$_] = get($port, $uri, start => 1); | |
252 IO::Select->new($sockets[$_])->can_read($wait) if $wait; | |
253 } | |
254 | |
255 return @sockets; | |
256 } | |
257 | |
258 sub http_end_multi { | |
259 my ($sockets) = @_; | |
260 my %ports; | |
261 | |
262 for my $sock (@$sockets) { | |
263 my $r = http_end($sock); | |
264 if ($r && $r =~ /X-Port: (\d+)/) { | |
265 $ports{$1} = 0 unless defined $ports{$1}; | |
266 $ports{$1}++; | |
267 } | |
268 close $sock; | |
269 } | |
270 | |
271 my @keys = map { my $p = $_; grep { $p == $_ } keys %ports } @ports; | |
272 return join ', ', map { $_ . ": " . $ports{$_} } @keys; | |
273 } | |
274 | |
275 ############################################################################### | |
276 | |
277 sub http_daemon { | |
278 my (@ports) = @_; | |
279 my (@socks, @clients); | |
280 | |
281 for my $port (@ports) { | |
282 my $server = IO::Socket::INET->new( | |
283 Proto => 'tcp', | |
284 LocalHost => "127.0.0.1:$port", | |
285 Listen => 42, | |
286 Reuse => 1 | |
287 ) | |
288 or die "Can't create listening socket: $!\n"; | |
289 push @socks, $server; | |
290 } | |
291 | |
292 my $sel = IO::Select->new(@socks); | |
293 my $skip = 4; | |
294 my $count = 0; | |
295 | |
296 local $SIG{PIPE} = 'IGNORE'; | |
297 | |
298 OUTER: | |
299 while (my @ready = $sel->can_read) { | |
300 foreach my $fh (@ready) { | |
301 if (grep $_ == $fh, @socks) { | |
302 my $new = $fh->accept; | |
303 $new->autoflush(1); | |
304 $sel->add($new); | |
305 $count++; | |
306 | |
307 } else { | |
308 my @busy = grep { $_->sockport() } @ready; | |
309 | |
310 # finish other handles | |
311 if ($fh->sockport() == port(8085) && @busy > 1 | |
312 && grep $_->sockport() != port(8085), | |
313 @busy) | |
314 { | |
315 next; | |
316 } | |
317 | |
318 # late events in other handles | |
319 if ($fh->sockport() == port(8085) && @busy == 1 | |
320 && $count > 1 && $skip-- > 0) | |
321 { | |
322 select undef, undef, undef, 0.1; | |
323 next OUTER; | |
324 } | |
325 | |
326 my $rv = process_socket($fh, \@clients); | |
327 if ($rv == 1) { | |
328 $sel->remove($fh); | |
329 $fh->close; | |
330 } | |
331 if ($rv == 2) { | |
332 for (@clients) { | |
333 $sel->remove($_); | |
334 $_->close; | |
335 } | |
336 $sel->remove($fh); | |
337 $fh->close; | |
338 $skip = 4; | |
339 } | |
340 $count--; | |
341 } | |
342 } | |
343 } | |
344 } | |
345 | |
346 # Returns true to close connection | |
347 | |
348 sub process_socket { | |
349 my ($client, $saved) = @_; | |
350 my $port = $client->sockport(); | |
351 | |
352 my $headers = ''; | |
353 my $uri = ''; | |
354 | |
355 while (<$client>) { | |
356 $headers .= $_; | |
357 last if (/^\x0d?\x0a?$/); | |
358 } | |
359 return 1 if $headers eq ''; | |
360 | |
361 $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i; | |
362 return 1 if $uri eq ''; | |
363 | |
364 Test::Nginx::log_core('||', "$port: response, 200"); | |
365 print $client <<EOF; | |
366 HTTP/1.1 200 OK | |
367 X-Port: $port | |
368 | |
369 OK | |
370 EOF | |
371 | |
372 return 2 if $uri =~ /closeall/; | |
373 return 1 if $uri =~ /close/; | |
374 | |
375 push @$saved, $client; | |
376 return 0; | |
377 } | |
378 | |
379 ############################################################################### |