Mercurial > hg > nginx-tests
comparison stream_limit_rate2.t @ 1473:ddbde6c5b0cd
Tests: stream limit rate tests, variables support.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 25 Apr 2019 13:41:45 +0300 |
parents | stream_limit_rate.t@7ae2747ee593 |
children | f3ba4c74de31 |
comparison
equal
deleted
inserted
replaced
1472:7ae2747ee593 | 1473:ddbde6c5b0cd |
---|---|
1 #!/usr/bin/perl | |
2 | |
3 # (C) Andrey Zelenkov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for stream proxy module, limit rate directives, variables support. | |
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; | |
21 use Test::Nginx::Stream qw/ stream /; | |
22 | |
23 ############################################################################### | |
24 | |
25 select STDERR; $| = 1; | |
26 select STDOUT; $| = 1; | |
27 | |
28 my $t = Test::Nginx->new()->has(qw/stream stream_map/) | |
29 ->write_file_expand('nginx.conf', <<'EOF'); | |
30 | |
31 %%TEST_GLOBALS%% | |
32 | |
33 daemon off; | |
34 | |
35 events { | |
36 } | |
37 | |
38 stream { | |
39 # download and upload rates are set equal to the maximum | |
40 # number of bytes transmitted | |
41 | |
42 # proxy_download_rate value comes from following calculations: | |
43 # test string length (1000) + whitespace (1) + time string length (10) | |
44 | |
45 map $server_port $down { | |
46 default 1011; | |
47 %%PORT_8082%% 0; | |
48 %%PORT_8083%% 1; | |
49 %%PORT_8085%% 250; | |
50 } | |
51 | |
52 map $server_port $up { | |
53 default 1000; | |
54 %%PORT_8082%% 0; | |
55 %%PORT_8084%% 1; | |
56 %%PORT_8086%% 250; | |
57 } | |
58 | |
59 proxy_download_rate $down; | |
60 proxy_upload_rate $up; | |
61 | |
62 server { | |
63 listen 127.0.0.1:8081; | |
64 proxy_pass 127.0.0.1:8080; | |
65 } | |
66 | |
67 server { | |
68 listen 127.0.0.1:8082; | |
69 proxy_pass 127.0.0.1:8080; | |
70 proxy_download_rate $down; | |
71 proxy_upload_rate $up; | |
72 } | |
73 | |
74 server { | |
75 listen 127.0.0.1:8083; | |
76 proxy_pass 127.0.0.1:8080; | |
77 proxy_download_rate $down; | |
78 } | |
79 | |
80 server { | |
81 listen 127.0.0.1:8084; | |
82 proxy_pass 127.0.0.1:8080; | |
83 proxy_upload_rate $up; | |
84 } | |
85 | |
86 server { | |
87 listen 127.0.0.1:8085; | |
88 proxy_pass 127.0.0.1:8080; | |
89 proxy_download_rate $down; | |
90 } | |
91 | |
92 server { | |
93 listen 127.0.0.1:8086; | |
94 proxy_pass 127.0.0.1:8087; | |
95 proxy_upload_rate $up; | |
96 } | |
97 } | |
98 | |
99 EOF | |
100 | |
101 $t->run_daemon(\&stream_daemon, port(8080)); | |
102 $t->run_daemon(\&stream_daemon, port(8087)); | |
103 $t->try_run('no proxy_download_rate variables')->plan(9); | |
104 | |
105 $t->waitforsocket('127.0.0.1:' . port(8080)); | |
106 $t->waitforsocket('127.0.0.1:' . port(8087)); | |
107 | |
108 ############################################################################### | |
109 | |
110 my $str = '1234567890' x 100; | |
111 | |
112 my %r = response($str, peer => '127.0.0.1:' . port(8081)); | |
113 is($r{'data'}, $str, 'exact limit'); | |
114 | |
115 %r = response($str . 'extra', peer => '127.0.0.1:' . port(8082)); | |
116 is($r{'data'}, $str . 'extra', 'unlimited'); | |
117 | |
118 SKIP: { | |
119 skip 'unsafe on VM', 3 unless $ENV{TEST_NGINX_UNSAFE}; | |
120 | |
121 # if interaction between backend and client is slow then proxy can add extra | |
122 # bytes to upload/download data | |
123 | |
124 %r = response($str . 'extra', peer => '127.0.0.1:' . port(8081)); | |
125 is($r{'data'}, $str, 'limited'); | |
126 | |
127 %r = response($str, peer => '127.0.0.1:' . port(8083), readonce => 1); | |
128 is($r{'data'}, '1', 'download - one byte'); | |
129 | |
130 %r = response($str, peer => '127.0.0.1:' . port(8084)); | |
131 is($r{'data'}, '1', 'upload - one byte'); | |
132 | |
133 } | |
134 | |
135 # Five chunks are split with four 1s delays: | |
136 # the first four chunks are quarters of test string | |
137 # and the fifth one is some extra data from backend. | |
138 | |
139 %r = response($str, peer => '127.0.0.1:' . port(8085)); | |
140 my $diff = time() - $r{'time'}; | |
141 cmp_ok($diff, '>=', 4, 'download - time'); | |
142 is($r{'data'}, $str, 'download - data'); | |
143 | |
144 my $time = time(); | |
145 %r = response($str . 'close', peer => '127.0.0.1:' . port(8086)); | |
146 $diff = time() - $time; | |
147 cmp_ok($diff, '>=', 4, 'upload - time'); | |
148 is($r{'data'}, $str . 'close', 'upload - data'); | |
149 | |
150 ############################################################################### | |
151 | |
152 sub response { | |
153 my ($data, %extra) = @_; | |
154 | |
155 my $s = stream($extra{peer}); | |
156 $s->write($data); | |
157 | |
158 $data = ''; | |
159 while (1) { | |
160 my $buf = $s->read(); | |
161 last unless length($buf); | |
162 | |
163 $data .= $buf; | |
164 | |
165 last if $extra{'readonce'}; | |
166 } | |
167 $data =~ /([\S]*)\s?(\d+)?/; | |
168 | |
169 return ('data' => $1, 'time' => $2) | |
170 } | |
171 | |
172 ############################################################################### | |
173 | |
174 sub stream_daemon { | |
175 my $port = shift; | |
176 | |
177 my $server = IO::Socket::INET->new( | |
178 Proto => 'tcp', | |
179 LocalAddr => '127.0.0.1', | |
180 LocalPort => $port, | |
181 Listen => 5, | |
182 Reuse => 1 | |
183 ) | |
184 or die "Can't create listening socket: $!\n"; | |
185 | |
186 my $sel = IO::Select->new($server); | |
187 | |
188 local $SIG{PIPE} = 'IGNORE'; | |
189 | |
190 while (my @ready = $sel->can_read) { | |
191 foreach my $fh (@ready) { | |
192 if ($server == $fh) { | |
193 my $new = $fh->accept; | |
194 $new->autoflush(1); | |
195 $sel->add($new); | |
196 | |
197 } elsif (stream_handle_client($fh)) { | |
198 $sel->remove($fh); | |
199 $fh->close; | |
200 } | |
201 } | |
202 } | |
203 } | |
204 | |
205 sub stream_handle_client { | |
206 my ($client) = @_; | |
207 | |
208 log2c("(new connection $client)"); | |
209 | |
210 $client->sysread(my $buffer, 65536) or return 1; | |
211 | |
212 log2i("$client $buffer"); | |
213 | |
214 $buffer .= " " . time() if $client->sockport() eq port(8080); | |
215 | |
216 log2o("$client $buffer"); | |
217 | |
218 $client->syswrite($buffer); | |
219 | |
220 return $client->sockport() eq port(8080) ? 1 : $buffer =~ /close/; | |
221 } | |
222 | |
223 sub log2i { Test::Nginx::log_core('|| <<', @_); } | |
224 sub log2o { Test::Nginx::log_core('|| >>', @_); } | |
225 sub log2c { Test::Nginx::log_core('||', @_); } | |
226 | |
227 ############################################################################### |