From e9593301044f305d4a0e074f77eea35015ca0ec4 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 5 Jun 2023 10:12:45 +0000 Subject: [PATCH 16/23] port t/t0116-client_body_buffer_size.sh to Perl 5 While I'm fine with depending on curl for certain things, there's no need for it here since unicorn has had lazy rack.input for over a decade, at this point. --- t/active-unix-socket.t | 1 + t/{t0116.ru => client_body_buffer_size.ru} | 2 - t/client_body_buffer_size.t | 83 ++++++++++++++++++++++ t/integration.t | 10 --- t/lib.perl | 12 +++- t/t0116-client_body_buffer_size.sh | 80 --------------------- 6 files changed, 95 insertions(+), 93 deletions(-) rename t/{t0116.ru => client_body_buffer_size.ru} (82%) create mode 100644 t/client_body_buffer_size.t delete mode 100755 t/t0116-client_body_buffer_size.sh diff --git a/t/active-unix-socket.t b/t/active-unix-socket.t index 8723137..4e11837 100644 --- a/t/active-unix-socket.t +++ b/t/active-unix-socket.t @@ -109,4 +109,5 @@ is($pidf, $to_kill{u1}, 'pid file contents unchanged after 2nd start failure'); } check_stderr; +undef $tmpdir; done_testing; diff --git a/t/t0116.ru b/t/client_body_buffer_size.ru similarity index 82% rename from t/t0116.ru rename to t/client_body_buffer_size.ru index fab5fce..44161a5 100644 --- a/t/t0116.ru +++ b/t/client_body_buffer_size.ru @@ -1,6 +1,4 @@ #\ -E none -use Rack::ContentLength -use Rack::ContentType, 'text/plain' app = lambda do |env| input = env['rack.input'] case env["PATH_INFO"] diff --git a/t/client_body_buffer_size.t b/t/client_body_buffer_size.t new file mode 100644 index 0000000..b1a99f3 --- /dev/null +++ b/t/client_body_buffer_size.t @@ -0,0 +1,83 @@ +#!perl -w +# Copyright (C) unicorn hackers +# License: GPL-3.0+ + +use v5.14; BEGIN { require './t/lib.perl' }; +use autodie; +my $uconf = "$tmpdir/u.conf.rb"; + +open my $conf_fh, '>', $uconf; +$conf_fh->autoflush(1); +print $conf_fh < $srv }); +my ($c, $status, $hdr); +my $mem_class = 'StringIO'; +my $fs_class = 'Unicorn::TmpIO'; + +$c = tcp_start($srv, "PUT /input_class HTTP/1.0\r\nContent-Length: 0"); +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $mem_class, 'zero-byte file is StringIO'); + +$c = tcp_start($srv, "PUT /tmp_class HTTP/1.0\r\nContent-Length: 1"); +print $c '.'; +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $fs_class, '1 byte file is filesystem-backed'); + + +my $fifo = "$tmpdir/fifo"; +POSIX::mkfifo($fifo, 0600) or die "mkfifo: $!"; +seek($conf_fh, 0, SEEK_SET); +truncate($conf_fh, 0); +print $conf_fh <do_kill('HUP'); +open my $fifo_fh, '<', $fifo; +like(my $wpid = readline($fifo_fh), qr/\Apid=\d+\z/a , + 'reloaded w/ default client_body_buffer_size'); + + +$c = tcp_start($srv, "PUT /tmp_class HTTP/1.0\r\nContent-Length: 1"); +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $mem_class, 'class for a 1 byte file is memory-backed'); + + +my $one_meg = 1024 ** 2; +$c = tcp_start($srv, "PUT /tmp_class HTTP/1.0\r\nContent-Length: $one_meg"); +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $fs_class, '1 megabyte file is FS-backed'); + +# reload with bigger client_body_buffer_size +say $conf_fh "client_body_buffer_size $one_meg"; +$ar->do_kill('HUP'); +open $fifo_fh, '<', $fifo; +like($wpid = readline($fifo_fh), qr/\Apid=\d+\z/a , + 'reloaded w/ bigger client_body_buffer_size'); + + +$c = tcp_start($srv, "PUT /tmp_class HTTP/1.0\r\nContent-Length: $one_meg"); +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $mem_class, '1 megabyte file is now memory-backed'); + +my $too_big = $one_meg + 1; +$c = tcp_start($srv, "PUT /tmp_class HTTP/1.0\r\nContent-Length: $too_big"); +($status, $hdr) = slurp_hdr($c); +like($status, qr!\AHTTP/1\.[01] 200\b!, 'status line valid'); +is(readline($c), $fs_class, '1 megabyte + 1 byte file is FS-backed'); + + +undef $ar; +check_stderr; +undef $tmpdir; +done_testing; diff --git a/t/integration.t b/t/integration.t index f5afd5d..855c260 100644 --- a/t/integration.t +++ b/t/integration.t @@ -15,16 +15,6 @@ open my $conf_fh, '>', $conf; $conf_fh->autoflush(1); my $ar = unicorn(qw(-E none t/integration.ru -c), $conf, { 3 => $srv }); my $curl = which('curl'); -END { diag slurp("$tmpdir/err.log") if $tmpdir }; -sub slurp_hdr { - my ($c) = @_; - local $/ = "\r\n\r\n"; # affects both readline+chomp - chomp(my $hdr = readline($c)); - my ($status, @hdr) = split(/\r\n/, $hdr); - diag explain([ $status, \@hdr ]) if $ENV{V}; - ($status, \@hdr); -} - my %PUT = ( chunked_md5 => sub { my ($in, $out, $path, %opt) = @_; diff --git a/t/lib.perl b/t/lib.perl index b6148cf..2685c3b 100644 --- a/t/lib.perl +++ b/t/lib.perl @@ -11,11 +11,12 @@ use POSIX qw(dup2 _exit setpgid :signal_h SEEK_SET F_SETFD); use File::Temp 0.19 (); # 0.19 for ->newdir our ($tmpdir, $errfh); our @EXPORT = qw(unicorn slurp tcp_server tcp_start unicorn $tmpdir $errfh - SEEK_SET tcp_host_port which spawn check_stderr unix_start); + SEEK_SET tcp_host_port which spawn check_stderr unix_start slurp_hdr); my ($base) = ($0 =~ m!\b([^/]+)\.[^\.]+\z!); $tmpdir = File::Temp->newdir("unicorn-$base-XXXX", TMPDIR => 1); open($errfh, '>>', "$tmpdir/err.log"); +END { diag slurp("$tmpdir/err.log") if $tmpdir }; sub check_stderr () { my @log = slurp("$tmpdir/err.log"); @@ -25,6 +26,15 @@ sub check_stderr () { is_deeply([grep(/SIGKILL/, @log)], [], 'no SIGKILL in stderr'); } +sub slurp_hdr { + my ($c) = @_; + local $/ = "\r\n\r\n"; # affects both readline+chomp + chomp(my $hdr = readline($c)); + my ($status, @hdr) = split(/\r\n/, $hdr); + diag explain([ $status, \@hdr ]) if $ENV{V}; + ($status, \@hdr); +} + sub tcp_server { my %opt = ( ReuseAddr => 1, diff --git a/t/t0116-client_body_buffer_size.sh b/t/t0116-client_body_buffer_size.sh deleted file mode 100755 index c9e17c7..0000000 --- a/t/t0116-client_body_buffer_size.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -. ./test-lib.sh -t_plan 12 "client_body_buffer_size settings" - -t_begin "setup and start" && { - unicorn_setup - rtmpfiles unicorn_config_tmp one_meg - dd if=/dev/zero bs=1M count=1 of=$one_meg - cat >> $unicorn_config < $unicorn_config_tmp - echo client_body_buffer_size 0 >> $unicorn_config - unicorn -D -c $unicorn_config t0116.ru - unicorn_wait_start - fs_class=Unicorn::TmpIO - mem_class=StringIO - - test x"$(cat $fifo)" = xSTART -} - -t_begin "class for a zero-byte file should be StringIO" && { - > $tmp - test xStringIO = x"$(curl -T $tmp -sSf http://$listen/input_class)" -} - -t_begin "class for a 1 byte file should be filesystem-backed" && { - echo > $tmp - test x$fs_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)" -} - -t_begin "reload with default client_body_buffer_size" && { - mv $unicorn_config_tmp $unicorn_config - kill -HUP $unicorn_pid - test x"$(cat $fifo)" = xSTART -} - -t_begin "class for a 1 byte file should be memory-backed" && { - echo > $tmp - test x$mem_class = x"$(curl -T $tmp -sSf http://$listen/tmp_class)" -} - -t_begin "class for a random blob file should be filesystem-backed" && { - resp="$(curl -T random_blob -sSf http://$listen/tmp_class)" - test x$fs_class = x"$resp" -} - -t_begin "one megabyte file should be filesystem-backed" && { - resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" - test x$fs_class = x"$resp" -} - -t_begin "reload with a big client_body_buffer_size" && { - echo "client_body_buffer_size(1024 * 1024)" >> $unicorn_config - kill -HUP $unicorn_pid - test x"$(cat $fifo)" = xSTART -} - -t_begin "one megabyte file should be memory-backed" && { - resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" - test x$mem_class = x"$resp" -} - -t_begin "one megabyte + 1 byte file should be filesystem-backed" && { - echo >> $one_meg - resp="$(curl -T $one_meg -sSf http://$listen/tmp_class)" - test x$fs_class = x"$resp" -} - -t_begin "killing succeeds" && { - kill $unicorn_pid -} - -t_begin "check stderr" && { - check_stderr -} - -t_done