about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <BOFH@YHBT.net>2023-09-07 23:18:16 +0000
committerEric Wong <BOFH@YHBT.net>2023-09-10 19:01:03 +0000
commitd4514174ee7eadea89003f380acacf32d52acd9d (patch)
treefaffd7f59765d32543367e390e08b56360f9e8a6 /t
parentf43c28ea10ca8d520b55f2fbb20710dd66fc4fb5 (diff)
downloadunicorn-d4514174ee7eadea89003f380acacf32d52acd9d.tar.gz
We can fold a bunch of them into one test to save startup
time, inodes, and FS activity.
Diffstat (limited to 't')
-rwxr-xr-xt/t0003-working_directory.sh51
-rwxr-xr-xt/t0004-working_directory_broken.sh24
-rwxr-xr-xt/t0005-working_directory_app.rb.sh40
-rwxr-xr-xt/t0007-working_directory_no_embed_cli.sh44
-rw-r--r--t/working_directory.t122
5 files changed, 122 insertions, 159 deletions
diff --git a/t/t0003-working_directory.sh b/t/t0003-working_directory.sh
deleted file mode 100755
index 79988d8..0000000
--- a/t/t0003-working_directory.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-. ./test-lib.sh
-
-t_plan 4 "config.ru inside alt working_directory"
-
-t_begin "setup and start" && {
-        unicorn_setup
-        rtmpfiles unicorn_config_tmp
-        rm -rf $t_pfx.app
-        mkdir $t_pfx.app
-
-        cat > $t_pfx.app/config.ru <<EOF
-#\--daemonize --host $host --port $port
-use Rack::ContentLength
-use Rack::ContentType, "text/plain"
-run lambda { |env| [ 200, {}, [ "#{\$master_ppid}\\n" ] ] }
-EOF
-        # we have --host/--port in config.ru instead
-        grep -v ^listen $unicorn_config > $unicorn_config_tmp
-
-        # the whole point of this exercise
-        echo "working_directory '$t_pfx.app'" >> $unicorn_config_tmp
-
-        # allows ppid to be 1 in before_fork
-        echo "preload_app true" >> $unicorn_config_tmp
-        cat >> $unicorn_config_tmp <<\EOF
-before_fork do |server,worker|
-  $master_ppid = Process.ppid # should be zero to detect daemonization
-end
-EOF
-
-        mv $unicorn_config_tmp $unicorn_config
-
-        # rely on --daemonize switch, no & or -D
-        unicorn -c $unicorn_config
-        unicorn_wait_start
-}
-
-t_begin "hit with curl" && {
-        body=$(curl -sSf http://$listen/)
-}
-
-t_begin "killing succeeds" && {
-        kill $unicorn_pid
-}
-
-t_begin "response body ppid == 1 (daemonized)" && {
-        test "$body" -eq 1
-}
-
-t_done
diff --git a/t/t0004-working_directory_broken.sh b/t/t0004-working_directory_broken.sh
deleted file mode 100755
index ca9d382..0000000
--- a/t/t0004-working_directory_broken.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-. ./test-lib.sh
-
-t_plan 3 "config.ru is missing inside alt working_directory"
-
-t_begin "setup" && {
-        unicorn_setup
-        rtmpfiles unicorn_config_tmp ok
-        rm -rf $t_pfx.app
-        mkdir $t_pfx.app
-
-        # the whole point of this exercise
-        echo "working_directory '$t_pfx.app'" >> $unicorn_config_tmp
-}
-
-t_begin "fails to start up w/o config.ru" && {
-        unicorn -c $unicorn_config_tmp || echo ok > $ok
-}
-
-t_begin "fallback code was run" && {
-        test x"$(cat $ok)" = xok
-}
-
-t_done
diff --git a/t/t0005-working_directory_app.rb.sh b/t/t0005-working_directory_app.rb.sh
deleted file mode 100755
index 0fbab4f..0000000
--- a/t/t0005-working_directory_app.rb.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-. ./test-lib.sh
-
-t_plan 4 "fooapp.rb inside alt working_directory"
-
-t_begin "setup and start" && {
-        unicorn_setup
-        rm -rf $t_pfx.app
-        mkdir $t_pfx.app
-
-        cat > $t_pfx.app/fooapp.rb <<\EOF
-class Fooapp
-  def self.call(env)
-    # Rack::Lint in 1.5.0 requires headers to be a hash
-    h = [%w(Content-Type text/plain), %w(Content-Length 2)]
-    h = Rack::Utils::HeaderHash.new(h)
-    [ 200, h, %w(HI) ]
-  end
-end
-EOF
-        # the whole point of this exercise
-        echo "working_directory '$t_pfx.app'" >> $unicorn_config
-        cd /
-        unicorn -D -c $unicorn_config -I. fooapp.rb
-        unicorn_wait_start
-}
-
-t_begin "hit with curl" && {
-        body=$(curl -sSf http://$listen/)
-}
-
-t_begin "killing succeeds" && {
-        kill $unicorn_pid
-}
-
-t_begin "response body expected" && {
-        test x"$body" = xHI
-}
-
-t_done
diff --git a/t/t0007-working_directory_no_embed_cli.sh b/t/t0007-working_directory_no_embed_cli.sh
deleted file mode 100755
index 77d6707..0000000
--- a/t/t0007-working_directory_no_embed_cli.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-. ./test-lib.sh
-
-t_plan 4 "config.ru inside alt working_directory (no embedded switches)"
-
-t_begin "setup and start" && {
-        unicorn_setup
-        rm -rf $t_pfx.app
-        mkdir $t_pfx.app
-
-        cat > $t_pfx.app/config.ru <<EOF
-use Rack::ContentLength
-use Rack::ContentType, "text/plain"
-run lambda { |env| [ 200, {}, [ "#{\$master_ppid}\\n" ] ] }
-EOF
-        # the whole point of this exercise
-        echo "working_directory '$t_pfx.app'" >> $unicorn_config
-
-        # allows ppid to be 1 in before_fork
-        echo "preload_app true" >> $unicorn_config
-        cat >> $unicorn_config <<\EOF
-before_fork do |server,worker|
-  $master_ppid = Process.ppid # should be zero to detect daemonization
-end
-EOF
-
-        cd /
-        unicorn -D -c $unicorn_config
-        unicorn_wait_start
-}
-
-t_begin "hit with curl" && {
-        body=$(curl -sSf http://$listen/)
-}
-
-t_begin "killing succeeds" && {
-        kill $unicorn_pid
-}
-
-t_begin "response body ppid == 1 (daemonized)" && {
-        test "$body" -eq 1
-}
-
-t_done
diff --git a/t/working_directory.t b/t/working_directory.t
new file mode 100644
index 0000000..e7ff43a
--- /dev/null
+++ b/t/working_directory.t
@@ -0,0 +1,122 @@
+#!perl -w
+# Copyright (C) unicorn hackers <unicorn-public@yhbt.net>
+# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
+use v5.14; BEGIN { require './t/lib.perl' };
+use autodie;
+mkdir "$tmpdir/alt";
+my $u_sock = "$tmpdir/u.sock";
+my $ru = "$tmpdir/alt/config.ru";
+my $u_conf = "$tmpdir/u.conf.rb";
+open my $fh, '>', $u_conf;
+print $fh <<EOM;
+pid "$tmpdir/pid"
+preload_app true
+stderr_path "$err_log"
+working_directory "$tmpdir/alt" # the whole point of this test
+before_fork { |_,_| \$master_ppid = Process.ppid }
+EOM
+close $fh;
+
+my $common_ru = <<'EOM';
+use Rack::ContentLength
+use Rack::ContentType, 'text/plain'
+run lambda { |env| [ 200, {}, [ "#{$master_ppid}\n" ] ] }
+EOM
+
+open $fh, '>', $ru;
+print $fh <<EOM;
+#\\--daemonize --listen $u_sock
+$common_ru
+EOM
+close $fh;
+
+my $pid;
+my $stop_daemon = sub {
+        my ($is_END) = @_;
+        kill('TERM', $pid);
+        my $tries = 1000;
+        while (CORE::kill(0, $pid) && --$tries) {
+                select undef, undef, undef, 0.01;
+        }
+        if ($is_END && CORE::kill(0, $pid)) {
+                CORE::kill('KILL', $pid);
+                die "daemonized PID=$pid did not die";
+        } else {
+                ok(!CORE::kill(0, $pid), 'daemonized unicorn gone');
+                undef $pid;
+        }
+};
+
+END { $stop_daemon->(1) if defined $pid };
+
+unicorn('-c', $u_conf)->join; # will daemonize
+chomp($pid = slurp("$tmpdir/pid"));
+
+my $c = unix_start($u_sock, 'GET / HTTP/1.0');
+my ($status, $hdr) = slurp_hdr($c);
+chomp(my $bdy = do { local $/; <$c> });
+is($bdy, 1, 'got expected $master_ppid');
+
+$stop_daemon->();
+check_stderr;
+
+if ('test without CLI switches in config.ru') {
+        truncate $err_log, 0;
+        open $fh, '>', $ru;
+        print $fh $common_ru;
+        close $fh;
+
+        unicorn('-D', '-l', $u_sock, '-c', $u_conf)->join; # will daemonize
+        chomp($pid = slurp("$tmpdir/pid"));
+
+        $c = unix_start($u_sock, 'GET / HTTP/1.0');
+        ($status, $hdr) = slurp_hdr($c);
+        chomp($bdy = do { local $/; <$c> });
+        is($bdy, 1, 'got expected $master_ppid');
+
+        $stop_daemon->();
+        check_stderr;
+}
+
+if ('ensures broken working_directory (missing config.ru) is OK') {
+        truncate $err_log, 0;
+        unlink $ru;
+
+        my $auto_reap = unicorn('-c', $u_conf);
+        $auto_reap->join;
+        isnt($?, 0, 'exited with error due to missing config.ru');
+
+        like(slurp($err_log), qr/rackup file \Q(config.ru)\E not readable/,
+                'noted unreadability of config.ru in stderr');
+}
+
+if ('fooapp.rb (not config.ru) works with working_directory') {
+        truncate $err_log, 0;
+        my $fooapp = "$tmpdir/alt/fooapp.rb";
+        open $fh, '>', $fooapp;
+        print $fh <<EOM;
+class Fooapp
+  def self.call(env)
+    b = "dir=#{Dir.pwd}"
+    h = { 'content-type' => 'text/plain', 'content-length' => b.bytesize.to_s }
+    [ 200, h, [ b ] ]
+  end
+end
+EOM
+        close $fh;
+        my $srv = tcp_server;
+        my $auto_reap = unicorn(qw(-c), $u_conf, qw(-I. fooapp.rb),
+                                { -C => '/', 3 => $srv });
+        $c = tcp_start($srv, 'GET / HTTP/1.0');
+        ($status, $hdr) = slurp_hdr($c);
+        chomp($bdy = do { local $/; <$c> });
+        is($bdy, "dir=$tmpdir/alt",
+                'fooapp.rb (w/o config.ru) w/ working_directory');
+        close $c;
+        $auto_reap->join('TERM');
+        is($?, 0, 'fooapp.rb process exited');
+        check_stderr;
+}
+
+undef $tmpdir;
+done_testing;