summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/t/80graceful-shutdown.t
blob: cdc904f94b4d42a3a415d7c4fbd4e93dfdec4aa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use strict;
use warnings;
use Net::EmptyPort qw(check_port empty_port);
use Test::More;
use t::Util;

plan skip_all => 'nghttp not found'
    unless prog_exists('nghttp');

plan skip_all => 'plackup not found'
    unless prog_exists('plackup');

plan skip_all => 'Starlet not found'
    unless system('perl -MStarlet /dev/null > /dev/null 2>&1') == 0;

my $upstream_port = empty_port();
my $upstream_hostport = "127.0.0.1:$upstream_port";

sub create_upstream {
    my @args = (
        qw(plackup -s Starlet --keepalive-timeout 100 --access-log /dev/null --listen),
        $upstream_hostport,
        ASSETS_DIR . "/upstream.psgi",
    );
    spawn_server(
        argv     => \@args,
        is_ready =>  sub {
            $upstream_hostport =~ /:([0-9]+)$/s
                or die "failed to extract port number";
            check_port($1);
        },
    );
};

sub doit {
    my $timeout = shift;
    my $server = spawn_h2o(<< "EOT");
http2-graceful-shutdown-timeout: $timeout
hosts:
  default:
    paths:
      "/":
        proxy.reverse.url: http://127.0.0.1:$upstream_port
EOT

    my $upstream = create_upstream();
    my $nghttp_pid = open(NGHTTP, "nghttp -w 1 -v http://127.0.0.1:$server->{'port'}/infinite-stream 2>&1 |");

    my $nghttp_interrupted=0;
    eval {
        local $SIG{ALRM} = sub { die "Timeout" };
        my $stopped=0;
        alarm(5);
        while (<NGHTTP>) {
            if (/recv DATA frame/ && !$stopped) {
                # after the request started, stop H2O
                kill 'TERM', $server->{pid};
                $stopped = 1;
            }
            if (/Some requests were not processed/) {
                $nghttp_interrupted = 1;
            }
        }
        alarm(0);
    };
    my $err = $@;
    if ($timeout == 1) {
        ok($nghttp_interrupted == 1, "nghttp was interrupted");
        ok($err !~ /^Timeout/, "nghttp didn't timeout");
    } else {
        kill 'TERM', $nghttp_pid;
        ok($nghttp_interrupted == 0, "nghttp was not interrupted");
        ok($err =~ /^Timeout/, "nghttp did timeout");
    }
}

doit(0);
doit(1);

done_testing();