]> Sergey Matveev's repositories - public-inbox.git/commitdiff
testcommon: spawn-aware system() and qx[] workalikes
authorEric Wong <e@yhbt.net>
Sun, 19 Apr 2020 23:19:37 +0000 (23:19 +0000)
committerEric Wong <e@yhbt.net>
Mon, 20 Apr 2020 20:18:21 +0000 (20:18 +0000)
Barely noticeable on Linux, but this gives a 1-2% speedup
on a FreeBSD 11.3 VM and lets us use built-in redirects
rather than relying on /bin/sh.

23 files changed:
lib/PublicInbox/TestCommon.pm
t/config.t
t/ds-leak.t
t/edit.t
t/git.t
t/hl_mod.t
t/httpd-corner.t
t/httpd.t
t/indexlevels-mirror.t
t/init.t
t/mda.t
t/mda_filter_rubylang.t
t/multi-mid.t
t/nntpd.t
t/nulsubject.t
t/replace.t
t/search.t
t/solver_git.t
t/v2mda.t
t/v2mirror.t
t/v2writable.t
t/www_listing.t
xt/git-http-backend.t

index e9efbac71264fe47b36f87c5bb9252c26c36aff1..b50871e8d9c65dd31105f8daa173aa020f4e8826 100644 (file)
@@ -9,7 +9,7 @@ use Fcntl qw(FD_CLOEXEC F_SETFD F_GETFD :seek);
 use POSIX qw(dup2);
 use IO::Socket::INET;
 our @EXPORT = qw(tmpdir tcp_server tcp_connect require_git require_mods
-       run_script start_script key2sub);
+       run_script start_script key2sub xsys xqx);
 
 sub tmpdir (;$) {
        my ($base) = @_;
@@ -87,7 +87,7 @@ sub require_mods {
 
 sub key2script ($) {
        my ($key) = @_;
-       return $key if (index($key, '/') >= 0);
+       return $key if ($key eq 'git' || index($key, '/') >= 0);
        # n.b. we may have scripts which don't start with "public-inbox" in
        # the future:
        $key =~ s/\A([-\.])/public-inbox$1/;
@@ -244,6 +244,28 @@ sub run_script ($;$$) {
 
 sub wait_for_tail () { sleep(2) }
 
+# like system() built-in, but uses spawn() for env/rdr + vfork
+sub xsys {
+       my ($cmd, $env, $rdr) = @_;
+       if (ref($cmd)) {
+               $rdr ||= {};
+       } else {
+               $cmd = [ @_ ];
+               $env = undef;
+               $rdr = {};
+       }
+       run_script($cmd, $env, { %$rdr, run_mode => 0 });
+       $? >> 8
+}
+
+# like `backtick` or qx{} op, but uses spawn() for env/rdr + vfork
+sub xqx {
+       my ($cmd, $env, $rdr) = @_;
+       $rdr //= {};
+       run_script($cmd, $env, { %$rdr, run_mode => 0, 1 => \(my $out) });
+       wantarray ? split(/^/m, $out) : $out;
+}
+
 sub start_script {
        my ($cmd, $env, $opt) = @_;
        my ($key, @argv) = @$cmd;
index 0db12359b5a29c7370ec190fc2413fa441531d2f..1f50bb86a0963bd5ac63e0817701a45c796846a5 100644 (file)
@@ -11,7 +11,7 @@ my ($tmpdir, $for_destroy) = tmpdir();
 {
        PublicInbox::Import::init_bare($tmpdir);
        my @cmd = ('git', "--git-dir=$tmpdir", qw(config foo.bar), "hi\nhi");
-       is(system(@cmd), 0, "set config");
+       is(xsys(@cmd), 0, "set config");
 
        my $tmp = PublicInbox::Config->new("$tmpdir/config");
 
index b29d814ee06395b49c9642bc3a0c98e7bdfeab33..72bf037937e544940bacd102326ebfde4eba6c67 100644 (file)
@@ -10,7 +10,7 @@ use PublicInbox::TestCommon;
 use_ok 'PublicInbox::DS';
 
 if ('close-on-exec for epoll and kqueue') {
-       use PublicInbox::Spawn qw(spawn);
+       use PublicInbox::Spawn qw(spawn which);
        my $pid;
        my $evfd_re = qr/(?:kqueue|eventpoll)/i;
 
@@ -31,10 +31,12 @@ if ('close-on-exec for epoll and kqueue') {
        my $l = <$r>;
        is($l, undef, 'cloexec works and sleep(1) is running');
 
-       my @of = grep(/$evfd_re/, `lsof -p $pid 2>/dev/null`);
-       my $err = $?;
        SKIP: {
-               skip "lsof missing? (\$?=$err)", 1 if $err;
+               my $lsof = which('lsof') or skip 'lsof missing', 1;
+               my $rdr = { 2 => \(my $null) };
+               my @of = grep(/$evfd_re/, xqx([$lsof, '-p', $pid], {}, $rdr));
+               my $err = $?;
+               skip "lsof broken ? (\$?=$err)", 1 if $err;
                is_deeply(\@of, [], 'no FDs leaked to subprocess');
        };
        if (defined $pid) {
index 2803dd01bbc69e4f4921c02ac85c10c338d28023..d8833f9c64a1d01f2b81e72d809a692bfe3d75a8 100644 (file)
--- a/t/edit.t
+++ b/t/edit.t
@@ -118,7 +118,7 @@ $t = 'non-interactive editor failure'; {
 
 $t = 'mailEditor set in config'; {
        $in = $out = $err = '';
-       my $rc = system(qw(git config), "--file=$cfgfile",
+       my $rc = xsys(qw(git config), "--file=$cfgfile",
                        'publicinbox.maileditor',
                        "$^X -i -p -e 's/boolean prefix/bool pfx/'");
        is($rc, 0, 'set publicinbox.mailEditor');
diff --git a/t/git.t b/t/git.t
index 0936ac5ea8d1420641afd00c4586cd95ceaddc0a..b05ac123bec6a342204726b838a235253799cfb1 100644 (file)
--- a/t/git.t
+++ b/t/git.t
@@ -13,9 +13,10 @@ use_ok 'PublicInbox::Git';
 {
        PublicInbox::Import::init_bare($dir);
        my $fi_data = './t/git.fast-import-data';
-       ok(-r $fi_data, "fast-import data readable (or run test at top level)");
-       local $ENV{GIT_DIR} = $dir;
-       system("git fast-import --quiet <$fi_data");
+       open my $fh, '<', $fi_data or die
+               "fast-import data readable (or run test at top level: $!";
+       my $rdr = { 0 => $fh };
+       xsys([qw(git fast-import --quiet)], { GIT_DIR => $dir }, $rdr);
        is($?, 0, 'fast-import succeeded');
 }
 
@@ -58,18 +59,14 @@ use_ok 'PublicInbox::Git';
 }
 
 if (1) {
-       my $cmd = [ 'git', "--git-dir=$dir", qw(hash-object -w --stdin) ];
-
        # need a big file, use the AGPL-3.0 :p
        my $big_data = './COPYING';
        ok(-r $big_data, 'COPYING readable');
        my $size = -s $big_data;
        ok($size > 8192, 'file is big enough');
-
-       my $buf = do {
-               local $ENV{GIT_DIR} = $dir;
-               `git hash-object -w --stdin <$big_data`;
-       };
+       open my $fh, '<', $big_data or die;
+       my $cmd = [ 'git', "--git-dir=$dir", qw(hash-object -w --stdin) ];
+       my $buf = xqx($cmd, { GIT_DIR => $dir }, { 0 => $fh });
        is(0, $?, 'hashed object successfully');
        chomp $buf;
 
index a4ef4a284dda689f7c06330147037633b6c513c0..95057354636ab6461de622f80fe4fd03d09be927 100644 (file)
@@ -4,7 +4,8 @@
 use strict;
 use warnings;
 use Test::More;
-use PublicInbox::Spawn qw(which spawn);
+use PublicInbox::Spawn qw(which);
+use PublicInbox::TestCommon;
 use IO::Handle; # ->autoflush
 use Fcntl qw(:seek);
 eval { require highlight } or
@@ -29,21 +30,14 @@ my $orig = $str;
        is($$ref, $$lref, 'do_hl_lang matches do_hl');
 
        SKIP: {
-               which('w3m') or skip 'w3m(1) missing to check output', 1;
-               my $cmd = [ qw(w3m -T text/html -dump -config /dev/null) ];
-               open my $in, '+>', undef or die;
-               open my $out, '+>', undef or die;
-               my $rdr = { 0 => fileno($in), 1 => fileno($out) };
-               $in->autoflush(1);
-               print $in '<pre>', $$ref, '</pre>' or die;
-               $in->seek(0, SEEK_SET) or die;
-               my $pid = spawn($cmd, undef, $rdr);
-               waitpid($pid, 0);
+               my $w3m = which('w3m') or
+                       skip('w3m(1) missing to check output', 1);
+               my $cmd = [ $w3m, qw(-T text/html -dump -config /dev/null) ];
+               my $in = '<pre>' . $$ref . '</pre>';
+               my $out = xqx($cmd, undef, { 0 => \$in });
                # expand tabs and normalize whitespace,
                # w3m doesn't preserve tabs
                $orig =~ s/\t/        /gs;
-               $out->seek(0, SEEK_SET) or die;
-               $out = do { local $/; <$out> };
                $out =~ s/\s*\z//sg;
                $orig =~ s/\s*\z//sg;
                is($out, $orig, 'w3m output matches');
index f25a9a9cb31d0ae5198687cdb37495d57ca9cff7..7a6bcc6696116c0f352fe89794cb63ac7e1b69ce 100644 (file)
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use Test::More;
 use Time::HiRes qw(gettimeofday tv_interval);
-use PublicInbox::Spawn qw(which spawn);
+use PublicInbox::Spawn qw(which spawn popen_rd);
 use PublicInbox::TestCommon;
 require_mods(qw(Plack::Util Plack::Builder HTTP::Date HTTP::Status));
 use Digest::SHA qw(sha1_hex);
@@ -26,9 +26,6 @@ my $psgi = "./t/httpd-corner.psgi";
 my $sock = tcp_server() or die;
 my @zmods = qw(PublicInbox::GzipFilter IO::Uncompress::Gunzip);
 
-# make sure stdin is not a pipe for lsof test to check for leaking pipes
-open(STDIN, '<', '/dev/null') or die 'no /dev/null: $!';
-
 # Make sure we don't clobber socket options set by systemd or similar
 # using socket activation:
 my ($defer_accept_val, $accf_arg, $TCP_DEFER_ACCEPT);
@@ -308,12 +305,12 @@ my $check_self = sub {
 };
 
 SKIP: {
-       which('curl') or skip('curl(1) missing', 4);
+       my $curl = which('curl') or skip('curl(1) missing', 4);
        my $base = 'http://' . $sock->sockhost . ':' . $sock->sockport;
        my $url = "$base/sha1";
        my ($r, $w);
        pipe($r, $w) or die "pipe: $!";
-       my $cmd = [qw(curl --tcp-nodelay --no-buffer -T- -HExpect: -sS), $url];
+       my $cmd = [$curl, qw(--tcp-nodelay -T- -HExpect: -sSN), $url];
        open my $cout, '+>', undef or die;
        open my $cerr, '>', undef or die;
        my $rdr = { 0 => $r, 1 => $cout, 2 => $cerr };
@@ -330,7 +327,7 @@ SKIP: {
        seek($cout, 0, SEEK_SET);
        is(<$cout>, sha1_hex($str), 'read expected body');
 
-       open my $fh, '-|', qw(curl -sS), "$base/async-big" or die $!;
+       my $fh = popen_rd([$curl, '-sS', "$base/async-big"]);
        my $n = 0;
        my $non_zero = 0;
        while (1) {
@@ -338,15 +335,14 @@ SKIP: {
                $n += $r;
                $buf =~ /\A\0+\z/ or $non_zero++;
        }
-       close $fh or die "curl errored out \$?=$?";
+       close $fh or die "close curl pipe: $!";
+       is($?, 0, 'curl succesful');
        is($n, 30 * 1024 * 1024, 'got expected output from curl');
        is($non_zero, 0, 'read all zeros');
 
-       require_mods(@zmods, 1);
-       open $fh, '-|', qw(curl -sS), "$base/psgi-return-gzip" or die;
-       binmode $fh;
-       my $buf = do { local $/; <$fh> };
-       close $fh or die "curl errored out \$?=$?";
+       require_mods(@zmods, 2);
+       my $buf = xqx([$curl, '-sS', "$base/psgi-return-gzip"]);
+       is($?, 0, 'curl succesful');
        IO::Uncompress::Gunzip::gunzip(\$buf => \(my $out));
        is($out, "hello world\n");
 }
@@ -605,12 +601,14 @@ SKIP: {
 
 SKIP: {
        skip 'only testing lsof(8) output on Linux', 1 if $^O ne 'linux';
-       skip 'no lsof in PATH', 1 unless which('lsof');
-       my @lsof = `lsof -p $td->{pid}`;
+       my $lsof = which('lsof') or skip 'no lsof in PATH', 1;
+       my $null_in = '';
+       my $rdr = { 2 => \(my $null_err), 0 => \$null_in };
+       my @lsof = xqx([$lsof, '-p', $td->{pid}], undef, $rdr);
        is_deeply([grep(/\bdeleted\b/, @lsof)], [], 'no lingering deleted inputs');
 
        # filter out pipes inherited from the parent
-       my @this = `lsof -p $$`;
+       my @this = xqx([$lsof, '-p', $$], undef, $rdr);
        my $bad;
        my $extract_inodes = sub {
                map {;
index 11511c73b6d1e5e039f355e8a201d19a9cbd0c82..61aec3b4436bd5db64c09d46015488a391091ca8 100644 (file)
--- a/t/httpd.t
+++ b/t/httpd.t
@@ -64,22 +64,22 @@ EOF
                is($conn->read($buf, 1), 0, "EOF");
        }
 
-       is(system(qw(git clone -q --mirror),
+       is(xsys(qw(git clone -q --mirror),
                        "http://$host:$port/$group", "$tmpdir/clone.git"),
                0, 'smart clone successful');
 
        # ensure dumb cloning works, too:
-       is(system('git', "--git-dir=$maindir",
+       is(xsys('git', "--git-dir=$maindir",
                qw(config http.uploadpack false)),
                0, 'disable http.uploadpack');
-       is(system(qw(git clone -q --mirror),
+       is(xsys(qw(git clone -q --mirror),
                        "http://$host:$port/$group", "$tmpdir/dumb.git"),
                0, 'clone successful');
 
        ok($td->kill, 'killed httpd');
        $td->join;
 
-       is(system('git', "--git-dir=$tmpdir/clone.git",
+       is(xsys('git', "--git-dir=$tmpdir/clone.git",
                  qw(fsck --no-verbose)), 0,
                'fsck on cloned directory successful');
 }
index 77c5271835a08949b988fec4c468dc81f36031b7..f220030607b21242c0c0e0d6ce9f40fbd976b619 100644 (file)
@@ -59,7 +59,7 @@ sub import_index_incremental {
                push @cmd, "$ibx->{inboxdir}/git/0.git", "$mirror/git/0.git";
        }
        my $fetch_dir = $cmd[-1];
-       is(system(@cmd), 0, "v$v clone OK");
+       is(xsys(@cmd), 0, "v$v clone OK");
 
        # inbox init
        local $ENV{PI_CONFIG} = "$tmpdir/.picfg";
@@ -86,7 +86,7 @@ sub import_index_incremental {
        $im->done;
 
        # mirror updates
-       is(system('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
+       is(xsys('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
        ok(run_script(['-index', $mirror]), "v$v index mirror again OK");
        ($nr, $msgs) = $ro_mirror->recent;
        is($nr, 2, '2nd message seen in mirror');
@@ -123,7 +123,7 @@ sub import_index_incremental {
        }
 
        # sync the mirror
-       is(system('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
+       is(xsys('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
        ok(run_script(['-index', $mirror]), "v$v index mirror again OK");
        ($nr, $msgs) = $ro_mirror->recent;
        is($nr, 1, '2nd message gone from mirror');
@@ -148,7 +148,7 @@ sub import_index_incremental {
                push @expect, $i;
        }
        $im->done;
-       is(system('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
+       is(xsys('git', "--git-dir=$fetch_dir", qw(fetch -q)), 0, 'fetch OK');
        ok(run_script(['-index', '--reindex', $mirror]),
                "v$v index --reindex mirror OK");
        @ro_nums = map { $_->{num} } @{$ro_mirror->over->query_ts(0, 0)};
index a78c2fc868a13da125cc29f2567559238224a796..94c6184ed891a3760c0f102ad3fdbc44c9683dd2 100644 (file)
--- a/t/init.t
+++ b/t/init.t
@@ -105,7 +105,8 @@ done_testing();
 
 sub read_indexlevel {
        my ($inbox) = @_;
-       local $ENV{GIT_CONFIG} = "$ENV{PI_DIR}/config";
-       chomp(my $lvl = `git config publicinbox.$inbox.indexlevel`);
+       my $cmd = [ qw(git config), "publicinbox.$inbox.indexlevel" ];
+       my $env = { GIT_CONFIG => "$ENV{PI_DIR}/config" };
+       chomp(my $lvl = xqx($cmd, $env));
        $lvl;
 }
diff --git a/t/mda.t b/t/mda.t
index af5e19319ed82cbbc30b687a0a6b92036db261eb..dc6916169cbab1c2ba964f87e8048f68a1570f11 100644 (file)
--- a/t/mda.t
+++ b/t/mda.t
@@ -298,7 +298,7 @@ Subject: this message will be trained as spam
 Date: Thu, 01 Jan 1970 00:00:00 +0000
 
 EOF
-       system(qw(git config --file), $pi_config, "$cfgpfx.listid", $list_id);
+       xsys(qw(git config --file), $pi_config, "$cfgpfx.listid", $list_id);
        $? == 0 or die "failed to set listid $?";
        my $in = $simple->as_string;
        ok(run_script(['-mda'], undef, { 0 => \$in }),
index 6f288b7ebbfb4075eb51cf77853a01791e18e104..f2cbe9d59584a8c3b341d72057defc74ebd368ff 100644 (file)
@@ -14,7 +14,7 @@ my $pi_config = "$tmpdir/pi_config";
 local $ENV{PI_CONFIG} = $pi_config;
 local $ENV{PI_EMERGENCY} = "$tmpdir/emergency";
 my @cfg = ('git', 'config', "--file=$pi_config");
-is(system(@cfg, 'publicinboxmda.spamcheck', 'none'), 0);
+is(xsys(@cfg, 'publicinboxmda.spamcheck', 'none'), 0);
 
 for my $v (qw(V1 V2)) {
        my @warn;
@@ -26,8 +26,8 @@ for my $v (qw(V1 V2)) {
                "http://example.com/$v", $addr ];
        ok(run_script($cmd), 'public-inbox-init');
        ok(run_script(['-index', $inboxdir]), 'public-inbox-index');
-       is(system(@cfg, "$cfgpfx.filter", 'PublicInbox::Filter::RubyLang'), 0);
-       is(system(@cfg, "$cfgpfx.altid",
+       is(xsys(@cfg, "$cfgpfx.filter", 'PublicInbox::Filter::RubyLang'), 0);
+       is(xsys(@cfg, "$cfgpfx.altid",
                'serial:alerts:file=msgmap.sqlite3'), 0);
 
        for my $i (1..2) {
index 31a8fd74cf29caf77708f2a3e8882fc8f0a3200a..5afb96933209d3e5f7e306f073a4764e9ba26f4a 100644 (file)
@@ -65,7 +65,7 @@ for my $order ([$bad, $good], [$good, $bad]) {
        my @v2 = ($ibx->over->get_art(1), $ibx->over->get_art(2));
        is_deeply(\@v2, \@old, 'v2 conversion times match');
 
-       system(qw(git clone -sq --mirror), "$tmpdir/v2/git/0.git",
+       xsys(qw(git clone -sq --mirror), "$tmpdir/v2/git/0.git",
                "$tmpdir/v2-clone/git/0.git") == 0 or die "clone: $?";
        $cmd = [ '-init', '-Lbasic', '-V2', 'v2c', "$tmpdir/v2-clone",
                'http://example.com/v2c', 'v2c@example.com' ];
index 826e3f3da27c297a8c490593998045304f0009b6..66aa48f1e67946def9ef5005222f191f00f6b91e 100644 (file)
--- a/t/nntpd.t
+++ b/t/nntpd.t
@@ -48,7 +48,7 @@ $ibx = PublicInbox::Inbox->new($ibx);
        my @cmd = ('-init', $group, $inboxdir, 'http://example.com/', $addr);
        push @cmd, "-V$version", '-Lbasic';
        ok(run_script(\@cmd), 'init OK');
-       is(system(qw(git config), "--file=$home/.public-inbox/config",
+       is(xsys(qw(git config), "--file=$home/.public-inbox/config",
                        "publicinbox.$group.newsgroup", $group),
                0, 'enabled newsgroup');
        my $len;
@@ -304,7 +304,8 @@ Date: Fri, 02 Oct 1993 00:00:00 +0000
                if ($INC{'Search/Xapian.pm'} && ($ENV{TEST_RUN_MODE}//2)) {
                        skip 'Search/Xapian.pm pre-loaded (by t/run.perl?)', 1;
                }
-               my @of = `lsof -p $td->{pid} 2>/dev/null`;
+               my $rdr = { 2 => \(my $null) };
+               my @of = xqx(['lsof', '-p', $td->{pid}], undef, $rdr);
                skip('lsof broken', 1) if (!scalar(@of) || $?);
                my @xap = grep m!Search/Xapian!, @of;
                is_deeply(\@xap, [], 'Xapian not loaded in nntpd');
index b21507c2ec1be4d16053c4550dac126c9c8e6e0e..1ded88d31f435fdad0fa3d792e5079e96ca08ee1 100644 (file)
@@ -25,7 +25,8 @@ my $git_dir = "$tmpdir/a.git";
                body => "hello world\n",
        ));
        $im->done;
-       is(system(qw(git --git-dir), $git_dir, 'fsck', '--strict'), 0, 'git fsck ok');
+       is(xsys(qw(git --git-dir), $git_dir, 'fsck', '--strict'), 0,
+               'git fsck ok');
 }
 
 done_testing();
index a44560fc8dc3b806354ef5880b20f38cb0017ad6..2efa25f1457e685c7557477331694c88254cedb1 100644 (file)
@@ -95,7 +95,7 @@ EOF
 
        for my $dir (glob("$ibx->{inboxdir}/git/*.git")) {
                my ($bn) = ($dir =~ m!([^/]+)\z!);
-               is(system(qw(git --git-dir), $dir,
+               is(xsys(qw(git --git-dir), $dir,
                                        qw(fsck --strict --no-progress)),
                        0, "git fsck is clean in epoch $bn");
        }
index 101d44e9cb769584b07ebe30588d2b734ce7c557..8508f27301443d28d39a57bd54ed86cd0a38300a 100644 (file)
@@ -14,7 +14,7 @@ my $git_dir = "$tmpdir/a.git";
 my $ibx = PublicInbox::Inbox->new({ inboxdir => $git_dir });
 my ($root_id, $last_id);
 
-is(0, system(qw(git init --shared -q --bare), $git_dir), "git init (main)")
+is(0, xsys(qw(git init --shared -q --bare), $git_dir), "git init (main)")
        or BAIL_OUT("`git init --shared' failed, weird FS or seccomp?");
 eval { PublicInbox::Search->new($ibx)->xdb };
 ok($@, "exception raised on non-existent DB");
index b5231d2cbc30749e55726bbaff647ef42be6507d..7f79ff4cc8790d65bb9052fe8880a2f44504a215 100644 (file)
@@ -8,8 +8,9 @@ use PublicInbox::TestCommon;
 require_git(2.6);
 use PublicInbox::Spawn qw(popen_rd);
 require_mods(qw(DBD::SQLite Search::Xapian Plack::Util));
-chomp(my $git_dir = `git rev-parse --git-dir 2>/dev/null`);
-plan skip_all => "$0 must be run from a git working tree" if $?;
+my $git_dir = xqx([qw(git rev-parse --git-dir)], undef, {2 => \(my $null)});
+$? == 0 or plan skip_all => "$0 must be run from a git working tree";
+chomp $git_dir;
 
 # needed for alternates, and --absolute-git-dir is only in git 2.13+
 $git_dir = abs_path($git_dir);
index c2118a89cf271c0f7240534a2c7bc2cb27766da9..e9dcdf44df8eb307506cefddb729f209ce378cd6 100644 (file)
--- a/t/v2mda.t
+++ b/t/v2mda.t
@@ -72,7 +72,7 @@ is($saved->{mime}->as_string, $mime->as_string, 'injected message');
        my $config = "$ENV{PI_DIR}/config";
        ok(-f $config, 'config exists');
        my $k = 'publicinboxmda.spamcheck';
-       is(system('git', 'config', "--file=$config", $k, 'none'), 0,
+       is(xsys('git', 'config', "--file=$config", $k, 'none'), 0,
                'disabled spamcheck for mda');
 
        ok(run_script(['-mda'], undef, $rdr), 'mda did not die');
index 2e23e763de09a31cf2b59b09de9b48780f327c63..406bbd4fc5f22f216031460678fc1062d9d6b5ec 100644 (file)
@@ -76,7 +76,7 @@ foreach my $i (0..$epoch_max) {
                "http://$host:$port/v2/$i$sfx",
                "$tmpdir/m/git/$i.git");
 
-       is(system(@cmd), 0, "cloned $i.git");
+       is(xsys(@cmd), 0, "cloned $i.git");
        ok(-d "$tmpdir/m/git/$i.git", "mirror $i OK");
 }
 
@@ -102,7 +102,7 @@ $ibx->cleanup;
 my $fetch_each_epoch = sub {
        foreach my $i (0..$epoch_max) {
                my $dir = "$tmpdir/m/git/$i.git";
-               is(system('git', "--git-dir=$dir", 'fetch', '-q'), 0,
+               is(xsys('git', "--git-dir=$dir", 'fetch', '-q'), 0,
                        'fetch successful');
        }
 };
index 66d5663e2a5895b8872351d36f87efe7baa10b06..8897062abfd04a2d8dbf51da5a2a16fc74145628 100644 (file)
@@ -48,7 +48,7 @@ my $git0;
 if ('ensure git configs are correct') {
        my @cmd = (qw(git config), "--file=$inboxdir/all.git/config",
                qw(core.sharedRepository 0644));
-       is(system(@cmd), 0, "set sharedRepository in all.git");
+       is(xsys(@cmd), 0, "set sharedRepository in all.git");
        $git0 = PublicInbox::Git->new("$inboxdir/git/0.git");
        chomp(my $v = $git0->qx(qw(config core.sharedRepository)));
        is($v, '0644', 'child repo inherited core.sharedRepository');
index c132edbc00b3bf1d34c9ff0ee05998efbf8fed37..31d76356d886697093a099129fddf22e1b5e50ad 100644 (file)
@@ -24,8 +24,10 @@ is(PublicInbox::WwwListing::fingerprint($bare), undef,
        'empty repo has no fingerprint');
 {
        my $fi_data = './t/git.fast-import-data';
-       local $ENV{GIT_DIR} = $bare->{git_dir};
-       is(system("git fast-import --quiet <$fi_data"), 0, 'fast-import');
+       open my $fh, '<', $fi_data or die "open $fi_data: $!";
+       my $env = { GIT_DIR => $bare->{git_dir} };
+       is(xsys([qw(git fast-import --quiet)], $env, { 0 => $fh }), 0,
+               'fast-import');
 }
 
 like(PublicInbox::WwwListing::fingerprint($bare), qr/\A[a-f0-9]{40}\z/,
@@ -76,17 +78,17 @@ SKIP: {
        ok($sock, 'sock created');
        my ($host, $port) = ($sock->sockhost, $sock->sockport);
        my @clone = qw(git clone -q -s --bare);
-       is(system(@clone, $bare->{git_dir}, $alt), 0, 'clone shared repo');
+       is(xsys(@clone, $bare->{git_dir}, $alt), 0, 'clone shared repo');
 
        PublicInbox::Import::init_bare("$v2/all.git");
        for my $i (0..2) {
-               is(system(@clone, $alt, "$v2/git/$i.git"), 0, "clone epoch $i");
+               is(xsys(@clone, $alt, "$v2/git/$i.git"), 0, "clone epoch $i")
        }
        ok(open(my $fh, '>', "$v2/inbox.lock"), 'mock a v2 inbox');
        open $fh, '>', "$alt/description" or die;
        print $fh "we're all clones\n" or die;
        close $fh or die;
-       is(system('git', "--git-dir=$alt", qw(config gitweb.owner lorelei)), 0,
+       is(xsys('git', "--git-dir=$alt", qw(config gitweb.owner lorelei)), 0,
                'set gitweb user');
        ok(unlink("$bare->{git_dir}/description"), 'removed bare/description');
        open $fh, '>', $cfgfile or die;
@@ -114,7 +116,8 @@ SKIP: {
 
        tiny_test($json, $host, $port);
 
-       skip 'skipping grok-pull integration test', 2 if !which('grok-pull');
+       my $grok_pull = which('grok-pull') or
+               skip('skipping grok-pull integration test', 2);
 
        ok(mkdir("$tmpdir/mirror"), 'prepare grok mirror dest');
        open $fh, '>', "$tmpdir/repos.conf" or die;
@@ -129,7 +132,7 @@ mymanifest = $tmpdir/local-manifest.js.gz
 
        close $fh or die;
 
-       system(qw(grok-pull -c), "$tmpdir/repos.conf");
+       xsys($grok_pull, '-c', "$tmpdir/repos.conf");
        is($? >> 8, 127, 'grok-pull exit code as expected');
        for (qw(alt bare v2/git/0.git v2/git/1.git v2/git/2.git)) {
                ok(-d "$tmpdir/mirror/$_", "grok-pull created $_");
@@ -149,7 +152,7 @@ mymanifest = $tmpdir/per-inbox-manifest.js.gz
 
        close $fh or die;
        ok(mkdir("$tmpdir/per-inbox"), 'prepare single-v2-inbox mirror');
-       system(qw(grok-pull -c), "$tmpdir/per-inbox.conf");
+       xsys($grok_pull, '-c', "$tmpdir/per-inbox.conf");
        is($? >> 8, 127, 'grok-pull exit code as expected');
        for (qw(v2/git/0.git v2/git/1.git v2/git/2.git)) {
                ok(-d "$tmpdir/per-inbox/$_", "grok-pull created $_");
index f2ae44fe870c169bb33b1f01e2d793f2d56512cd..2f02725a69988e316a6c4a5be7550099df20297d 100644 (file)
@@ -83,13 +83,13 @@ SKIP: { # make sure Last-Modified + If-Modified-Since works with curl
        skip 'curl(1) not found', $nr unless $curl;
        my $url = "http://$host:$port/description";
        my $dst = "$tmpdir/desc";
-       is(system($curl, qw(-RsSf), '-o', $dst, $url), 0, 'curl -R');
+       is(xsys($curl, qw(-RsSf), '-o', $dst, $url), 0, 'curl -R');
        is((stat($dst))[9], $mtime, 'curl used remote mtime');
-       is(system($curl, qw(-sSf), '-z', $dst, '-o', "$dst.2", $url), 0,
+       is(xsys($curl, qw(-sSf), '-z', $dst, '-o', "$dst.2", $url), 0,
                'curl -z noop');
        ok(!-e "$dst.2", 'no modification, nothing retrieved');
        utime(0, 0, $dst) or die "utime failed: $!";
-       is(system($curl, qw(-sSfR), '-z', $dst, '-o', "$dst.2", $url), 0,
+       is(xsys($curl, qw(-sSfR), '-z', $dst, '-o', "$dst.2", $url), 0,
                'curl -z updates');
        ok(-e "$dst.2", 'faked modification, got new file retrieved');
 }