Skip to content

Commit

Permalink
Tests: grpc request buffering and next upstream tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
pluknet committed Mar 29, 2018
1 parent 011b2cb commit 0f11ae8
Show file tree
Hide file tree
Showing 2 changed files with 289 additions and 0 deletions.
146 changes: 146 additions & 0 deletions grpc_next_upstream.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/perl

# (C) Maxim Dounin
# (C) Sergey Kandaurov
# (C) Nginx, Inc.

# Tests for grpc module, grpc_next_upstream directive.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http http_v2 grpc rewrite/);

$t->write_file_expand('nginx.conf', <<'EOF');
%%TEST_GLOBALS%%
daemon off;
events {
}
http {
%%TEST_GLOBALS_HTTP%%
upstream u {
server 127.0.0.1:8081 max_fails=2;
server 127.0.0.1:8082;
}
upstream u2 {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 127.0.0.1:8080;
server_name localhost;
location / {
grpc_pass u;
grpc_next_upstream http_500 http_404 invalid_header;
}
location /all/ {
grpc_pass u2;
grpc_next_upstream http_500 http_404;
error_page 404 /all/404;
grpc_intercept_errors on;
}
location /all/404 {
return 200 "$upstream_addr\n";
}
}
server {
listen 127.0.0.1:8081 http2;
server_name localhost;
location / {
return 404;
}
location /ok {
return 200 "AND-THIS\n";
}
location /500 {
return 500;
}
location /444 {
return 444;
}
location /all/ {
return 404;
}
}
server {
listen 127.0.0.1:8082 http2;
server_name localhost;
location / {
return 200 "TEST-OK-IF-YOU-SEE-THIS\n";
}
location /all/ {
return 404;
}
}
}
EOF

$t->try_run('no grpc')->plan(9);

###############################################################################

my ($p1, $p2) = (port(8081), port(8082));

# check if both request fallback to a backend
# which returns valid response

like(http_get('/'), qr/SEE-THIS/, 'grpc request');
like(http_get('/'), qr/SEE-THIS/, 'second request');

# make sure backend isn't switched off after
# grpc_next_upstream http_404

like(http_get('/ok') . http_get('/ok'), qr/AND-THIS/, 'not down');

# next upstream on invalid_header

like(http_get('/444'), qr/SEE-THIS/, 'request 444');
like(http_get('/444'), qr/SEE-THIS/, 'request 444 second');

# next upstream on http_500

like(http_get('/500'), qr/SEE-THIS/, 'request 500');
like(http_get('/500'), qr/SEE-THIS/, 'request 500 second');

# make sure backend switched off with http_500

unlike(http_get('/ok') . http_get('/ok'), qr/AND-THIS/, 'down after 500');

# make sure all backends are tried once

like(http_get('/all/rr'),
qr/^127.0.0.1:($p1, 127.0.0.1:$p2|$p2, 127.0.0.1:$p1)$/mi,
'all tried once');

###############################################################################
143 changes: 143 additions & 0 deletions grpc_request_buffering.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/usr/bin/perl

# (C) Sergey Kandaurov
# (C) Nginx, Inc.

# Tests for grpc module, request body buffered.

###############################################################################

use warnings;
use strict;

use Test::More;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;
use Test::Nginx::HTTP2;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

my $t = Test::Nginx->new()->has(qw/http http_v2 grpc mirror/);

$t->write_file_expand('nginx.conf', <<'EOF');
%%TEST_GLOBALS%%
daemon off;
events {
}
http {
%%TEST_GLOBALS_HTTP%%
server {
listen 127.0.0.1:8080 http2;
server_name localhost;
location /mirror { }
location / {
grpc_pass 127.0.0.1:8081;
add_header X-Body $request_body;
mirror /mirror;
}
}
}
EOF

$t->try_run('no grpc')->plan(9);

###############################################################################

my $p = port(8081);
my $f = grpc();

my $frames = $f->{http_start}('/SayHello');
my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
is($frame->{flags}, 4, 'request - HEADERS flags');
is($frame->{headers}{':method'}, 'POST', 'request - method');
is($frame->{headers}{':scheme'}, 'http', 'request - scheme');
is($frame->{headers}{':path'}, '/SayHello', 'request - path');
is($frame->{headers}{':authority'}, "127.0.0.1:$p", 'request - authority');

($frame) = grep { $_->{type} eq "DATA" } @$frames;
is($frame->{data}, 'Hello', 'request - DATA');
is($frame->{length}, 5, 'request - DATA length');
is($frame->{flags}, 1, 'request - DATA flags');

$frames = $f->{http_end}();
($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
is($frame->{headers}{'x-body'}, 'Hello', 'request body in memory');

###############################################################################

sub grpc {
my ($server, $client, $f, $s, $c, $sid, $uri);

$server = IO::Socket::INET->new(
Proto => 'tcp',
LocalHost => '127.0.0.1',
LocalPort => $p,
Listen => 5,
Reuse => 1
)
or die "Can't create listening socket: $!\n";

$f->{http_start} = sub {
($uri, my %extra) = @_;
$s = Test::Nginx::HTTP2->new() if !defined $s;
$s->new_stream({ body => 'Hello', headers => [
{ name => ':method', value => 'POST', mode => 0 },
{ name => ':scheme', value => 'http', mode => 0 },
{ name => ':path', value => $uri },
{ name => ':authority', value => 'localhost' },
{ name => 'content-length', value => '5' }]});

if (!$extra{reuse}) {
$client = $server->accept() or return;
log2c("(new connection $client)");

$client->sysread(my $buf, 24) == 24 or return; # preface

$c = Test::Nginx::HTTP2->new(1, socket => $client,
pure => 1, preface => "") or return;
}

my $frames = $c->read(all => [{ fin => 1 }]);

if (!$extra{reuse}) {
$c->h2_settings(0);
$c->h2_settings(1);
}

my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
$sid = $frame->{sid};
return $frames;
};
$f->{http_end} = sub {
$c->new_stream({ body_more => 1, headers => [
{ name => ':status', value => '200', mode => 0 },
{ name => 'content-type', value => 'application/grpc' },
]}, $sid);
$c->h2_body('Hello world', { body_more => 1 });
$c->new_stream({ headers => [
{ name => 'grpc-status', value => '0', mode => 2 },
{ name => 'grpc-message', value => '', mode => 2 },
]}, $sid);

return $s->read(all => [{ fin => 1 }]);
};
return $f;
}

sub log2c { Test::Nginx::log_core('||', @_); }

###############################################################################

0 comments on commit 0f11ae8

Please sign in to comment.