]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/TestCommon.pm
eml: pure-Perl replacement for Email::MIME
[public-inbox.git] / lib / PublicInbox / TestCommon.pm
index 6e3e9d8c8f506a92b195f15c4cd558a60b8ef31a..600843f006663815a3b0f95b1f61a1c24dfa3899 100644 (file)
@@ -9,7 +9,20 @@ 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 mime_load eml_load);
+
+sub mime_load ($) {
+       my ($path) = @_;
+       open(my $fh, '<', $path) or die "open $path: $!";
+       PublicInbox::MIME->new(\(do { local $/; <$fh> }));
+}
+
+sub eml_load ($) {
+       my ($path, $cb) = @_;
+       open(my $fh, '<', $path) or die "open $path: $!";
+       binmode $fh;
+       PublicInbox::Eml->new(\(do { local $/; <$fh> }));
+}
 
 sub tmpdir (;$) {
        my ($base) = @_;
@@ -87,7 +100,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 +257,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;
@@ -319,8 +354,9 @@ sub kill {
 }
 
 sub join {
-       my ($self) = @_;
+       my ($self, $sig) = @_;
        my $pid = delete $self->{pid} or return;
+       CORE::kill($sig, $pid) if defined $sig;
        my $ret = waitpid($pid, 0);
        defined($ret) or die "waitpid($pid): $!";
        $ret == $pid or die "waitpid($pid) != $ret";
@@ -333,8 +369,7 @@ sub DESTROY {
                PublicInbox::TestCommon::wait_for_tail();
                CORE::kill('TERM', $tail);
        }
-       my $pid = delete $self->{pid} or return;
-       CORE::kill('TERM', $pid);
+       $self->join('TERM');
 }
 
 1;