Mercurial > hg > nginx-tests
annotate grpc_ssl.t @ 1427:eb1d883305ea
Tests: avoid edge cases in upstream random two test.
Unavailable servers contribute to the number of attempts, if selected,
before the balancer would fall back to the default round-robin method.
This means that it's quite possible to get server with more connections.
To facilitate with selecting two alive servers, down server was removed
from the upstream configuration at the cost of slightly worse coverage.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 10 Jan 2019 17:42:34 +0300 |
parents | 01d806268a12 |
children | dbce8fb5f5f8 |
rev | line source |
---|---|
1303 | 1 #!/usr/bin/perl |
2 | |
3 # (C) Sergey Kandaurov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Tests for grpc backend with ssl. | |
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; | |
19 use Test::Nginx::HTTP2; | |
20 | |
21 ############################################################################### | |
22 | |
23 select STDERR; $| = 1; | |
24 select STDOUT; $| = 1; | |
25 | |
1312
6f95c0ed2335
Tests: removed proxy prerequisite from grpc tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1303
diff
changeset
|
26 my $t = Test::Nginx->new()->has(qw/http rewrite http_v2 grpc/) |
1378
ba7e2e60f8b6
Tests: fixed grpc_ssl.t prerequisites.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1376
diff
changeset
|
27 ->has(qw/upstream_keepalive http_ssl/)->has_daemon('openssl'); |
1303 | 28 |
29 $t->{_configure_args} =~ /OpenSSL ([\d\.]+)/; | |
30 plan(skip_all => 'OpenSSL too old') unless defined $1 and $1 ge '1.0.2'; | |
31 | |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1378
diff
changeset
|
32 $t->write_file_expand('nginx.conf', <<'EOF')->plan(33); |
1303 | 33 |
34 %%TEST_GLOBALS%% | |
35 | |
36 daemon off; | |
37 | |
38 events { | |
39 } | |
40 | |
41 http { | |
42 %%TEST_GLOBALS_HTTP%% | |
43 | |
44 upstream u { | |
45 server 127.0.0.1:8081; | |
46 keepalive 1; | |
47 } | |
48 | |
49 server { | |
50 listen 127.0.0.1:8081 http2 ssl; | |
51 server_name localhost; | |
52 | |
53 ssl_certificate_key localhost.key; | |
54 ssl_certificate localhost.crt; | |
55 | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
56 ssl_verify_client optional; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
57 ssl_client_certificate client.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
58 |
1303 | 59 http2_max_field_size 128k; |
60 http2_max_header_size 128k; | |
61 http2_body_preread_size 128k; | |
62 | |
63 location / { | |
64 grpc_pass 127.0.0.1:8082; | |
65 add_header X-Connection $connection; | |
66 } | |
67 } | |
68 | |
69 server { | |
70 listen 127.0.0.1:8080 http2; | |
71 server_name localhost; | |
72 | |
73 http2_max_field_size 128k; | |
74 http2_max_header_size 128k; | |
75 http2_body_preread_size 128k; | |
76 | |
77 location / { | |
78 grpc_pass grpcs://127.0.0.1:8081; | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
79 grpc_ssl_name localhost; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
80 grpc_ssl_verify on; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
81 grpc_ssl_trusted_certificate localhost.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
82 |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
83 grpc_ssl_certificate client.crt; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
84 grpc_ssl_certificate_key client.key; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
85 grpc_ssl_password_file password; |
1303 | 86 |
87 if ($arg_if) { | |
88 # nothing | |
89 } | |
90 | |
91 limit_except GET { | |
92 # nothing | |
93 } | |
94 } | |
95 | |
96 location /KeepAlive { | |
97 grpc_pass grpcs://u; | |
98 } | |
99 } | |
100 } | |
101 | |
102 EOF | |
103 | |
104 $t->write_file('openssl.conf', <<EOF); | |
105 [ req ] | |
106 default_bits = 1024 | |
107 encrypt_key = no | |
108 distinguished_name = req_distinguished_name | |
109 [ req_distinguished_name ] | |
110 EOF | |
111 | |
112 my $d = $t->testdir(); | |
113 | |
114 foreach my $name ('localhost') { | |
115 system('openssl req -x509 -new ' | |
116 . "-config $d/openssl.conf -subj /CN=$name/ " | |
117 . "-out $d/$name.crt -keyout $d/$name.key " | |
118 . ">>$d/openssl.out 2>&1") == 0 | |
119 or die "Can't create certificate for $name: $!\n"; | |
120 } | |
121 | |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
122 foreach my $name ('client') { |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
123 system("openssl genrsa -out $d/$name.key -passout pass:$name " |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
124 . "-aes128 1024 >>$d/openssl.out 2>&1") == 0 |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
125 or die "Can't create private key: $!\n"; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
126 system('openssl req -x509 -new ' |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
127 . "-config $d/openssl.conf -subj /CN=$name/ " |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
128 . "-out $d/$name.crt " |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
129 . "-key $d/$name.key -passin pass:$name" |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
130 . ">>$d/openssl.out 2>&1") == 0 |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
131 or die "Can't create certificate for $name: $!\n"; |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
132 } |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
133 |
1323
6eb3dd2d4d5a
Tests: postponed grpc_ssl.t startup on win32, see eadd24ccfda1.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
134 sleep 1 if $^O eq 'MSWin32'; |
6eb3dd2d4d5a
Tests: postponed grpc_ssl.t startup on win32, see eadd24ccfda1.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1321
diff
changeset
|
135 |
1313
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
136 $t->write_file('password', 'client'); |
cc2f17cd9677
Tests: very basic grpc ssl verify and passphrase tests added.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1312
diff
changeset
|
137 |
1381
97c8280de681
Tests: removed TODO and try_run() checks for legacy versions.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1378
diff
changeset
|
138 $t->run(); |
1303 | 139 |
140 ############################################################################### | |
141 | |
142 my $p = port(8082); | |
143 my $f = grpc(); | |
144 | |
145 my $frames = $f->{http_start}('/SayHello'); | |
146 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
147 is($frame->{flags}, 4, 'request - HEADERS flags'); | |
148 ok((my $sid = $frame->{sid}) % 2, 'request - HEADERS sid odd'); | |
149 is($frame->{headers}{':method'}, 'POST', 'request - method'); | |
150 is($frame->{headers}{':scheme'}, 'http', 'request - scheme'); | |
151 is($frame->{headers}{':path'}, '/SayHello', 'request - path'); | |
152 is($frame->{headers}{':authority'}, "127.0.0.1:$p", 'request - authority'); | |
153 is($frame->{headers}{'content-type'}, 'application/grpc', | |
154 'request - content type'); | |
155 is($frame->{headers}{te}, 'trailers', 'request - te'); | |
156 | |
157 $frames = $f->{data}('Hello'); | |
158 ($frame) = grep { $_->{type} eq "SETTINGS" } @$frames; | |
159 is($frame->{flags}, 1, 'request - SETTINGS ack'); | |
160 is($frame->{sid}, 0, 'request - SETTINGS sid'); | |
161 is($frame->{length}, 0, 'request - SETTINGS length'); | |
162 | |
163 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
164 is($frame->{data}, 'Hello', 'request - DATA'); | |
165 is($frame->{length}, 5, 'request - DATA length'); | |
166 is($frame->{flags}, 1, 'request - DATA flags'); | |
167 is($frame->{sid}, $sid, 'request - DATA sid match'); | |
168 | |
169 $frames = $f->{http_end}(); | |
170 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
171 is($frame->{flags}, 4, 'response - HEADERS flags'); | |
172 is($frame->{sid}, 1, 'response - HEADERS sid'); | |
173 is($frame->{headers}{':status'}, '200', 'response - status'); | |
174 is($frame->{headers}{'content-type'}, 'application/grpc', | |
175 'response - content type'); | |
176 ok($frame->{headers}{server}, 'response - server'); | |
177 ok($frame->{headers}{date}, 'response - date'); | |
178 ok(my $c = $frame->{headers}{'x-connection'}, 'response - connection'); | |
179 | |
180 ($frame) = grep { $_->{type} eq "DATA" } @$frames; | |
181 is($frame->{data}, 'Hello world', 'response - DATA'); | |
182 is($frame->{length}, 11, 'response - DATA length'); | |
183 is($frame->{flags}, 0, 'response - DATA flags'); | |
184 is($frame->{sid}, 1, 'response - DATA sid'); | |
185 | |
186 (undef, $frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
187 is($frame->{flags}, 5, 'response - trailers flags'); | |
188 is($frame->{sid}, 1, 'response - trailers sid'); | |
189 is($frame->{headers}{'grpc-message'}, '', 'response - trailers message'); | |
190 is($frame->{headers}{'grpc-status'}, '0', 'response - trailers status'); | |
191 | |
192 # next request is on a new backend connection, no sid incremented | |
193 | |
194 $f->{http_start}('/SayHello'); | |
195 $f->{data}('Hello'); | |
196 $frames = $f->{http_end}(); | |
197 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
198 cmp_ok($frame->{headers}{'x-connection'}, '>', $c, 'response 2 - connection'); | |
199 | |
200 # upstream keepalive | |
201 | |
202 $f->{http_start}('/KeepAlive'); | |
203 $f->{data}('Hello'); | |
204 $frames = $f->{http_end}(); | |
205 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
206 ok($c = $frame->{headers}{'x-connection'}, 'keepalive - connection'); | |
207 | |
208 $f->{http_start}('/KeepAlive'); | |
209 $f->{data}('Hello'); | |
210 $frames = $f->{http_end}(); | |
211 ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
212 is($frame->{headers}{'x-connection'}, $c, 'keepalive - connection reuse'); | |
213 | |
214 ############################################################################### | |
215 | |
216 sub grpc { | |
217 my ($server, $client, $f, $s, $c, $sid, $uri); | |
218 | |
219 $server = IO::Socket::INET->new( | |
220 Proto => 'tcp', | |
221 LocalHost => '127.0.0.1', | |
222 LocalPort => $p, | |
223 Listen => 5, | |
224 Reuse => 1 | |
225 ) | |
226 or die "Can't create listening socket: $!\n"; | |
227 | |
228 $f->{http_start} = sub { | |
229 ($uri, my %extra) = @_; | |
230 my $body_more = 1 if $uri !~ /LongHeader/; | |
231 $s = Test::Nginx::HTTP2->new() if !defined $s; | |
232 $s->new_stream({ body_more => $body_more, headers => [ | |
233 { name => ':method', value => 'POST', mode => 0 }, | |
234 { name => ':scheme', value => 'http', mode => 0 }, | |
235 { name => ':path', value => $uri, }, | |
236 { name => ':authority', value => 'localhost' }, | |
237 { name => 'content-type', value => 'application/grpc' }, | |
238 { name => 'te', value => 'trailers', mode => 2 }]}); | |
239 | |
240 if (!$extra{reuse}) { | |
1321
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
241 eval { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
242 local $SIG{ALRM} = sub { die "timeout\n" }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
243 alarm(5); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
244 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
245 $client = $server->accept() or return; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
246 |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
247 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
248 }; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
249 alarm(0); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
250 if ($@) { |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
251 log_in("died: $@"); |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
252 return undef; |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
253 } |
351b95be742b
Tests: fixed grpc tests hang in accept() on internal nginx error.
Sergey Kandaurov <pluknet@nginx.com>
parents:
1313
diff
changeset
|
254 |
1303 | 255 log2c("(new connection $client)"); |
256 | |
257 $client->sysread(my $buf, 24) == 24 or return; # preface | |
258 | |
259 $c = Test::Nginx::HTTP2->new(1, socket => $client, | |
260 pure => 1, preface => "") or return; | |
261 } | |
262 | |
263 my $frames = $c->read(all => [{ fin => 4 }]); | |
264 | |
265 if (!$extra{reuse}) { | |
266 $c->h2_settings(0); | |
267 $c->h2_settings(1); | |
268 } | |
269 | |
270 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames; | |
271 $sid = $frame->{sid}; | |
272 return $frames; | |
273 }; | |
274 $f->{data} = sub { | |
275 my ($body, %extra) = @_; | |
276 $s->h2_body($body, { %extra }); | |
277 return $c->read(all => [{ sid => $sid, | |
278 length => length($body) }]); | |
279 }; | |
280 $f->{http_end} = sub { | |
281 $c->new_stream({ body_more => 1, headers => [ | |
282 { name => ':status', value => '200', mode => 0 }, | |
283 { name => 'content-type', value => 'application/grpc', | |
284 mode => 1, huff => 1 }, | |
285 ]}, $sid); | |
286 $c->h2_body('Hello world', { body_more => 1 }); | |
287 $c->new_stream({ headers => [ | |
288 { name => 'grpc-status', value => '0', | |
289 mode => 2, huff => 1 }, | |
290 { name => 'grpc-message', value => '', | |
291 mode => 2, huff => 1 }, | |
292 ]}, $sid); | |
293 | |
294 return $s->read(all => [{ fin => 1 }]); | |
295 }; | |
296 return $f; | |
297 } | |
298 | |
299 sub log2i { Test::Nginx::log_core('|| <<', @_); } | |
300 sub log2o { Test::Nginx::log_core('|| >>', @_); } | |
301 sub log2c { Test::Nginx::log_core('||', @_); } | |
302 | |
303 ############################################################################### |