From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 5B2731FA05 for ; Sun, 19 Apr 2020 23:19:40 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 4/4] testcommon: spawn-aware system() and qx[] workalikes Date: Sun, 19 Apr 2020 23:19:37 +0000 Message-Id: <20200419231937.56365-5-e@yhbt.net> In-Reply-To: <20200419231937.56365-1-e@yhbt.net> References: <20200419231937.56365-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: 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. --- lib/PublicInbox/TestCommon.pm | 26 ++++++++++++++++++++++++-- t/config.t | 2 +- t/ds-leak.t | 10 ++++++---- t/edit.t | 2 +- t/git.t | 17 +++++++---------- t/hl_mod.t | 20 +++++++------------- t/httpd-corner.t | 30 ++++++++++++++---------------- t/httpd.t | 8 ++++---- t/indexlevels-mirror.t | 8 ++++---- t/init.t | 5 +++-- t/mda.t | 2 +- t/mda_filter_rubylang.t | 6 +++--- t/multi-mid.t | 2 +- t/nntpd.t | 5 +++-- t/nulsubject.t | 3 ++- t/replace.t | 2 +- t/search.t | 2 +- t/solver_git.t | 5 +++-- t/v2mda.t | 2 +- t/v2mirror.t | 4 ++-- t/v2writable.t | 2 +- t/www_listing.t | 19 +++++++++++-------- xt/git-http-backend.t | 6 +++--- 23 files changed, 104 insertions(+), 84 deletions(-) diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm index e9efbac7..b50871e8 100644 --- a/lib/PublicInbox/TestCommon.pm +++ b/lib/PublicInbox/TestCommon.pm @@ -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; diff --git a/t/config.t b/t/config.t index 0db12359..1f50bb86 100644 --- a/t/config.t +++ b/t/config.t @@ -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"); diff --git a/t/ds-leak.t b/t/ds-leak.t index b29d814e..72bf0379 100644 --- a/t/ds-leak.t +++ b/t/ds-leak.t @@ -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) { diff --git a/t/edit.t b/t/edit.t index 2803dd01..d8833f9c 100644 --- 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 0936ac5e..b05ac123 100644 --- 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; diff --git a/t/hl_mod.t b/t/hl_mod.t index a4ef4a28..95057354 100644 --- a/t/hl_mod.t +++ b/t/hl_mod.t @@ -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 '
', $$ref, '
' 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 = '
' . $$ref . '
'; + 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'); diff --git a/t/httpd-corner.t b/t/httpd-corner.t index f25a9a9c..7a6bcc66 100644 --- a/t/httpd-corner.t +++ b/t/httpd-corner.t @@ -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 {; diff --git a/t/httpd.t b/t/httpd.t index 11511c73..61aec3b4 100644 --- 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'); } diff --git a/t/indexlevels-mirror.t b/t/indexlevels-mirror.t index 77c52718..f2200306 100644 --- a/t/indexlevels-mirror.t +++ b/t/indexlevels-mirror.t @@ -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)}; diff --git a/t/init.t b/t/init.t index a78c2fc8..94c6184e 100644 --- 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 af5e1931..dc691616 100644 --- 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 }), diff --git a/t/mda_filter_rubylang.t b/t/mda_filter_rubylang.t index 6f288b7e..f2cbe9d5 100644 --- a/t/mda_filter_rubylang.t +++ b/t/mda_filter_rubylang.t @@ -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) { diff --git a/t/multi-mid.t b/t/multi-mid.t index 31a8fd74..5afb9693 100644 --- a/t/multi-mid.t +++ b/t/multi-mid.t @@ -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' ]; diff --git a/t/nntpd.t b/t/nntpd.t index 826e3f3d..66aa48f1 100644 --- 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'); diff --git a/t/nulsubject.t b/t/nulsubject.t index b21507c2..1ded88d3 100644 --- a/t/nulsubject.t +++ b/t/nulsubject.t @@ -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(); diff --git a/t/replace.t b/t/replace.t index a44560fc..2efa25f1 100644 --- a/t/replace.t +++ b/t/replace.t @@ -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"); } diff --git a/t/search.t b/t/search.t index 101d44e9..8508f273 100644 --- a/t/search.t +++ b/t/search.t @@ -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"); diff --git a/t/solver_git.t b/t/solver_git.t index b5231d2c..7f79ff4c 100644 --- a/t/solver_git.t +++ b/t/solver_git.t @@ -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); diff --git a/t/v2mda.t b/t/v2mda.t index c2118a89..e9dcdf44 100644 --- 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'); diff --git a/t/v2mirror.t b/t/v2mirror.t index 2e23e763..406bbd4f 100644 --- a/t/v2mirror.t +++ b/t/v2mirror.t @@ -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'); } }; diff --git a/t/v2writable.t b/t/v2writable.t index 66d5663e..8897062a 100644 --- a/t/v2writable.t +++ b/t/v2writable.t @@ -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'); diff --git a/t/www_listing.t b/t/www_listing.t index c132edbc..31d76356 100644 --- a/t/www_listing.t +++ b/t/www_listing.t @@ -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 $_"); diff --git a/xt/git-http-backend.t b/xt/git-http-backend.t index f2ae44fe..2f02725a 100644 --- a/xt/git-http-backend.t +++ b/xt/git-http-backend.t @@ -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'); }