comparison stream_upstream_random.t @ 1350:fda743e92b31

Tests: upstream random tests.
author Sergey Kandaurov <pluknet@nginx.com>
date Fri, 15 Jun 2018 13:59:08 +0300
parents
children a37d8526e691
comparison
equal deleted inserted replaced
1349:99a83f7e7755 1350:fda743e92b31
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Tests for upstream random balancer module.
7
8 ###############################################################################
9
10 use warnings;
11 use strict;
12
13 use Test::More;
14
15 BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17 use lib 'lib';
18 use Test::Nginx qw/ :DEFAULT http_end /;
19
20 ###############################################################################
21
22 select STDERR; $| = 1;
23 select STDOUT; $| = 1;
24
25 my $t = Test::Nginx->new()
26 ->has(qw/stream stream_upstream_zone stream_upstream_random/)
27 ->write_file_expand('nginx.conf', <<'EOF');
28
29 %%TEST_GLOBALS%%
30
31 daemon off;
32 worker_processes 2;
33
34 events {
35 }
36
37 stream {
38 upstream u {
39 zone z 1m;
40 random;
41 server 127.0.0.1:8081;
42 server 127.0.0.1:8082;
43 }
44
45 upstream lc {
46 zone lc 1m;
47 random two;
48 server 127.0.0.1:8081;
49 server 127.0.0.1:8082;
50 }
51
52 upstream w {
53 zone w 1m;
54 random two least_conn;
55 server 127.0.0.1:8081;
56 server 127.0.0.1:8082 weight=2;
57 }
58
59 upstream mc {
60 zone mc 1m;
61 random;
62 server 127.0.0.1:8081 max_conns=2;
63 server 127.0.0.1:8082 max_conns=1;
64 }
65
66 upstream mc2 {
67 zone mc 1m;
68 random two;
69 server 127.0.0.1:8081 max_conns=2;
70 server 127.0.0.1:8082 max_conns=1;
71 }
72
73 upstream one {
74 random;
75 server 127.0.0.1:8081;
76 }
77
78 upstream two {
79 random two;
80 server 127.0.0.1:8081;
81 }
82
83 upstream zone {
84 zone z 1m;
85 random;
86 server 127.0.0.1:8081;
87 }
88
89 upstream ztwo {
90 zone z 1m;
91 random two;
92 server 127.0.0.1:8081;
93 }
94
95 upstream fail {
96 zone fail 1m;
97 random;
98 server 127.0.0.1:8096;
99 server 127.0.0.1:8083 down;
100 server 127.0.0.1:8082;
101 }
102
103 upstream fail2 {
104 zone fail2 1m;
105 random two;
106 server 127.0.0.1:8096;
107 server 127.0.0.1:8083 down;
108 server 127.0.0.1:8082;
109 }
110
111 server {
112 listen 127.0.0.1:8080;
113 proxy_pass u;
114 }
115
116 server {
117 listen 127.0.0.1:8083;
118 proxy_pass lc;
119 }
120
121 server {
122 listen 127.0.0.1:8084;
123 proxy_pass w;
124 }
125
126 server {
127 listen 127.0.0.1:8085;
128 proxy_pass mc;
129 }
130
131 server {
132 listen 127.0.0.1:8086;
133 proxy_pass mc2;
134 }
135
136 server {
137 listen 127.0.0.1:8087;
138 proxy_pass one;
139 }
140
141 server {
142 listen 127.0.0.1:8088;
143 proxy_pass two;
144 }
145
146 server {
147 listen 127.0.0.1:8089;
148 proxy_pass zone;
149 }
150
151 server {
152 listen 127.0.0.1:8090;
153 proxy_pass ztwo;
154 }
155
156 proxy_connect_timeout 1s;
157
158 server {
159 listen 127.0.0.1:8091;
160 proxy_pass fail;
161 }
162
163 server {
164 listen 127.0.0.1:8092;
165 proxy_pass fail2;
166 }
167 }
168
169 EOF
170
171 $t->run_daemon(\&http_daemon, port(8081));
172 $t->run_daemon(\&http_daemon, port(8082));
173 $t->try_run('no upstream random')->plan(12);
174
175 $t->waitforsocket('127.0.0.1:' . port(8081));
176 $t->waitforsocket('127.0.0.1:' . port(8082));
177
178 ###############################################################################
179
180 my @ports = my ($port1, $port2) = (port(8081), port(8082));
181
182 like(get(8080, '/'), qr/X-Port: ($port1|$port2)/, 'random');
183 like(get(8083, '/'), qr/X-Port: ($port1|$port2)/, 'random two');
184
185 my $s = get(8083, '/w', start => 1, sleep => 0.2);
186 my $r = get(8083, '/');
187 my ($p) = http_end($s) =~ /X-Port: (\d+)/;
188 like($r, qr/X-Port: (?!$p)/, 'random wait');
189
190 SKIP: {
191 skip 'long test', 3 unless $ENV{TEST_NGINX_UNSAFE};
192
193 is(parallel(8084, '/w', 3), "$port1: 1, $port2: 2", 'random weight');
194
195 is(parallel(8085, '/w', 4), "$port1: 2, $port2: 1", 'max_conns');
196 is(parallel(8086, '/w', 4), "$port1: 2, $port2: 1", 'max_conns two');
197
198 }
199
200 # single variants
201
202 like(get(8087, '/'), qr/X-Port: $port1/, 'single one');
203 like(get(8088, '/'), qr/X-Port: $port1/, 'single two');
204 like(get(8089, '/'), qr/X-Port: $port1/, 'zone one');
205 like(get(8090, '/'), qr/X-Port: $port1/, 'zone two');
206
207 like(many(8091, '/', 10), qr/$port2: 10/, 'failures');
208 like(many(8092, '/', 10), qr/$port2: 10/, 'failures two');
209
210 ###############################################################################
211
212 sub get {
213 my ($port, $uri, %opts) = @_;
214 my $s = IO::Socket::INET->new(
215 Proto => 'tcp',
216 PeerAddr => '127.0.0.1',
217 PeerPort => port($port),
218 )
219 or die "Can't connect to nginx: $!\n";
220
221 http_get($uri, socket => $s, %opts);
222 }
223
224 sub many {
225 my ($port, $uri, $count, %opts) = @_;
226 my %ports;
227
228 for (1 .. $count) {
229 if (get($port, $uri) =~ /X-Port: (\d+)/) {
230 $ports{$1} = 0 unless defined $ports{$1};
231 $ports{$1}++;
232 }
233
234 select undef, undef, undef, $opts{delay} if $opts{delay};
235 }
236
237 my @keys = map { my $p = $_; grep { $p == $_ } keys %ports } @ports;
238 return join ', ', map { $_ . ": " . $ports{$_} } @keys;
239 }
240
241 sub parallel {
242 my ($port, $uri, $n) = @_;
243 my %ports;
244
245 my @s = map { get($port, $uri, start => 1, sleep => 0.1) } (1 .. $n);
246
247 for (@s) {
248 if (http_end($_) =~ /X-Port: (\d+)/) {
249 $ports{$1} = 0 unless defined $ports{$1};
250 $ports{$1}++;
251 }
252 }
253
254 my @keys = map { my $p = $_; grep { $p == $_ } keys %ports } @ports;
255 return join ', ', map { $_ . ": " . $ports{$_} } @keys;
256 }
257
258 ###############################################################################
259
260 sub http_daemon {
261 my ($port) = @_;
262
263 my $server = IO::Socket::INET->new(
264 Proto => 'tcp',
265 LocalHost => '127.0.0.1',
266 LocalPort => $port,
267 Listen => 5,
268 Reuse => 1
269 )
270 or die "Can't create listening socket: $!\n";
271
272 local $SIG{PIPE} = 'IGNORE';
273
274 while (my $client = $server->accept()) {
275 $client->autoflush(1);
276
277 my $headers = '';
278 my $uri = '';
279
280 while (<$client>) {
281 $headers .= $_;
282 last if (/^\x0d?\x0a?$/);
283 }
284
285 $uri = $1 if $headers =~ /^\S+\s+([^ ]+)\s+HTTP/i;
286
287 if ($uri eq '/w') {
288 Test::Nginx::log_core('||', "$port: sleep(2.5)");
289 select undef, undef, undef, 2.5;
290 }
291
292 if ($uri eq '/close' && $port == port(8081)) {
293 next;
294 }
295
296 Test::Nginx::log_core('||', "$port: response, 200");
297 print $client <<EOF;
298 HTTP/1.1 200 OK
299 Connection: close
300 X-Port: $port
301
302 OK
303 EOF
304
305 close $client;
306 }
307 }
308
309 ###############################################################################